The state of the application representing what video will be processed, how, and what to do with the result. This includes handling all input options via command line and config file. Once the CLI creates a context, it is executed by passing it to the `scenedetect._cli.controller.run_sce
| 72 | |
| 73 | |
| 74 | class CliContext: |
| 75 | """The state of the application representing what video will be processed, how, and what to do |
| 76 | with the result. This includes handling all input options via command line and config file. |
| 77 | Once the CLI creates a context, it is executed by passing it to the |
| 78 | `scenedetect._cli.controller.run_scenedetect` function. |
| 79 | """ |
| 80 | |
| 81 | def __init__(self): |
| 82 | # State: |
| 83 | self.config: ConfigRegistry = USER_CONFIG |
| 84 | self.quiet_mode: bool | None = None |
| 85 | self.scene_manager: SceneManager | None = None |
| 86 | self.stats_manager: StatsManager | None = None |
| 87 | self.save_images: bool = False # True if the save-images command was specified |
| 88 | self.save_images_result: ty.Any = (None, None) # Result of save-images used by save-html |
| 89 | |
| 90 | # Input: |
| 91 | self.video_stream: VideoStream | None = None |
| 92 | self.load_scenes_input: str | None = None # load-scenes -i/--input |
| 93 | self.load_scenes_column_name: str | None = None # load-scenes -c/--start-col-name |
| 94 | self.start_time: FrameTimecode | None = None # time -s/--start |
| 95 | self.end_time: FrameTimecode | None = None # time -e/--end |
| 96 | self.duration: FrameTimecode | None = None # time -d/--duration |
| 97 | self.frame_skip: int | None = None |
| 98 | |
| 99 | # Options: |
| 100 | self.drop_short_scenes: bool | None = None |
| 101 | self.merge_last_scene: bool | None = None |
| 102 | self.min_scene_len: FrameTimecode | None = None |
| 103 | self.default_detector: tuple[type[SceneDetector], dict[str, ty.Any]] | None = None |
| 104 | self.output: str | None = None |
| 105 | self.stats_file_path: str | None = None |
| 106 | |
| 107 | # Output Commands (e.g. split-video, save-images): |
| 108 | # Commands to run after the detection pipeline. Stored as (callback, args) and invoked with |
| 109 | # the results of the detection pipeline by the controller. |
| 110 | self.commands: list[tuple[ty.Callable, dict[str, ty.Any]]] = [] |
| 111 | |
| 112 | def add_command(self, command: ty.Callable, command_args: dict[str, ty.Any]): |
| 113 | """Add `command` to the processing pipeline. Will be called after processing the input.""" |
| 114 | if "output" in command_args and command_args["output"] is None: |
| 115 | command_args["output"] = self.output |
| 116 | logger.debug("Adding command: %s(%s)", command.__name__, command_args) |
| 117 | self.commands.append((command, command_args)) |
| 118 | |
| 119 | def add_detector(self, detector: type[SceneDetector], detector_args: dict[str, ty.Any]): |
| 120 | """Instantiate and add `detector` to the processing pipeline.""" |
| 121 | if self.load_scenes_input: |
| 122 | raise click.ClickException("The load-scenes command cannot be used with detectors.") |
| 123 | assert self.scene_manager is not None |
| 124 | logger.debug("Adding detector: %s(%s)", detector.__name__, detector_args) |
| 125 | self.scene_manager.add_detector(detector(**detector_args)) |
| 126 | |
| 127 | def ensure_detector(self): |
| 128 | """Ensures at least one detector has been instantiated, otherwise adds a default one.""" |
| 129 | assert self.scene_manager is not None |
| 130 | assert self.default_detector is not None |
| 131 | if self.scene_manager.get_num_detectors() == 0: |
no outgoing calls
no test coverage detected