Spaces:
Running
Running
Update video_processor.py
Browse files- video_processor.py +40 -40
video_processor.py
CHANGED
@@ -36,14 +36,14 @@ def generate_audio_with_elevenlabs(text, output_path):
|
|
36 |
return False
|
37 |
|
38 |
def create_video(video_script, audio_script, summary):
|
39 |
-
"""Create educational video
|
40 |
try:
|
41 |
-
# Generate audio
|
42 |
audio_path = os.path.join(tempfile.gettempdir(), "narration.mp3")
|
43 |
if not generate_audio_with_elevenlabs(audio_script, audio_path):
|
44 |
raise Exception("Audio generation failed")
|
45 |
-
|
46 |
-
# Parse scenes
|
47 |
scenes = []
|
48 |
for scene_text in video_script.split("\n\n"):
|
49 |
if "[Visual]:" in scene_text:
|
@@ -52,59 +52,59 @@ def create_video(video_script, audio_script, summary):
|
|
52 |
"voiceover": scene_text.split("[Voiceover]:")[1].strip()
|
53 |
}
|
54 |
scenes.append(scene)
|
55 |
-
|
56 |
-
#
|
57 |
video_clips = []
|
58 |
for scene in scenes:
|
59 |
try:
|
60 |
-
|
61 |
f"https://api.pexels.com/videos/search?query={scene['visual']}&per_page=1",
|
62 |
headers={"Authorization": PEXELS_API_KEY},
|
63 |
timeout=10
|
64 |
)
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
67 |
|
68 |
-
clip = VideoFileClip(
|
69 |
-
clip = clip.resize(height=1080)
|
70 |
video_clips.append(clip)
|
71 |
except Exception as e:
|
72 |
-
print(f"Failed to
|
73 |
-
|
74 |
-
|
75 |
if not video_clips:
|
76 |
-
raise Exception("No
|
77 |
-
|
78 |
-
# Combine
|
79 |
-
final_video = concatenate_videoclips(video_clips)
|
80 |
-
audio_clip = AudioFileClip(audio_path)
|
81 |
final_video = final_video.set_audio(audio_clip)
|
82 |
-
|
83 |
-
# Create subtitles
|
84 |
def create_subtitle(text):
|
85 |
return TextClip(
|
86 |
-
text,
|
87 |
-
fontsize=40,
|
88 |
-
color='white',
|
89 |
-
font='Arial-Bold',
|
90 |
-
stroke_color='black',
|
91 |
stroke_width=1
|
92 |
).set_position(('center', 'bottom')).set_duration(8)
|
93 |
-
|
94 |
-
subtitles = [create_subtitle(scene['voiceover']) for scene in scenes]
|
95 |
-
|
96 |
-
|
97 |
-
# Add watermark
|
98 |
watermark = TextClip(
|
99 |
-
"MentorMindz",
|
100 |
-
fontsize=30,
|
101 |
color='white'
|
102 |
).set_position(('right', 'top')).set_duration(final_video.duration)
|
103 |
-
|
104 |
-
# Combine all
|
105 |
-
final_video = CompositeVideoClip([final_video, subtitles, watermark])
|
106 |
-
|
107 |
-
# Export
|
108 |
output_path = os.path.join(tempfile.gettempdir(), "final_output.mp4")
|
109 |
final_video.write_videofile(
|
110 |
output_path,
|
@@ -113,8 +113,8 @@ def create_video(video_script, audio_script, summary):
|
|
113 |
fps=24,
|
114 |
threads=4
|
115 |
)
|
116 |
-
|
117 |
return output_path
|
118 |
-
|
119 |
except Exception as e:
|
120 |
raise Exception(f"Video creation failed: {str(e)}")
|
|
|
36 |
return False
|
37 |
|
38 |
def create_video(video_script, audio_script, summary):
|
39 |
+
"""Create educational video using Pexels and ElevenLabs"""
|
40 |
try:
|
41 |
+
# Step 1: Generate audio
|
42 |
audio_path = os.path.join(tempfile.gettempdir(), "narration.mp3")
|
43 |
if not generate_audio_with_elevenlabs(audio_script, audio_path):
|
44 |
raise Exception("Audio generation failed")
|
45 |
+
|
46 |
+
# Step 2: Parse scenes
|
47 |
scenes = []
|
48 |
for scene_text in video_script.split("\n\n"):
|
49 |
if "[Visual]:" in scene_text:
|
|
|
52 |
"voiceover": scene_text.split("[Voiceover]:")[1].strip()
|
53 |
}
|
54 |
scenes.append(scene)
|
55 |
+
|
56 |
+
# Step 3: Fetch video clips from Pexels
|
57 |
video_clips = []
|
58 |
for scene in scenes:
|
59 |
try:
|
60 |
+
response = requests.get(
|
61 |
f"https://api.pexels.com/videos/search?query={scene['visual']}&per_page=1",
|
62 |
headers={"Authorization": PEXELS_API_KEY},
|
63 |
timeout=10
|
64 |
)
|
65 |
+
response.raise_for_status()
|
66 |
+
video_files = response.json()['videos'][0]['video_files']
|
67 |
+
mp4_url = next((file['link'] for file in video_files if file['file_type'] == 'video/mp4' and file['quality'] == 'sd'), None)
|
68 |
+
if not mp4_url:
|
69 |
+
raise Exception("No MP4 video found.")
|
70 |
|
71 |
+
clip = VideoFileClip(mp4_url).subclip(0, 8).resize(height=1080)
|
|
|
72 |
video_clips.append(clip)
|
73 |
except Exception as e:
|
74 |
+
print(f"Failed to fetch video for scene '{scene['visual']}': {str(e)}")
|
75 |
+
|
|
|
76 |
if not video_clips:
|
77 |
+
raise Exception("No video clips found")
|
78 |
+
|
79 |
+
# Step 4: Combine clips and set audio
|
80 |
+
final_video = concatenate_videoclips(video_clips, method="compose")
|
81 |
+
audio_clip = AudioFileClip(audio_path).set_duration(final_video.duration)
|
82 |
final_video = final_video.set_audio(audio_clip)
|
83 |
+
|
84 |
+
# Step 5: Create subtitles
|
85 |
def create_subtitle(text):
|
86 |
return TextClip(
|
87 |
+
text,
|
88 |
+
fontsize=40,
|
89 |
+
color='white',
|
90 |
+
font='Arial-Bold',
|
91 |
+
stroke_color='black',
|
92 |
stroke_width=1
|
93 |
).set_position(('center', 'bottom')).set_duration(8)
|
94 |
+
|
95 |
+
subtitles = [create_subtitle(scene['voiceover']).set_start(i * 8) for i, scene in enumerate(scenes)]
|
96 |
+
|
97 |
+
# Step 6: Add watermark
|
|
|
98 |
watermark = TextClip(
|
99 |
+
"MentorMindz",
|
100 |
+
fontsize=30,
|
101 |
color='white'
|
102 |
).set_position(('right', 'top')).set_duration(final_video.duration)
|
103 |
+
|
104 |
+
# Step 7: Combine all layers
|
105 |
+
final_video = CompositeVideoClip([final_video, *subtitles, watermark])
|
106 |
+
|
107 |
+
# Step 8: Export
|
108 |
output_path = os.path.join(tempfile.gettempdir(), "final_output.mp4")
|
109 |
final_video.write_videofile(
|
110 |
output_path,
|
|
|
113 |
fps=24,
|
114 |
threads=4
|
115 |
)
|
116 |
+
|
117 |
return output_path
|
118 |
+
|
119 |
except Exception as e:
|
120 |
raise Exception(f"Video creation failed: {str(e)}")
|