(context: CliContext)
| 175 | |
| 176 | |
| 177 | def _load_scenes(context: CliContext) -> tuple[SceneList, CutList]: |
| 178 | assert context.load_scenes_input |
| 179 | assert context.load_scenes_column_name is not None |
| 180 | assert context.video_stream is not None |
| 181 | assert os.path.exists(context.load_scenes_input) |
| 182 | |
| 183 | video_stream = context.video_stream |
| 184 | with open(context.load_scenes_input) as input_file: |
| 185 | file_reader = csv.reader(input_file) |
| 186 | csv_headers = next(file_reader) |
| 187 | if context.load_scenes_column_name not in csv_headers: |
| 188 | csv_headers = next(file_reader) |
| 189 | # Check to make sure column headers are present and then load the data. |
| 190 | if context.load_scenes_column_name not in csv_headers: |
| 191 | raise ValueError("specified column header for scene start is not present") |
| 192 | col_idx = csv_headers.index(context.load_scenes_column_name) |
| 193 | |
| 194 | def calculate_timecode(value: str) -> FrameTimecode: |
| 195 | # Assume other columns are in seconds except frame numbers. |
| 196 | if value.isdigit(): |
| 197 | # Frame numbers start from index 1 in the CLI output so we correct for that. |
| 198 | return FrameTimecode(int(value) - 1, fps=video_stream.frame_rate) |
| 199 | return FrameTimecode(value, fps=video_stream.frame_rate) |
| 200 | |
| 201 | cut_list = sorted(calculate_timecode(row[col_idx]) for row in file_reader) |
| 202 | # `SceneDetector` works on cuts, so we have to skip the first scene and place the first |
| 203 | # cut point where the next scenes starts. |
| 204 | if cut_list: |
| 205 | cut_list = cut_list[1:] |
| 206 | |
| 207 | start_time = context.video_stream.base_timecode |
| 208 | if context.start_time is not None: |
| 209 | start_time = context.start_time |
| 210 | cut_list = [cut for cut in cut_list if cut > context.start_time] |
| 211 | |
| 212 | video_duration = context.video_stream.duration |
| 213 | assert video_duration is not None |
| 214 | end_time = video_duration |
| 215 | if context.end_time is not None: |
| 216 | end_time = min(context.end_time, video_duration) |
| 217 | elif context.duration is not None: |
| 218 | end_time = min(start_time + context.duration, video_duration) |
| 219 | |
| 220 | cut_list = [cut for cut in cut_list if cut < end_time] |
| 221 | scene_list = get_scenes_from_cuts(cut_list=cut_list, start_pos=start_time, end_pos=end_time) |
| 222 | |
| 223 | return (scene_list, cut_list) |
no test coverage detected