| """End-to-end: run the full Oz_ShotSplitter pipeline on real samples.""" |
|
|
| import importlib.util |
| import os |
| import sys |
|
|
| import pytest |
|
|
| PACK_DIR = "/workspace/ComfyUI/custom_nodes/ComfyUI-ShotSplitter" |
|
|
|
|
| def _load_pack(): |
| """Load the hyphenated-name pack as a proper Python package.""" |
| if "/workspace/ComfyUI" not in sys.path: |
| sys.path.insert(0, "/workspace/ComfyUI") |
|
|
| if "ComfyUI_ShotSplitter" in sys.modules: |
| return sys.modules["ComfyUI_ShotSplitter"] |
|
|
| spec = importlib.util.spec_from_file_location( |
| "ComfyUI_ShotSplitter", |
| os.path.join(PACK_DIR, "__init__.py"), |
| submodule_search_locations=[PACK_DIR], |
| ) |
| mod = importlib.util.module_from_spec(spec) |
| sys.modules["ComfyUI_ShotSplitter"] = mod |
| spec.loader.exec_module(mod) |
| return mod |
|
|
|
|
| THREESHOT = "test_3shots.mp4" |
| REEL = "reel_multishot.mp4" |
|
|
|
|
| @pytest.mark.skipif( |
| not os.path.exists(f"/workspace/ComfyUI/input/{THREESHOT}"), |
| reason="synthetic sample missing", |
| ) |
| def test_e2e_3shot_synthetic_produces_three_clips(): |
| pack = _load_pack() |
| node = pack.Oz_ShotSplitter() |
| out = node.run( |
| video=THREESHOT, |
| detector="ensemble", |
| min_shot_seconds=0.3, |
| merge_window_frames=3, |
| adaptive_threshold=3.0, |
| transnet_threshold=0.5, |
| output_subfolder="shots/e2e_syn_test", |
| filename_prefix="shot", |
| crf=23, |
| preset="veryfast", |
| keep_audio=True, |
| ) |
| assert "result" in out |
| clip_paths, first_frames, shot_count, manifest_json = out["result"] |
| print(f"\n[E2E synthetic] shot_count={shot_count}") |
| print(f"[E2E synthetic] clip_paths={clip_paths}") |
| assert shot_count == 3, f"expected 3 shots for synthetic red/green/blue, got {shot_count}" |
| assert len(clip_paths) == 3 |
| assert first_frames.shape[0] == 3 |
| assert all(os.path.isfile(p) for p in clip_paths) |
| import json as _json |
| manifest = _json.loads(manifest_json) |
| assert len(manifest) == 3 |
|
|
| |
| assert "ui" in out |
| assert "videos" in out["ui"] |
| assert len(out["ui"]["videos"]) == 3 |
| for v in out["ui"]["videos"]: |
| assert v["filename"].endswith(".mp4") |
| assert v["subfolder"] == "shots/e2e_syn_test" |
| assert v["type"] == "output" |
|
|
|
|
| @pytest.mark.skipif( |
| not os.path.exists(f"/workspace/ComfyUI/input/{REEL}"), |
| reason="reel sample missing", |
| ) |
| def test_e2e_real_reel_produces_two_or_more_clips(): |
| pack = _load_pack() |
| node = pack.Oz_ShotSplitter() |
| out = node.run( |
| video=REEL, |
| detector="ensemble", |
| min_shot_seconds=0.5, |
| merge_window_frames=3, |
| adaptive_threshold=3.0, |
| transnet_threshold=0.5, |
| output_subfolder="shots/e2e_reel_test", |
| filename_prefix="shot", |
| crf=23, |
| preset="veryfast", |
| keep_audio=True, |
| ) |
| clip_paths, first_frames, shot_count, manifest_json = out["result"] |
| print(f"\n[E2E reel] shot_count={shot_count}") |
| print(f"[E2E reel] clip_paths={clip_paths}") |
| assert shot_count >= 2, f"expected >=2 shots in reel, got {shot_count}" |
| assert all(os.path.isfile(p) for p in clip_paths) |
| assert first_frames.shape[0] == shot_count |
|
|