File size: 3,053 Bytes
1425afc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | 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 |