Spaces:
Sleeping
Sleeping
File size: 4,923 Bytes
8b274aa 15e8c2d bafc5cd 15e8c2d 6d66777 15e8c2d bafc5cd 15e8c2d 1829fd6 15e8c2d 1829fd6 15e8c2d 1829fd6 15e8c2d 1829fd6 15e8c2d 1829fd6 15e8c2d 9b7097e 15e8c2d 1829fd6 15e8c2d 8b274aa bafc5cd 15e8c2d 8b274aa 15e8c2d 6d66777 15e8c2d 374c72e 15e8c2d |
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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
import os
import asyncio
import logging
import tempfile
import requests
from datetime import datetime
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip, afx
import edge_tts
import gradio as gr
from transformers import GPT2Tokenizer, GPT2LMHeadModel
import torch
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Inicializa tokenizer y modelo (puedes cambiar modelo si quieres)
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
model = GPT2LMHeadModel.from_pretrained("gpt2").eval()
def generate_script(prompt, max_length=300):
logger.info("Generando guion...")
inputs = tokenizer(prompt, return_tensors="pt", truncation=False)
with torch.no_grad():
outputs = model.generate(
**inputs,
max_length=max_length,
do_sample=True,
top_p=0.95,
top_k=60,
temperature=0.9,
pad_token_id=tokenizer.eos_token_id
)
text = tokenizer.decode(outputs[0], skip_special_tokens=True)
logger.info(f"Guion generado, longitud: {len(text)} caracteres")
return text
async def text_to_speech(text, voice="es-ES-ElviraNeural", output_path="voz.mp3"):
logger.info("Generando audio TTS...")
communicate = edge_tts.Communicate(text, voice)
await communicate.save(output_path)
logger.info(f"Audio guardado en {output_path}")
def download_video_sample(url):
logger.info(f"Descargando video de ejemplo: {url}")
tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
response = requests.get(url, stream=True)
for chunk in response.iter_content(chunk_size=1024*1024):
tmp.write(chunk)
tmp.close()
return tmp.name
def loop_audio_to_length(audio_clip, target_duration):
if audio_clip.duration >= target_duration:
return audio_clip.subclip(0, target_duration)
loops = int(target_duration // audio_clip.duration) + 1
audios = [audio_clip] * loops
concatenated = concatenate_videoclips(audios, method="compose")
return concatenated.subclip(0, target_duration)
def crear_video(prompt, musica_url=None):
# 1. Generar guion
guion = generate_script(prompt, max_length=300)
# 2. TTS
voz_archivo = "voz.mp3"
asyncio.run(text_to_speech(guion, output_path=voz_archivo))
# 3. Descargar videos de ejemplo (puedes reemplazar por tu búsqueda real)
# Aquí pongo 3 clips de ejemplo (deberías poner tus URLs)
video_urls = [
"https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_1mb.mp4",
"https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_1mb.mp4",
"https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_1mb.mp4"
]
clips = []
for url in video_urls[:3]:
video_path = download_video_sample(url)
clip = VideoFileClip(video_path).subclip(0, 10) # máximo 10 segundos
clips.append(clip)
# 4. Concatenar videos
video_final = concatenate_videoclips(clips, method="compose")
# 5. Cargar audio TTS
audio_tts = AudioFileClip(voz_archivo)
# 6. Música de fondo en loop si está definida
if musica_url:
musica_path = download_video_sample(musica_url)
musica_audio = AudioFileClip(musica_path)
# Loop música a duración voz
musica_loop = loop_audio_to_length(musica_audio, audio_tts.duration)
# Mezclar audio TTS y música
mezcla = CompositeAudioClip([musica_loop.volumex(0.3), audio_tts.volumex(1.0)])
else:
mezcla = audio_tts
# 7. Asignar audio al video
video_final = video_final.set_audio(mezcla).subclip(0, audio_tts.duration)
# 8. Guardar video final
output_path = f"video_output_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
video_final.write_videofile(output_path, fps=24, threads=2, logger=None)
# 9. Limpiar archivos temporales
os.remove(voz_archivo)
for clip in clips:
clip.close()
return output_path
def run_app(prompt, musica_url):
logger.info(f"Entrada recibida: {prompt}")
try:
video_path = crear_video(prompt, musica_url if musica_url.strip() else None)
logger.info(f"Video generado en: {video_path}")
return video_path
except Exception as e:
logger.error(f"Error durante la generación: {e}")
return None
with gr.Blocks() as app:
gr.Markdown("### Generador simple de video con texto, voz y música en loop")
with gr.Row():
prompt_input = gr.Textbox(label="Introduce el tema para generar el guion", lines=2)
musica_input = gr.Textbox(label="URL de música (opcional) para usar de fondo")
boton = gr.Button("Generar video")
salida = gr.Video(label="Video generado")
boton.click(run_app, inputs=[prompt_input, musica_input], outputs=salida)
if __name__ == "__main__":
app.launch(server_name="0.0.0.0", server_port=7860)
|