🎉 ¡Actualización! Ahora tu descargador de YouTube en Python también baja subtítulos

 

🎉 ¡Actualización! Ahora tu descargador de YouTube en Python también baja subtítulos

¿Ya creaste tu app para descargar videos de YouTube con interfaz gráfica y arte ASCII? ¡Excelente! Ahora te traigo una mejora súper útil: descargar automáticamente los subtítulos si están disponibles. Aquí te explico qué cambió y cómo funciona.


🆕 ¿Qué incluye esta actualización?

  • ✅ Detecta si hay subtítulos disponibles (en español o inglés).
  • ✅ Los descarga en formato .srt.
  • ✅ Guarda los subtítulos en la misma carpeta que el video.
  • ✅ Notifica al usuario si no hay subtítulos disponibles.

🔧 ¿Cómo funciona?

Cuando pegas la URL del video y haces clic en “Descargar video”, la app ahora:

  1. Descarga el video como antes.
  2. Revisa si el video tiene subtítulos en español (es) o inglés (en).
  3. Si encuentra alguno, los convierte a .srt y los guarda.
  4. Muestra una notificación confirmando ambos archivos (video y subtítulos), o indica que no se encontraron subtítulos.

💡 Detalles técnicos

  • Usa la biblioteca pytubefix para extraer subtítulos.
  • Detecta tanto subtítulos manuales como automáticos (a.en).
  • El archivo de subtítulos se nombra con el título del video, con extensión .srt.

🐍 ¿Necesito actualizar algo?

Sí. Asegúrate de tener la versión más reciente de pytubefix. Puedes instalarla o actualizarla con este comando:

pip install -U pytubefix

📷 Vista general de la app

La app conserva su diseño clásico en consola con una ventana gráfica simple, amigable, y un toque especial con arte ASCII. Ahora además te avisa si los subtítulos están disponibles:

Estado: Video descargado. Subtítulos encontrados y guardados.

O, si no hay subtítulos:

Estado: Video descargado. No se encontraron subtítulos.

🧪 Código completo del programa actualizado


import tkinter as tk
from tkinter import ttk, messagebox, filedialog
from pytubefix import YouTube
import threading
import os

def descargar_video():
    url = entrada_url.get()
    carpeta = ruta_descarga.get()

    if not url:
        messagebox.showwarning("Advertencia", "Por favor, ingresa una URL de YouTube.")
        return

    try:
        boton_descargar.config(state=tk.DISABLED)
        estado.set("Descargando video...")

        yt = YouTube(url)
        video = yt.streams.filter(progressive=True, file_extension='mp4').order_by('resolution').desc().first()

        if not video:
            raise Exception("No se encontró un stream compatible.")

        video_path = video.download(output_path=carpeta)
        estado.set("Video descargado. Buscando subtítulos...")

        # Descargar subtítulos si existen
        captions = yt.captions
        caption = None

        if 'es' in captions:
            caption = captions['es']
        elif 'a.en' in captions:
            caption = captions['a.en']
        elif 'en' in captions:
            caption = captions['en']

        if caption:
            srt = caption.generate_srt_captions()
            titulo_archivo = yt.title.replace(" ", "_").replace("/", "_") + ".srt"
            ruta_srt = os.path.join(carpeta, titulo_archivo)
            with open(ruta_srt, "w", encoding="utf-8") as f:
                f.write(srt)
            estado.set("Video y subtítulos descargados.")
            messagebox.showinfo("Completado", f"Video y subtítulos guardados:\n{video_path}\n{ruta_srt}")
        else:
            estado.set("Video descargado. No se encontraron subtítulos.")
            messagebox.showinfo("Completado", f"Video descargado:\n{video_path}\n(No se encontraron subtítulos)")

    except Exception as e:
        estado.set("Error en la descarga.")
        messagebox.showerror("Error", str(e))
    finally:
        boton_descargar.config(state=tk.NORMAL)

def elegir_carpeta():
    carpeta = filedialog.askdirectory()
    if carpeta:
        ruta_descarga.set(carpeta)

def iniciar_descarga():
    hilo = threading.Thread(target=descargar_video)
    hilo.start()

# Crear ventana
ventana = tk.Tk()
ventana.title("Descargador de YouTube con Subtítulos")
ventana.geometry("600x460")
ventana.resizable(False, False)
ventana.configure(bg="#ffffff")

# Variables
ruta_descarga = tk.StringVar()
estado = tk.StringVar(value="Esperando URL...")

# Arte ASCII
ascii_art = r"""
 __     __     ______     __         ______     __   __    
/\ \  _ \ \   /\  __ \   /\ \       /\  ___\   /\ "-.\ \   
\ \ \/ ".\ \  \ \ \/\ \  \ \ \____  \ \  __\   \ \ \-.  \  
 \ \__/".~\_\  \ \_____\  \ \_____\  \ \_____\  \ \_\\"\_\ 
  \/_/   \/_/   \/_____/   \/_____/   \/_____/   \/_/ \/_/ 
"""
etiqueta_ascii = tk.Label(
    ventana,
    text=ascii_art,
    font=("Courier", 10),
    bg="#ffffff",
    fg="#cc0000",
    justify="left"
)
etiqueta_ascii.pack(pady=(5, 0))

# Estilo
estilo = ttk.Style()
estilo.theme_use("clam")
estilo.configure("TButton", font=("Segoe UI", 10), padding=6)
estilo.configure("TLabel", font=("Segoe UI", 10), background="#ffffff")
estilo.configure("TEntry", font=("Segoe UI", 10))

# Widgets
ttk.Label(ventana, text="URL del video de YouTube:").pack(pady=10)
entrada_url = ttk.Entry(ventana, width=60)
entrada_url.pack(pady=5)

frame_carpeta = ttk.Frame(ventana)
frame_carpeta.pack(pady=10)

ttk.Entry(frame_carpeta, textvariable=ruta_descarga, width=45).pack(side=tk.LEFT, padx=(0, 10))
ttk.Button(frame_carpeta, text="Elegir carpeta", command=elegir_carpeta).pack(side=tk.LEFT)

boton_descargar = ttk.Button(ventana, text="Descargar Video", command=iniciar_descarga)
boton_descargar.pack(pady=15)

ttk.Label(ventana, textvariable=estado, foreground="blue").pack(pady=5)

ventana.mainloop()

🚀 ¿Qué sigue?

Próximas mejoras que puedes añadir:

  • Selección manual de idioma de subtítulos.
  • Conversión automática a .txt.
  • Compatibilidad con listas de reproducción.

¿Te gustaría que te ayude con alguna de estas mejoras? ¡Déjamelo saber en los comentarios!

Comentarios

Entradas populares