Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import requests | |
| import json | |
| import base64 | |
| def descargar_con_api(url, calidad, cookies_txt): | |
| """ | |
| Usa APIs de terceros que funcionan en HF Spaces | |
| """ | |
| try: | |
| # Extraer video ID | |
| import re | |
| video_id_match = re.search(r'(?:v=|\/)([0-9A-Za-z_-]{11})', url) | |
| if not video_id_match: | |
| return None, "❌ URL de YouTube inválida" | |
| video_id = video_id_match.group(1) | |
| # Opción 1: Usar API de invidious (proxy de YouTube open source) | |
| apis_disponibles = [ | |
| f"https://inv.riverside.rocks/api/v1/videos/{video_id}", | |
| f"https://invidious.snopyta.org/api/v1/videos/{video_id}", | |
| f"https://yewtu.be/api/v1/videos/{video_id}", | |
| ] | |
| info_video = None | |
| for api_url in apis_disponibles: | |
| try: | |
| response = requests.get(api_url, timeout=10) | |
| if response.status_code == 200: | |
| info_video = response.json() | |
| break | |
| except: | |
| continue | |
| if not info_video: | |
| return None, "❌ No se pudo conectar a las APIs disponibles" | |
| # Extraer información | |
| titulo = info_video.get('title', 'Sin título') | |
| duracion = info_video.get('lengthSeconds', 0) | |
| # Filtrar formatos | |
| formatos = info_video.get('formatStreams', []) | |
| # Mapeo de calidades | |
| calidad_map = { | |
| "360p": "360p", | |
| "480p": "480p", | |
| "720p": "720p", | |
| "1080p": "1080p" | |
| } | |
| calidad_buscada = calidad_map.get(calidad, "720p") | |
| # Buscar formato | |
| url_descarga = None | |
| formato_encontrado = None | |
| for fmt in formatos: | |
| if fmt.get('qualityLabel') == calidad_buscada or fmt.get('quality') == calidad_buscada: | |
| url_descarga = fmt.get('url') | |
| formato_encontrado = fmt | |
| break | |
| # Si no encuentra la calidad exacta, buscar la más cercana | |
| if not url_descarga and formatos: | |
| formato_encontrado = formatos[0] | |
| url_descarga = formato_encontrado.get('url') | |
| if not url_descarga: | |
| return None, "❌ No se encontró formato disponible" | |
| # Mensaje con información | |
| mensaje = f"✅ Video encontrado!\n\n" | |
| mensaje += f"📺 Título: {titulo}\n" | |
| mensaje += f"⏱️ Duración: {duracion//60}:{duracion%60:02d}\n" | |
| mensaje += f"📊 Calidad: {formato_encontrado.get('qualityLabel', calidad)}\n\n" | |
| mensaje += f"🔗 URL de descarga:\n{url_descarga}\n\n" | |
| mensaje += f"💡 Copia la URL y pégala en tu navegador para descargar" | |
| return url_descarga, mensaje | |
| except Exception as e: | |
| return None, f"❌ Error: {str(e)}" | |
| def generar_enlace_descarga(url, calidad): | |
| """Genera enlaces de descarga usando servicios públicos""" | |
| try: | |
| import re | |
| video_id_match = re.search(r'(?:v=|\/)([0-9A-Za-z_-]{11})', url) | |
| if not video_id_match: | |
| return None, "❌ URL inválida" | |
| video_id = video_id_match.group(1) | |
| # Servicios de descarga públicos | |
| servicios = { | |
| "Y2Mate": f"https://www.y2mate.com/youtube/{video_id}", | |
| "SaveFrom": f"https://en.savefrom.net/1-youtube-video-downloader-{video_id}", | |
| "YTMate": f"https://ytmate.ch/es/youtube-downloader/{video_id}", | |
| } | |
| mensaje = f"🔗 **Enlaces de descarga directa**\n\n" | |
| mensaje += f"📺 Video ID: {video_id}\n" | |
| mensaje += f"📊 Calidad solicitada: {calidad}\n\n" | |
| mensaje += "Usa cualquiera de estos servicios:\n\n" | |
| for nombre, link in servicios.items(): | |
| mensaje += f"🌐 **{nombre}**: {link}\n\n" | |
| mensaje += "\n💡 **Instrucciones:**\n" | |
| mensaje += "1. Haz clic en cualquier enlace de arriba\n" | |
| mensaje += "2. Selecciona la calidad deseada\n" | |
| mensaje += "3. Descarga el video\n\n" | |
| mensaje += "⚠️ Estos servicios funcionan sin necesidad de cookies" | |
| return None, mensaje | |
| except Exception as e: | |
| return None, f"❌ Error: {str(e)}" | |
| # Interfaz de Gradio | |
| with gr.Blocks(title="YouTube Downloader") as demo: | |
| gr.Markdown(""" | |
| # 🎥 Descargador de YouTube | |
| ## ⚠️ Limitación de HuggingFace Spaces | |
| HuggingFace Spaces **bloquea conexiones directas a YouTube** por seguridad. | |
| Esta app te proporciona **enlaces directos** para descargar usando servicios públicos. | |
| ## 🎯 Opciones disponibles: | |
| """) | |
| with gr.Tabs(): | |
| with gr.Tab("🌐 Enlaces Directos (Recomendado)"): | |
| gr.Markdown(""" | |
| ### Genera enlaces a servicios de descarga populares | |
| No requiere cookies ni instalación. | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| url_input1 = gr.Textbox( | |
| label="URL del video", | |
| placeholder="https://www.youtube.com/watch?v=...", | |
| ) | |
| calidad_input1 = gr.Radio( | |
| choices=["360p", "480p", "720p", "1080p"], | |
| value="720p", | |
| label="Calidad preferida" | |
| ) | |
| btn1 = gr.Button("🔗 Generar Enlaces", variant="primary") | |
| with gr.Column(): | |
| output1 = gr.Textbox(label="Enlaces de descarga", lines=15) | |
| btn1.click( | |
| fn=generar_enlace_descarga, | |
| inputs=[url_input1, calidad_input1], | |
| outputs=[gr.File(visible=False), output1] | |
| ) | |
| with gr.Tab("🔄 API Invidious"): | |
| gr.Markdown(""" | |
| ### Usa APIs alternativas de YouTube | |
| Intenta obtener enlaces directos vía Invidious (puede fallar). | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| url_input2 = gr.Textbox( | |
| label="URL del video", | |
| placeholder="https://www.youtube.com/watch?v=...", | |
| ) | |
| calidad_input2 = gr.Radio( | |
| choices=["360p", "480p", "720p", "1080p"], | |
| value="720p", | |
| label="Calidad" | |
| ) | |
| cookies_input2 = gr.File( | |
| label="Cookies (no necesario para videos públicos)", | |
| file_types=[".txt"] | |
| ) | |
| btn2 = gr.Button("🔍 Intentar Descarga", variant="secondary") | |
| with gr.Column(): | |
| output2 = gr.Textbox(label="Resultado", lines=15) | |
| btn2.click( | |
| fn=descargar_con_api, | |
| inputs=[url_input2, calidad_input2, cookies_input2], | |
| outputs=[gr.File(visible=False), output2] | |
| ) | |
| gr.Markdown(""" | |
| --- | |
| ## 💡 Soluciones alternativas para descargas automáticas: | |
| ### Opción A: Ejecutar localmente en tu PC | |
| ```bash | |
| pip install yt-dlp | |
| yt-dlp --cookies cookies.txt "URL_DEL_VIDEO" | |
| ``` | |
| ### Opción B: Usar Google Colab (Gratis) | |
| ```python | |
| !pip install yt-dlp | |
| !yt-dlp --cookies /content/cookies.txt "URL" | |
| ``` | |
| ### Opción C: Desplegar en Railway/Render | |
| Estas plataformas SÍ permiten conexiones a YouTube. | |
| ### Opción D: Extensiones de navegador | |
| - Video DownloadHelper (Firefox/Chrome) | |
| - SaveFrom.net Helper | |
| --- | |
| ## 📝 Nota sobre cookies: | |
| Las cookies solo son necesarias para: | |
| - Videos con restricción de edad (+18) | |
| - Videos privados | |
| - Videos con restricciones regionales | |
| Para videos públicos normales, usa la pestaña **"Enlaces Directos"**. | |
| """) | |
| if __name__ == "__main__": | |
| demo.launch() |