Spaces:
Running
Running
File size: 4,086 Bytes
cbfaa69 c537a4f 374c72e c537a4f 374c72e c537a4f 374c72e c537a4f 9a06bc2 c537a4f 6d66777 c537a4f 6d66777 374c72e c537a4f 6d66777 c537a4f 6d66777 c537a4f 6d66777 c537a4f 6d66777 c537a4f 6d66777 c537a4f 6d66777 c537a4f 6d66777 c537a4f 6d66777 c537a4f 6d66777 c537a4f 9a06bc2 c537a4f 6d66777 374c72e c537a4f |
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 |
import gradio as gr
import asyncio
import edge_tts
import requests
import tempfile
import os
from datetime import datetime
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip
# Voz predeterminada (puedes cambiarla o cargar lista)
VOCES = [{'ShortName': 'es-ES-ElviraNeural', 'Name': 'Elvira', 'Gender': 'Female'}]
VOICE_NAMES = [f"{v['Name']} ({v['Gender']})" for v in VOCES]
# Simula función para generar texto según prompt
def generar_texto(prompt):
# Aquí deberías integrar tu generador real, por ahora solo repetimos prompt
return f"Este es un texto generado para el tema: {prompt}"
# Simula función para buscar videos (debes conectar con Pexels u otra API)
def buscar_videos(prompt):
# Retorna lista simulada con links a videos (debes poner tu API real)
return [
{
"video_files": [{"link": "https://filesamples.com/samples/video/mp4/sample_640x360.mp4"}],
"duration": 10
},
{
"video_files": [{"link": "https://filesamples.com/samples/video/mp4/sample_640x360.mp4"}],
"duration": 10
}
]
async def crear_video(prompt, voz_index, musica_path=None):
try:
texto = generar_texto(prompt)
voz_shortname = VOCES[voz_index]['ShortName']
# Generar audio TTS
archivo_audio = "audio.mp3"
await edge_tts.Communicate(texto, voz_shortname).save(archivo_audio)
audio_clip = AudioFileClip(archivo_audio)
duracion_audio = audio_clip.duration
# Cargar música si se pasa
if musica_path:
musica_clip = AudioFileClip(musica_path).volumex(0.2) # Volumen bajo para música
musica_clip = musica_clip.subclip(0, duracion_audio)
audio_final = CompositeAudioClip([musica_clip, audio_clip])
else:
audio_final = audio_clip
# Descargar y preparar videos
videos = buscar_videos(prompt)
if not videos:
return None
clips = []
for v in videos[:3]:
video_url = v['video_files'][0]['link']
response = requests.get(video_url, stream=True)
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
for chunk in response.iter_content(chunk_size=1024*1024):
temp_file.write(chunk)
temp_file.close()
clip = VideoFileClip(temp_file.name).subclip(0, min(duracion_audio/len(videos), v['duration']))
clips.append(clip)
video_final = concatenate_videoclips(clips)
video_final = video_final.set_audio(audio_final)
output_filename = f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
video_final.write_videofile(output_filename, codec="libx264", audio_codec="aac", fps=24)
# Limpieza
audio_clip.close()
if musica_path:
musica_clip.close()
for c in clips:
c.close()
os.remove(c.filename)
os.remove(archivo_audio)
return output_filename
except Exception as e:
return f"Error: {e}"
def run_crear_video(prompt, voz_nombre, musica_file):
try:
voz_index = VOICE_NAMES.index(voz_nombre)
except ValueError:
voz_index = 0
musica_path = musica_file.name if musica_file else None
return asyncio.run(crear_video(prompt, voz_index, musica_path))
with gr.Blocks(title="Generador de Video con TTS y Música de Fondo") as demo:
with gr.Row():
with gr.Column():
prompt = gr.Textbox(label="Tema del video", lines=2)
voz = gr.Dropdown(VOICE_NAMES, label="Voz", value=VOICE_NAMES[0])
musica = gr.File(label="Sube música de fondo (opcional, mp3/wav)", file_types=[".mp3", ".wav"])
btn = gr.Button("Generar Video")
with gr.Column():
salida = gr.Video(label="Video generado")
btn.click(run_crear_video, inputs=[prompt, voz, musica], outputs=salida)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)
|