Update app.py
Browse files
app.py
CHANGED
|
@@ -16,7 +16,8 @@ import re
|
|
| 16 |
import random
|
| 17 |
from google_drive_upload import authenticate_google_drive, upload_to_google_drive
|
| 18 |
from io import BytesIO
|
| 19 |
-
|
|
|
|
| 20 |
|
| 21 |
# Crear el archivo de credenciales de servicio desde los secretos
|
| 22 |
service_account_info = json.loads(os.getenv('GOOGLE_SERVICE_ACCOUNT', '{}'))
|
|
@@ -29,17 +30,12 @@ output_folder = "outputs"
|
|
| 29 |
os.makedirs(output_folder, exist_ok=True)
|
| 30 |
|
| 31 |
# ID de la carpeta de destino en Google Drive
|
| 32 |
-
FOLDER_ID = "12S6adpanAXjf71pKKGRRPqpzbJa5XEh3" # Reemplaza con tu ID
|
|
|
|
| 33 |
|
| 34 |
def resize_and_add_background(clip, target_width=1920, target_height=1080, background_url="https://wallpaperaccess.com/full/231401.jpg"):
|
| 35 |
"""
|
| 36 |
Redimensiona el video al tamaño 1080p (16:9) y añade una imagen de fondo descargada desde una URL.
|
| 37 |
-
|
| 38 |
-
:param clip: VideoFileClip original.
|
| 39 |
-
:param target_width: Ancho objetivo del video final (por defecto: 1920).
|
| 40 |
-
:param target_height: Alto objetivo del video final (por defecto: 1080).
|
| 41 |
-
:param background_url: URL de la imagen de fondo.
|
| 42 |
-
:return: VideoFileClip procesado con fondo agregado.
|
| 43 |
"""
|
| 44 |
try:
|
| 45 |
w, h = clip.size
|
|
@@ -59,9 +55,10 @@ def resize_and_add_background(clip, target_width=1920, target_height=1080, backg
|
|
| 59 |
.resize((target_width, target_height))
|
| 60 |
)
|
| 61 |
else:
|
| 62 |
-
image_data = BytesIO(response.content)
|
|
|
|
| 63 |
background = (
|
| 64 |
-
ImageClip(
|
| 65 |
.set_duration(clip.duration)
|
| 66 |
.resize((target_width, target_height))
|
| 67 |
)
|
|
@@ -112,7 +109,7 @@ def concatenate_pixabay_videos(keywords, num_videos_per_keyword=1):
|
|
| 112 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_video:
|
| 113 |
tmp_video.write(video_response.content)
|
| 114 |
clip = VideoFileClip(tmp_video.name)
|
| 115 |
-
processed_clip = resize_and_add_background(clip)
|
| 116 |
video_clips.append(processed_clip)
|
| 117 |
os.unlink(tmp_video.name) # Limpiamos el archivo temporal
|
| 118 |
except Exception as e:
|
|
@@ -188,33 +185,40 @@ def process_input(text, txt_file, mp3_file, selected_voice, rate, pitch, keyword
|
|
| 188 |
final_text = txt_file.decode("utf-8")
|
| 189 |
else:
|
| 190 |
raise ValueError("No text input provided")
|
|
|
|
| 191 |
# Generamos el audio
|
| 192 |
audio_file = asyncio.run(text_to_speech(final_text, selected_voice, rate, pitch))
|
| 193 |
if not audio_file:
|
| 194 |
raise ValueError("Failed to generate audio")
|
|
|
|
| 195 |
# Generamos el video
|
| 196 |
video_clip = concatenate_pixabay_videos(keywords, num_videos_per_keyword=1)
|
| 197 |
if not video_clip:
|
| 198 |
raise ValueError("Failed to generate video")
|
|
|
|
| 199 |
# Procesamos la música de fondo si existe
|
| 200 |
music_clip = None
|
| 201 |
if mp3_file is not None:
|
| 202 |
music_clip = adjust_background_music(video_clip.duration, mp3_file.name)
|
|
|
|
| 203 |
# Combinamos todo
|
| 204 |
final_video_path = combine_audio_video(audio_file, video_clip, music_clip)
|
| 205 |
if not final_video_path:
|
| 206 |
raise ValueError("Failed to combine audio and video")
|
|
|
|
| 207 |
# Subimos a Google Drive
|
| 208 |
video_id = upload_to_google_drive(final_video_path, folder_id=FOLDER_ID)
|
| 209 |
if video_id:
|
| 210 |
print(f"Video subido a Google Drive con ID: {video_id}")
|
|
|
|
|
|
|
| 211 |
else:
|
| 212 |
print("Error subiendo el video a Google Drive")
|
| 213 |
-
|
| 214 |
-
|
| 215 |
except Exception as e:
|
| 216 |
print(f"Error durante el procesamiento: {e}")
|
| 217 |
-
return
|
| 218 |
|
| 219 |
|
| 220 |
# Interfaz Gradio
|
|
@@ -227,7 +231,7 @@ with gr.Blocks() as demo:
|
|
| 227 |
mp3_file_input = gr.File(label="Upload background music (.mp3)", file_types=[".mp3"])
|
| 228 |
keyword_input = gr.Textbox(
|
| 229 |
label="Enter keywords separated by commas (e.g., universe, galaxy, forest, cat)",
|
| 230 |
-
value="space, espacio,galaxy,moon,fear,astral,god,
|
| 231 |
)
|
| 232 |
voices = asyncio.run(get_voices())
|
| 233 |
voice_dropdown = gr.Dropdown(choices=list(voices.keys()), label="Select Voice")
|
|
@@ -235,7 +239,7 @@ with gr.Blocks() as demo:
|
|
| 235 |
pitch_slider = gr.Slider(minimum=-20, maximum=20, value=0, label="Pitch Adjustment (Hz)", step=1)
|
| 236 |
|
| 237 |
with gr.Column():
|
| 238 |
-
output_video = gr.Textbox(label="Download Link") #
|
| 239 |
|
| 240 |
btn = gr.Button("Generate Video")
|
| 241 |
btn.click(
|
|
|
|
| 16 |
import random
|
| 17 |
from google_drive_upload import authenticate_google_drive, upload_to_google_drive
|
| 18 |
from io import BytesIO
|
| 19 |
+
from PIL import Image
|
| 20 |
+
import numpy as np
|
| 21 |
|
| 22 |
# Crear el archivo de credenciales de servicio desde los secretos
|
| 23 |
service_account_info = json.loads(os.getenv('GOOGLE_SERVICE_ACCOUNT', '{}'))
|
|
|
|
| 30 |
os.makedirs(output_folder, exist_ok=True)
|
| 31 |
|
| 32 |
# ID de la carpeta de destino en Google Drive
|
| 33 |
+
FOLDER_ID = "12S6adpanAXjf71pKKGRRPqpzbJa5XEh3" # Reemplaza con tu ID real
|
| 34 |
+
|
| 35 |
|
| 36 |
def resize_and_add_background(clip, target_width=1920, target_height=1080, background_url="https://wallpaperaccess.com/full/231401.jpg"):
|
| 37 |
"""
|
| 38 |
Redimensiona el video al tamaño 1080p (16:9) y añade una imagen de fondo descargada desde una URL.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
"""
|
| 40 |
try:
|
| 41 |
w, h = clip.size
|
|
|
|
| 55 |
.resize((target_width, target_height))
|
| 56 |
)
|
| 57 |
else:
|
| 58 |
+
image_data = Image.open(BytesIO(response.content))
|
| 59 |
+
image_array = np.array(image_data)
|
| 60 |
background = (
|
| 61 |
+
ImageClip(image_array)
|
| 62 |
.set_duration(clip.duration)
|
| 63 |
.resize((target_width, target_height))
|
| 64 |
)
|
|
|
|
| 109 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_video:
|
| 110 |
tmp_video.write(video_response.content)
|
| 111 |
clip = VideoFileClip(tmp_video.name)
|
| 112 |
+
processed_clip = resize_and_add_background(clip)
|
| 113 |
video_clips.append(processed_clip)
|
| 114 |
os.unlink(tmp_video.name) # Limpiamos el archivo temporal
|
| 115 |
except Exception as e:
|
|
|
|
| 185 |
final_text = txt_file.decode("utf-8")
|
| 186 |
else:
|
| 187 |
raise ValueError("No text input provided")
|
| 188 |
+
|
| 189 |
# Generamos el audio
|
| 190 |
audio_file = asyncio.run(text_to_speech(final_text, selected_voice, rate, pitch))
|
| 191 |
if not audio_file:
|
| 192 |
raise ValueError("Failed to generate audio")
|
| 193 |
+
|
| 194 |
# Generamos el video
|
| 195 |
video_clip = concatenate_pixabay_videos(keywords, num_videos_per_keyword=1)
|
| 196 |
if not video_clip:
|
| 197 |
raise ValueError("Failed to generate video")
|
| 198 |
+
|
| 199 |
# Procesamos la música de fondo si existe
|
| 200 |
music_clip = None
|
| 201 |
if mp3_file is not None:
|
| 202 |
music_clip = adjust_background_music(video_clip.duration, mp3_file.name)
|
| 203 |
+
|
| 204 |
# Combinamos todo
|
| 205 |
final_video_path = combine_audio_video(audio_file, video_clip, music_clip)
|
| 206 |
if not final_video_path:
|
| 207 |
raise ValueError("Failed to combine audio and video")
|
| 208 |
+
|
| 209 |
# Subimos a Google Drive
|
| 210 |
video_id = upload_to_google_drive(final_video_path, folder_id=FOLDER_ID)
|
| 211 |
if video_id:
|
| 212 |
print(f"Video subido a Google Drive con ID: {video_id}")
|
| 213 |
+
download_link = f"https://drive.google.com/file/d/{video_id}/view?usp=sharing"
|
| 214 |
+
return download_link # Devuelve el enlace compartido
|
| 215 |
else:
|
| 216 |
print("Error subiendo el video a Google Drive")
|
| 217 |
+
return "Error al subir el video"
|
| 218 |
+
|
| 219 |
except Exception as e:
|
| 220 |
print(f"Error durante el procesamiento: {e}")
|
| 221 |
+
return f"Error durante el procesamiento: {e}"
|
| 222 |
|
| 223 |
|
| 224 |
# Interfaz Gradio
|
|
|
|
| 231 |
mp3_file_input = gr.File(label="Upload background music (.mp3)", file_types=[".mp3"])
|
| 232 |
keyword_input = gr.Textbox(
|
| 233 |
label="Enter keywords separated by commas (e.g., universe, galaxy, forest, cat)",
|
| 234 |
+
value="space, espacio,galaxy,moon,fear,astral,god,evil,mistery,cosmos,stars"
|
| 235 |
)
|
| 236 |
voices = asyncio.run(get_voices())
|
| 237 |
voice_dropdown = gr.Dropdown(choices=list(voices.keys()), label="Select Voice")
|
|
|
|
| 239 |
pitch_slider = gr.Slider(minimum=-20, maximum=20, value=0, label="Pitch Adjustment (Hz)", step=1)
|
| 240 |
|
| 241 |
with gr.Column():
|
| 242 |
+
output_video = gr.Textbox(label="Download Link") # Mostramos el enlace de descarga
|
| 243 |
|
| 244 |
btn = gr.Button("Generate Video")
|
| 245 |
btn.click(
|