from moviepy.editor import VideoFileClip import os import logging logger = logging.getLogger(__name__) # ===================================================== # SEGMENT NORMALIZER (CRITICAL V8 FIX) # ===================================================== def normalize_segments(segments): """ Accepts: - dict segments: {"start": x, "end": y} - list segments: [{"start":x,"end":y}, ...] - tuple/list segments: [(start,end), ...] Returns: - clean list of dicts """ if not segments: return [] normalized = [] # Case 1: single dict if isinstance(segments, dict): segments = [segments] for s in segments: # dict format (preferred) if isinstance(s, dict): if "start" in s and "end" in s: normalized.append({ "start": float(s["start"]), "end": float(s["end"]) }) continue # list/tuple format if isinstance(s, (list, tuple)) and len(s) >= 2: try: normalized.append({ "start": float(s[0]), "end": float(s[1]) }) except Exception: continue return normalized # ===================================================== # CORE CLIP GENERATOR (SAFE VERSION) # ===================================================== def create_clip(video_path, start, end, index): """ Creates a single clip safely with validation """ try: start = float(start) end = float(end) if end <= start: logger.warning(f"Invalid segment skipped: {start}-{end}") return None clip = VideoFileClip(video_path).subclip(start, end) output = video_path.replace( ".mp4", f"_clip_{index}.mp4" ) clip.write_videofile( output, codec="libx264", audio_codec="aac", preset="ultrafast", threads=2, logger=None # prevents HF log spam ) return output except Exception as e: logger.error(f"Clip creation failed: {str(e)}") return None # ===================================================== # BATCH CLIP ENGINE (V8 AUTOCUT CORE FIX) # ===================================================== def create_clips(video_path, segments): """ Main entry used by V8 Highlights / AutoClip engine """ segments = normalize_segments(segments) if not segments: logger.warning("No valid segments found") return [] outputs = [] for i, seg in enumerate(segments): try: out = create_clip( video_path, seg["start"], seg["end"], i ) if out: outputs.append(out) except Exception as e: logger.error(f"Segment {i} failed: {str(e)}") continue return outputs