Spaces:
Sleeping
Sleeping
File size: 2,326 Bytes
2c3ea7b 7006220 d53004d 2c3ea7b d53004d 2c3ea7b 7006220 aec5d3a 7006220 d53004d aec5d3a 7006220 2c3ea7b 7006220 d53004d e2fc4a2 d53004d e2fc4a2 d53004d e2fc4a2 d53004d 2c3ea7b d53004d aec5d3a d53004d 2c3ea7b e2fc4a2 d53004d 2c3ea7b d53004d e2fc4a2 2c3ea7b d53004d 2c3ea7b d53004d e2fc4a2 |
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 |
import os, uuid, requests
from gtts import gTTS
from mutagen.mp3 import MP3
from moviepy.editor import ImageClip, concatenate_videoclips, AudioFileClip
from moviepy.config import change_settings
# β
Force MoviePy temp directory to /tmp
change_settings({"FFMPEG_BINARY": "ffmpeg"})
os.environ["TMPDIR"] = "/tmp"
def generate_video_file(script: str, duration: int = None) -> str:
base_tmp = "/tmp/video"
audio_tmp = "/tmp/audio"
tmp_images = "/tmp/video_tmp"
os.makedirs(base_tmp, exist_ok=True)
os.makedirs(audio_tmp, exist_ok=True)
os.makedirs(tmp_images, exist_ok=True)
video_filename = f"video_{uuid.uuid4().hex}.mp4"
video_path = os.path.join(base_tmp, video_filename)
audio_path = os.path.join(audio_tmp, f"audio_{uuid.uuid4().hex}.mp3")
# Step 1: Generate TTS audio
tts = gTTS(text=script, lang='en')
tts.save(audio_path)
# Step 2: Get audio duration
audio = MP3(audio_path)
audio_duration = max(audio.info.length, 3.0)
# Step 3: Fetch Unsplash images
images = fetch_unsplash_images(script, count=3)
if not images:
raise Exception("No images found from Unsplash for the prompt")
clips, tmp_files = [], []
per_image_duration = audio_duration / len(images)
for url in images:
img_data = requests.get(url).content
tmp_file = os.path.join(tmp_images, f"tmp_{uuid.uuid4().hex}.jpg")
tmp_files.append(tmp_file)
with open(tmp_file, "wb") as f:
f.write(img_data)
clip = ImageClip(tmp_file).resize(height=720).set_duration(per_image_duration)
clips.append(clip)
# Step 4: Build final video
final_clip = concatenate_videoclips(clips, method="compose").set_duration(audio_duration)
final_clip = final_clip.set_audio(AudioFileClip(audio_path))
# β
Step 5: Export video with all temp files in /tmp
final_clip.write_videofile(
video_path,
fps=24,
codec="libx264",
audio_codec="aac",
threads=4,
preset="ultrafast",
temp_audiofile="/tmp/temp-audio.m4a",
remove_temp=True,
ffmpeg_params=["-avoid_negative_ts", "make_zero"]
)
# Cleanup images
for file in tmp_files:
try:
os.remove(file)
except:
pass
return video_filename |