File size: 2,849 Bytes
aa61beb
1829fd6
8b274aa
 
bafc5cd
8b274aa
 
 
 
c537a4f
8b274aa
 
6d66777
8b274aa
 
bafc5cd
8b274aa
 
1829fd6
8b274aa
 
 
1829fd6
8b274aa
 
 
 
1829fd6
8b274aa
 
 
 
 
1829fd6
8b274aa
 
 
1829fd6
8b274aa
 
9b7097e
8b274aa
 
1829fd6
8b274aa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bafc5cd
8b274aa
 
 
 
 
 
 
 
 
6d66777
8b274aa
374c72e
8b274aa
 
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
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)