Spaces:
Running
Running
import gradio as gr | |
import edge_tts | |
import asyncio | |
import os | |
import logging | |
import torch | |
from transformers import pipeline, set_seed | |
from moviepy.editor import * | |
from dotenv import load_dotenv | |
# Configurar logs visibles en Hugging Face | |
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s") | |
# Cargar variables de entorno si hay .env | |
load_dotenv() | |
# Verificar si CUDA está disponible | |
device = 0 if torch.cuda.is_available() else -1 | |
# Inicializar generador de texto | |
generator = pipeline("text-generation", model="gpt2", device=device) | |
set_seed(42) | |
# Asíncrono: convertir texto a voz con edge-tts | |
async def text_to_speech(text, output_path, voice="es-MX-DaliaNeural"): | |
tts = edge_tts.Communicate(text=text, voice=voice) | |
await tts.save(output_path) | |
def generate_video(prompt, background_music_path="musica.mp3"): | |
logging.info("🚀 Generando guion con IA...") | |
result = generator(prompt, max_length=500, do_sample=True, truncation=True) | |
script = result[0]['generated_text'] | |
logging.info("🗣 Guion generado.") | |
# Guardar guion a texto plano | |
with open("guion.txt", "w") as f: | |
f.write(script) | |
# Convertir texto a voz (bloqueo controlado) | |
output_audio = "voz.mp3" | |
try: | |
asyncio.run(text_to_speech(script, output_audio)) | |
logging.info("🎤 Voz generada.") | |
except Exception as e: | |
logging.error(f"❌ Error generando voz: {e}") | |
return None, script | |
# Cargar clip de voz | |
voice_clip = AudioFileClip(output_audio) | |
duration = voice_clip.duration | |
# Video negro (fondo) + voz | |
video = ColorClip(size=(1280, 720), color=(0, 0, 0), duration=duration) | |
# Música en loop si es más corta que la voz | |
if os.path.exists(background_music_path): | |
music = AudioFileClip(background_music_path) | |
if music.duration < duration: | |
loops = int(duration // music.duration) + 1 | |
music = concatenate_audioclips([music] * loops) | |
music = music.subclip(0, duration) | |
final_audio = CompositeAudioClip([music.volumex(0.2), voice_clip]) | |
else: | |
final_audio = voice_clip | |
video = video.set_audio(final_audio) | |
output_path = "video_generado.mp4" | |
video.write_videofile(output_path, fps=24, codec="libx264", audio_codec="aac") | |
return output_path, script | |
# Interfaz de Gradio | |
with gr.Blocks() as app: | |
gr.Markdown("# 🎬 Generador de video IA + Voz + Música") | |
prompt = gr.Textbox(label="Prompt del guion") | |
boton = gr.Button("Generar video") | |
salida_video = gr.Video() | |
salida_texto = gr.Textbox(label="Guion generado") | |
def ejecutar(prompt): | |
video, script = generate_video(prompt) | |
return video, script | |
boton.click(ejecutar, inputs=prompt, outputs=[salida_video, salida_texto]) | |
# Lanzar app | |
app.launch(debug=True) | |