Spaces:
Sleeping
Sleeping
import os | |
import gradio as gr | |
import requests | |
import tempfile | |
import asyncio | |
import edge_tts | |
from datetime import datetime | |
from moviepy.editor import ( | |
VideoFileClip, AudioFileClip, | |
concatenate_videoclips, CompositeAudioClip, afx | |
) | |
from transformers import pipeline | |
import nest_asyncio | |
nest_asyncio.apply() | |
# Generador de texto | |
generador = pipeline("text-generation", model="gpt2") | |
# Obtener voces disponibles | |
async def get_voices(): | |
voices = await edge_tts.list_voices() | |
return voices | |
VOICES = asyncio.run(get_voices()) | |
VOICE_OPTIONS = [ | |
f"{v['Name']} ({v['Gender']}, {v['Locale']})" for v in VOICES | |
] | |
VOICE_MAP = {v['Name']: v['ShortName'] for v in VOICES} | |
# Mock de videos | |
def buscar_videos_mock(): | |
return [ | |
"https://samplelib.com/lib/preview/mp4/sample-5s.mp4", | |
"https://samplelib.com/lib/preview/mp4/sample-10s.mp4" | |
] | |
# Mock de m煤sica | |
def buscar_musica_mock(): | |
return "https://samplelib.com/lib/preview/mp3/sample-3s.mp3" | |
# Funci贸n principal | |
async def generar_video(prompt, voz_str): | |
try: | |
# 1. Texto largo | |
texto = generador(prompt, max_length=300, do_sample=True)[0]['generated_text'] | |
# 2. Voz | |
voz_id = voz_str.split(" ")[0] | |
short_name = VOICE_MAP.get(voz_id, "es-ES-ElviraNeural") | |
voz_path = "voz.mp3" | |
await edge_tts.Communicate(text=texto, voice=short_name).save(voz_path) | |
voz_clip = AudioFileClip(voz_path) | |
# 3. Videos | |
video_urls = buscar_videos_mock() | |
clips = [] | |
for url in video_urls: | |
r = requests.get(url, stream=True) | |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as f: | |
for chunk in r.iter_content(1024 * 1024): | |
f.write(chunk) | |
f.flush() | |
clips.append(VideoFileClip(f.name).subclip(0, 5)) | |
video = concatenate_videoclips(clips).set_audio(voz_clip) | |
# 4. M煤sica (loop) | |
music_url = buscar_musica_mock() | |
r = requests.get(music_url, stream=True) | |
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f: | |
for chunk in r.iter_content(1024 * 1024): | |
f.write(chunk) | |
f.flush() | |
music_clip = AudioFileClip(f.name) | |
music_loop = afx.audio_loop(music_clip, duration=video.duration).volumex(0.3) | |
# 5. Composici贸n de audio | |
final_audio = CompositeAudioClip([video.audio, music_loop]) | |
video = video.set_audio(final_audio) | |
# 6. Guardar | |
output_path = f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4" | |
video.write_videofile(output_path, fps=24) | |
return output_path | |
except Exception as e: | |
return f"Error: {e}" | |
# Interfaz Gradio | |
with gr.Blocks() as demo: | |
prompt = gr.Textbox(label="Prompt", placeholder="Escribe un tema...") | |
voz_dropdown = gr.Dropdown(VOICE_OPTIONS, label="Voz", value=VOICE_OPTIONS[0]) | |
btn = gr.Button("Generar video") | |
salida = gr.Video(label="Resultado") | |
btn.click(fn=lambda p, v: asyncio.run(generar_video(p, v)), | |
inputs=[prompt, voz_dropdown], | |
outputs=salida) | |
if __name__ == "__main__": | |
demo.launch(server_name="0.0.0.0", server_port=7860) | |