Skip to content

Commit 26a50cf

Browse files
committed
[tests] Expand VFR test coverage and rework CLI tests
Use Click's CliRunner rather than subprocesses for CLI tests. Add CSV, EDL, and expand OTIO tests for VFR and compare that the OpenCV and PyAV backends return equal results for both CFR and VFR video.
1 parent 701cdb7 commit 26a50cf

File tree

3 files changed

+431
-222
lines changed

3 files changed

+431
-222
lines changed

scenedetect/_cli/commands.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,9 @@ def save_xml(
487487
logger.error(f"Unknown format: {format}")
488488

489489

490+
# TODO: We have to export framerate as a float for OTIO's current format. When OTIO supports
491+
# fractional timecodes, we should export the framerate as a rational number instead.
492+
# https://github.com/AcademySoftwareFoundation/OpenTimelineIO/issues/190
490493
def save_otio(
491494
context: CliContext,
492495
scenes: SceneList,

tests/test_cli.py

Lines changed: 84 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import scenedetect
4040
from scenedetect.output import is_ffmpeg_available, is_mkvmerge_available
4141

42+
from .helpers import invoke_cli
43+
4244
SCENEDETECT_CMD = sys.executable + " -m scenedetect"
4345

4446
ALL_DETECTORS = [
@@ -303,14 +305,22 @@ def test_cli_detector_with_stats(tmp_path, detector_command: str):
303305

304306
def test_cli_list_scenes(tmp_path: Path):
305307
"""Test `list-scenes` command."""
306-
# Regular invocation
307-
assert (
308-
invoke_scenedetect(
309-
"-i {VIDEO} time {TIME} {DETECTOR} list-scenes",
310-
output_dir=tmp_path,
311-
)
312-
== 0
308+
exit_code, _ = invoke_cli(
309+
[
310+
"-i",
311+
DEFAULT_VIDEO_PATH,
312+
"-o",
313+
str(tmp_path),
314+
"time",
315+
"-s",
316+
"2s",
317+
"-d",
318+
"4s",
319+
"detect-content",
320+
"list-scenes",
321+
]
313322
)
323+
assert exit_code == 0
314324
output_path = tmp_path.joinpath(f"{DEFAULT_VIDEO_NAME}-Scenes.csv")
315325
assert os.path.exists(output_path)
316326
EXPECTED_CSV_OUTPUT = """Timecode List:,00:00:03.754
@@ -742,13 +752,22 @@ def test_cli_load_scenes_round_trip():
742752

743753
def test_cli_save_edl(tmp_path: Path):
744754
"""Test `save-edl` command."""
745-
assert (
746-
invoke_scenedetect(
747-
"-i {VIDEO} time {TIME} {DETECTOR} save-edl",
748-
output_dir=tmp_path,
749-
)
750-
== 0
755+
exit_code, _ = invoke_cli(
756+
[
757+
"-i",
758+
DEFAULT_VIDEO_PATH,
759+
"-o",
760+
str(tmp_path),
761+
"time",
762+
"-s",
763+
"2s",
764+
"-d",
765+
"4s",
766+
"detect-content",
767+
"save-edl",
768+
]
751769
)
770+
assert exit_code == 0
752771
output_path = tmp_path.joinpath(f"{DEFAULT_VIDEO_NAME}.edl")
753772
assert os.path.exists(output_path)
754773
EXPECTED_EDL_OUTPUT = f"""* CREATED WITH PYSCENEDETECT {scenedetect.__version__}
@@ -763,13 +782,28 @@ def test_cli_save_edl(tmp_path: Path):
763782

764783
def test_cli_save_edl_with_params(tmp_path: Path):
765784
"""Test `save-edl` command but override the other options."""
766-
assert (
767-
invoke_scenedetect(
768-
"-i {VIDEO} time {TIME} {DETECTOR} save-edl -t title -r BX -f file_no_ext",
769-
output_dir=tmp_path,
770-
)
771-
== 0
785+
exit_code, _ = invoke_cli(
786+
[
787+
"-i",
788+
DEFAULT_VIDEO_PATH,
789+
"-o",
790+
str(tmp_path),
791+
"time",
792+
"-s",
793+
"2s",
794+
"-d",
795+
"4s",
796+
"detect-content",
797+
"save-edl",
798+
"-t",
799+
"title",
800+
"-r",
801+
"BX",
802+
"-f",
803+
"file_no_ext",
804+
]
772805
)
806+
assert exit_code == 0
773807
output_path = tmp_path.joinpath("file_no_ext")
774808
assert os.path.exists(output_path)
775809
EXPECTED_EDL_OUTPUT = f"""* CREATED WITH PYSCENEDETECT {scenedetect.__version__}
@@ -784,13 +818,22 @@ def test_cli_save_edl_with_params(tmp_path: Path):
784818

785819
def test_cli_save_otio(tmp_path: Path):
786820
"""Test `save-otio` command."""
787-
assert (
788-
invoke_scenedetect(
789-
"-i {VIDEO} time {TIME} {DETECTOR} save-otio",
790-
output_dir=tmp_path,
791-
)
792-
== 0
821+
exit_code, _ = invoke_cli(
822+
[
823+
"-i",
824+
DEFAULT_VIDEO_PATH,
825+
"-o",
826+
str(tmp_path),
827+
"time",
828+
"-s",
829+
"2s",
830+
"-d",
831+
"4s",
832+
"detect-content",
833+
"save-otio",
834+
]
793835
)
836+
assert exit_code == 0
794837
output_path = tmp_path.joinpath(f"{DEFAULT_VIDEO_NAME}.otio")
795838
assert os.path.exists(output_path)
796839
EXPECTED_OTIO_OUTPUT = """{
@@ -992,13 +1035,23 @@ def test_cli_save_otio(tmp_path: Path):
9921035

9931036
def test_cli_save_otio_no_audio(tmp_path: Path):
9941037
"""Test `save-otio` command without audio."""
995-
assert (
996-
invoke_scenedetect(
997-
"-i {VIDEO} time {TIME} {DETECTOR} save-otio --no-audio",
998-
output_dir=tmp_path,
999-
)
1000-
== 0
1038+
exit_code, _ = invoke_cli(
1039+
[
1040+
"-i",
1041+
DEFAULT_VIDEO_PATH,
1042+
"-o",
1043+
str(tmp_path),
1044+
"time",
1045+
"-s",
1046+
"2s",
1047+
"-d",
1048+
"4s",
1049+
"detect-content",
1050+
"save-otio",
1051+
"--no-audio",
1052+
]
10011053
)
1054+
assert exit_code == 0
10021055
output_path = tmp_path.joinpath(f"{DEFAULT_VIDEO_NAME}.otio")
10031056
assert os.path.exists(output_path)
10041057
EXPECTED_OTIO_OUTPUT = """{

0 commit comments

Comments
 (0)