@@ -413,6 +413,59 @@ def combine_scenes(scene_list: Sequence[Tuple], config: ProcessingConfig) -> Lis
413413 return combined_scene_list
414414
415415
416+ class _SecondsTime :
417+ """Lightweight stand-in for scene time objects using seconds.
418+
419+ Provides the minimal API used elsewhere: get_seconds(), get_timecode(), get_frames().
420+ Frames are computed assuming 30 fps to keep behavior consistent with tests.
421+ """
422+
423+ def __init__ (self , seconds : float ):
424+ self ._seconds = float (seconds )
425+
426+ def get_seconds (self ) -> float :
427+ return self ._seconds
428+
429+ def get_timecode (self ) -> str :
430+ # Keep simple representation similar to tests' MockTime
431+ return str (self ._seconds )
432+
433+ def get_frames (self ) -> int :
434+ return int (self ._seconds * 30 )
435+
436+
437+ def split_overlong_scenes (combined_scene_list : List [List ], config : ProcessingConfig ) -> List [List ]:
438+ """Split scenes longer than 4 * max_short_length into n equal parts.
439+
440+ For each scene with duration D > 4 * max_short_length, compute
441+ n = floor(D / (2 * max_short_length)) and split the scene into n
442+ equal sub-scenes. Scenes not exceeding the threshold are kept as is.
443+ """
444+
445+ result : List [List ] = []
446+ threshold = 4 * config .max_short_length
447+ for scene in combined_scene_list :
448+ start_s = scene [0 ].get_seconds ()
449+ end_s = scene [1 ].get_seconds ()
450+ duration = end_s - start_s
451+
452+ if duration > threshold :
453+ n = int (math .floor (duration / (2 * config .max_short_length )))
454+ if n <= 1 :
455+ result .append (scene )
456+ continue
457+
458+ part_len = duration / n
459+ for i in range (n ):
460+ part_start = start_s + i * part_len
461+ part_end = start_s + (i + 1 ) * part_len
462+ result .append ([_SecondsTime (part_start ), _SecondsTime (part_end )])
463+ else :
464+ result .append (scene )
465+
466+ return result
467+
468+
416469def process_video (video_file : Path , config : ProcessingConfig , output_dir : Path ) -> None :
417470 """Process a single video file and generate short clips."""
418471
@@ -424,14 +477,15 @@ def process_video(video_file: Path, config: ProcessingConfig, output_dir: Path)
424477 logging .info ("Computing audio action profile..." )
425478 audio_times , audio_score = compute_audio_action_profile (video_file )
426479
427- combined_scene_list = combine_scenes (scene_list , config )
480+ processed_scene_list = combine_scenes (scene_list , config )
481+ processed_scene_list = split_overlong_scenes (processed_scene_list , config )
428482
429- logging .info ("Combined scenes list with action scores:" )
430- for i , scene in enumerate (combined_scene_list , start = 1 ):
483+ logging .info ("Scenes list with action scores:" )
484+ for i , scene in enumerate (processed_scene_list , start = 1 ):
431485 duration = scene [1 ].get_seconds () - scene [0 ].get_seconds ()
432486 score_val = scene_action_score (scene , audio_times , audio_score )
433487 logging .info (
434- " Combined Scene %2d: Duration %5.1f s, ActionScore %7.3f,"
488+ " Scene %2d: Duration %5.1f s, ActionScore %7.3f,"
435489 " Start %s / Frame %d, End %s / Frame %d" ,
436490 i ,
437491 duration ,
@@ -443,14 +497,14 @@ def process_video(video_file: Path, config: ProcessingConfig, output_dir: Path)
443497 )
444498
445499 # Sort by action score, not by length
446- sorted_combined_scene_list = sorted (
447- combined_scene_list ,
500+ sorted_processed_scene_list = sorted (
501+ processed_scene_list ,
448502 key = lambda s : scene_action_score (s , audio_times , audio_score ),
449503 reverse = True ,
450504 )
451505
452- logging .info ("Sorted combined scenes list (by action score):" )
453- for i , scene in enumerate (sorted_combined_scene_list , start = 1 ):
506+ logging .info ("Sorted scenes list (by action score):" )
507+ for i , scene in enumerate (sorted_processed_scene_list , start = 1 ):
454508 duration = scene [1 ].get_seconds () - scene [0 ].get_seconds ()
455509 score_val = scene_action_score (scene , audio_times , audio_score )
456510 logging .info (
@@ -466,9 +520,9 @@ def process_video(video_file: Path, config: ProcessingConfig, output_dir: Path)
466520 )
467521
468522 video_clip = VideoFileClip (str (video_file ))
469- truncated_list = sorted_combined_scene_list [: config .scene_limit ]
523+ truncated_list = sorted_processed_scene_list [: config .scene_limit ]
470524
471- logging .info ("Truncated sorted combined scenes list:" )
525+ logging .info ("Truncated sorted scenes list:" )
472526 for i , scene in enumerate (truncated_list , start = 1 ):
473527 logging .info (
474528 " Scene %2d: Duration %d Start %s / Frame %d, End %s / Frame %d" ,
0 commit comments