Descargar vídeos de YouTube con Python puede ser útil para crear una copia de seguridad de tus propias publicaciones, archivar material con licencia compatible o procesar vídeos para los que tienes autorización explícita. La misma técnica también puede utilizarse incorrectamente, por lo que este tutorial se limita a contenido propio, de dominio público, con licencia que permita la descarga o acompañado de un permiso claro del titular.
Antes de empezar, revisa cómo instalar bibliotecas con pip, crear entornos virtuales con venv, gestionar variables de entorno, utilizar pathlib para rutas y aplicar manejo de excepciones.
Las referencias externas principales son los Términos de Servicio de YouTube, la ayuda oficial para descargar vídeos que tú mismo has subido y el repositorio oficial de yt-dlp.
Comprueba primero si necesitas un script
YouTube permite descargar desde YouTube Studio determinados vídeos que has subido. Para copias completas de una cuenta, también puede existir una opción oficial de exportación. Estas vías son preferibles porque no dependen de cambios en la página ni requieren mantener código.
Usa Python cuando tengas un flujo autorizado que necesite automatización, por ejemplo archivar periódicamente tus propios vídeos públicos, descargar material interno con permiso o preparar archivos para una transcripción local.
Qué no cubre esta guía
No se explica cómo descargar vídeos privados ajenos, evitar autenticación, eludir DRM, capturar contenido de pago, romper restricciones regionales o ignorar una prohibición del titular. Tampoco se deben reutilizar audio, imágenes o vídeos sin respetar derechos de autor, licencias y condiciones de la plataforma.
Crear el entorno
mkdir respaldo_youtube
cd respaldo_youtube
python -m venv .venv
Activa el entorno. En Windows:
.venv\Scripts\activate
En macOS o Linux:
source .venv/bin/activate
Instala yt-dlp:
python -m pip install -U yt-dlp
El proyecto se actualiza con frecuencia debido a cambios en los sitios compatibles. Utiliza una versión actual, pero prueba las actualizaciones antes de aplicarlas a una automatización importante.
Probar primero desde la terminal
Utiliza únicamente la URL de un vídeo que te pertenece o para el que tienes autorización:
yt-dlp "URL_AUTORIZADA"
Para ver formatos disponibles sin descargar:
yt-dlp -F "URL_AUTORIZADA"
No elijas una calidad mayor de la necesaria. Los archivos grandes consumen almacenamiento, ancho de banda y tiempo.
Usar yt-dlp desde Python
from pathlib import Path
from yt_dlp import YoutubeDL
DESTINO = Path("videos_autorizados")
DESTINO.mkdir(exist_ok=True)
def descargar_video(url: str) -> None:
url = url.strip()
if not url.startswith("https://"):
raise ValueError("La URL debe usar HTTPS")
opciones = {
"outtmpl": str(DESTINO / "%(title)s [%(id)s].%(ext)s"),
"format": "bv*+ba/b",
"noplaylist": True,
"restrictfilenames": True,
}
with YoutubeDL(opciones) as ydl:
ydl.download([url])
noplaylist evita descargar accidentalmente una lista completa. restrictfilenames reduce caracteres problemáticos en los nombres. El selector de formato solicita vídeo y audio cuando están disponibles y utiliza una alternativa combinada.
FFmpeg y combinación de formatos
En calidades altas, YouTube puede entregar vídeo y audio por separado. yt-dlp utiliza FFmpeg para combinarlos cuando está instalado. Descarga FFmpeg desde una fuente oficial o mediante el gestor de paquetes de tu sistema y confirma:
ffmpeg -version
No incluyas ejecutables desconocidos encontrados en sitios de terceros dentro de tu proyecto.
Elegir una carpeta segura
from pathlib import Path
BASE = Path.home() / "Videos" / "RespaldoYouTube"
BASE.mkdir(parents=True, exist_ok=True)
No construyas rutas directamente a partir de entrada no confiable. El título de un vídeo puede contener caracteres especiales; por eso es importante utilizar plantillas y restricciones de nombre.
Obtener información sin descargar
from yt_dlp import YoutubeDL
def obtener_info(url):
opciones = {
"quiet": True,
"skip_download": True,
"noplaylist": True,
}
with YoutubeDL(opciones) as ydl:
info = ydl.extract_info(url, download=False)
return {
"id": info.get("id"),
"titulo": info.get("title"),
"duracion": info.get("duration"),
"canal": info.get("channel"),
}
Antes de descargar, muestra estos datos y pide confirmación. Esto reduce el riesgo de usar una URL equivocada.
Confirmación explícita
info = obtener_info("URL_AUTORIZADA")
print(info)
confirmacion = input(
"Confirmo que tengo derecho a descargar este vídeo [s/N]: "
).strip().lower()
if confirmacion == "s":
descargar_video("URL_AUTORIZADA")
else:
print("Operación cancelada")
Una confirmación no crea derechos legales, pero obliga a detenerse y revisar el origen antes de continuar.
Evitar descargas duplicadas
yt-dlp admite un archivo de historial para registrar identificadores descargados:
opciones = {
"outtmpl": str(DESTINO / "%(title)s [%(id)s].%(ext)s"),
"download_archive": "videos_descargados.txt",
"noplaylist": True,
"restrictfilenames": True,
}
Este archivo evita repetir vídeos en ejecuciones posteriores. Guárdalo junto al proyecto o en una ruta persistente y crea una copia de seguridad.
Descargar una lista autorizada
En lugar de aceptar cualquier playlist, conserva un archivo de URLs revisadas:
from pathlib import Path
RUTA_URLS = Path("urls_autorizadas.txt")
urls = [
linea.strip()
for linea in RUTA_URLS.read_text(encoding="utf-8").splitlines()
if linea.strip() and not linea.startswith("#")
]
for url in urls:
descargar_video(url)
Añade junto a cada URL una nota interna sobre propiedad, licencia o permiso. No automatices búsquedas para descargar resultados masivamente.
Manejar errores
import logging
from yt_dlp.utils import DownloadError
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s",
)
try:
descargar_video("URL_AUTORIZADA")
except ValueError as error:
logging.error("URL inválida: %s", error)
except DownloadError:
logging.exception("No fue posible descargar el vídeo")
except OSError:
logging.exception("Error de almacenamiento o permisos")
No registres cookies, cabeceras de autenticación o información privada. Si una descarga falla porque el vídeo no está disponible para ti, no intentes eludir la restricción.
Limitar velocidad y cantidad
Una copia de seguridad no debería saturar la conexión. Puedes definir un límite:
opciones = {
"ratelimit": 2_000_000,
"max_downloads": 5,
"noplaylist": True,
"download_archive": "videos_descargados.txt",
}
Los valores son ejemplos. Ajusta la velocidad a tu red y evita lanzar varios procesos paralelos sin necesidad.
Seleccionar una resolución
opciones = {
"format": "bv*[height<=1080]+ba/b[height<=1080]",
"merge_output_format": "mp4",
"noplaylist": True,
}
El límite de 1080p puede ser suficiente para una copia de trabajo. La combinación disponible depende del vídeo y de FFmpeg.
Subtítulos de contenido autorizado
Para tus propios vídeos o contenido con permiso, puedes conservar subtítulos disponibles:
opciones = {
"writesubtitles": True,
"writeautomaticsub": False,
"subtitleslangs": ["es", "en"],
"skip_download": True,
"noplaylist": True,
}
Los subtítulos también pueden estar protegidos por derechos de autor. No los redistribuyas sin autorización.
Cookies y vídeos privados
La herramienta admite métodos de autenticación, pero esta guía no enseña a importar cookies ni acceder a vídeos privados. Usa YouTube Studio o las opciones oficiales de exportación para tu propio contenido privado. Copiar cookies aumenta el riesgo de comprometer la cuenta.
Crear un modo simulación
def revisar_sin_descargar(url):
with YoutubeDL({
"skip_download": True,
"quiet": True,
"noplaylist": True,
}) as ydl:
return ydl.extract_info(url, download=False)
Ejecuta primero el modo de revisión para confirmar título, canal, duración y disponibilidad.
Verificar los archivos
import hashlib
def sha256_archivo(ruta):
hash_obj = hashlib.sha256()
with open(ruta, "rb") as archivo:
for bloque in iter(lambda: archivo.read(1024 * 1024), b""):
hash_obj.update(bloque)
return hash_obj.hexdigest()
Guardar hashes ayuda a comprobar que una copia no cambió durante una transferencia. Mantén también metadatos sobre fecha, licencia y origen.
Organización del proyecto
respaldo_youtube/
├── app.py
├── urls_autorizadas.txt
├── videos_descargados.txt
├── requisitos.txt
└── videos_autorizados/
El archivo de URLs no debería contener enlaces privados o datos sensibles si el repositorio es público.
Errores frecuentes
Los problemas habituales son descargar sin comprobar derechos, aceptar playlists por accidente, guardar todo en la carpeta actual, ignorar el espacio disponible, utilizar una versión antigua de la herramienta y no instalar FFmpeg. También es un error introducir cookies o credenciales en scripts compartidos.
Alternativas oficiales
Para tus propias publicaciones, empieza por YouTube Studio y las herramientas de exportación de la cuenta. Para ver contenido sin conexión como usuario, utiliza las funciones ofrecidas por YouTube en tu región y plan. Un script no debe utilizarse para sustituir ni eludir esas opciones.
Conclusión
Python y yt-dlp pueden automatizar copias de seguridad de vídeos propios o autorizados, pero la responsabilidad comienza antes del código. Comprueba la licencia, utiliza primero las herramientas oficiales, evita contenido privado o protegido y limita cada ejecución. En el programa, valida URLs, desactiva playlists por defecto, conserva un historial, maneja errores y organiza los archivos. Así podrás crear un flujo de respaldo útil sin convertirlo en una herramienta para infringir derechos o restricciones.






