Cómo Automatizar la Clonación de Vídeos en YouTube con Python

Si necesitas mover contenido entre canales o crear un respaldo de seguridad de tus vídeos, hacerlo a mano es una pérdida de tiempo. En este artículo, vamos a ver cómo crear un script en Python que automatiza la descarga de un vídeo, extrae sus etiquetas originales, descarga la miniatura y lo sube a tu nuevo canal de forma privada.


🛠️ Requisitos previos

Para que este script funcione en tu ordenador (Windows), necesitas tres cosas:

  1. Python 3.x instalado: Descárgalo desde la web oficial.

  2. FFmpeg: Es la herramienta que permite a Python «unir» el audio y el vídeo que descarga. Debes descargarlo y añadirlo al PATH de Windows.

  3. Librerías de Python: Abre una terminal (CMD) y ejecuta este comando para instalar las herramientas necesarias:

    Bash
     
    pip install google-api-python-client google-auth-oauthlib google-auth-httplib2 yt-dlp requests
    

🔑 Paso 1: Configurar la API de Google Cloud

Antes de correr el código, necesitas «permiso» de Google para subir vídeos:

  1. Ve a Google Cloud Console.

  2. Crea un proyecto nuevo y activa la YouTube Data API v3.

  3. En la sección de Pantalla de consentimiento de OAuth, elige «Externo» y añade tu correo en «Usuarios de prueba».

  4. Crea una Credencial de ID de cliente de OAuth (tipo «Aplicación de escritorio»).

  5. Descarga el archivo JSON, cámbiale el nombre a client_secrets.json y guárdalo en la misma carpeta donde estará tu script.


📝 Paso 2: El Script de Automatización

Este es el código final. Su funcionamiento es sencillo: lee una lista de URLs desde un archivo de texto, procesa el vídeo y lo sube como Privado a tu canal.

Python
 
import os
import pickle
import time
import requests
import yt_dlp
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload

# --- CONFIGURACIÓN ---
# Permisos necesarios para subir vídeos y gestionar miniaturas
SCOPES = ["https://www.googleapis.com/auth/youtube.upload", "https://www.googleapis.com/auth/youtube"]
LOG_FILE = "subidos.log"

def get_authenticated_service():
    creds = None
    if os.path.exists("token.pickle"):
        with open("token.pickle", "rb") as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file("client_secrets.json", SCOPES)
            creds = flow.run_local_server(port=0)
        with open("token.pickle", "wb") as token:
            pickle.dump(creds, token)
    return build("youtube", "v3", credentials=creds)

def ya_subido(video_id):
    if not os.path.exists(LOG_FILE): return False
    with open(LOG_FILE, "r") as f:
        return video_id in f.read()

def registrar_subida(video_id):
    with open(LOG_FILE, "a") as f:
        f.write(f"{video_id}\n")

def subir_miniatura(youtube, video_id_nuevo, url_miniatura):
    print(f"🖼️ Descargando y subiendo miniatura...")
    img_data = requests.get(url_miniatura).content
    with open("temp_thumb.jpg", "wb") as handler:
        handler.write(img_data)
    
    youtube.thumbnails().set(
        videoId=video_id_nuevo,
        media_body=MediaFileUpload("temp_thumb.jpg")
    ).execute()
    
    os.remove("temp_thumb.jpg")

def procesar_video(youtube, url):
    ydl_opts = {
        'format': 'bestvideo+bestaudio/best',
        'outtmpl': 'temp_%(id)s.%(ext)s',
        'quiet': True,
        'no_warnings': True,
    }
    
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=True)
        video_id_original = info['id']
        
        if ya_subido(video_id_original):
            print(f"⏭️ El video {video_id_original} ya fue clonado. Saltando...")
            filename = ydl.prepare_filename(info)
            if os.path.exists(filename): os.remove(filename)
            return

        filename = ydl.prepare_filename(info)
        print(f"✅ Descargado: {info['title']}")

        # Extraer metadatos originales
        etiquetas = info.get('tags', [])
        descripcion_original = info.get('description', '')
        url_miniatura = info.get('thumbnail')

        request_body = {
            'snippet': {
                'title': info['title'],
                'description': descripcion_original,
                'tags': etiquetas,
                'categoryId': '22'
            },
            'status': {'privacyStatus': 'private'}
        }

        media = MediaFileUpload(filename, chunksize=-1, resumable=True)
        upload_req = youtube.videos().insert(part="snippet,status", body=request_body, media_body=media)
        
        print(f"⬆️ Subiendo video...")
        response = upload_req.execute()
        video_id_nuevo = response['id']
        
        if url_miniatura:
            try:
                subir_miniatura(youtube, video_id_nuevo, url_miniatura)
            except Exception as e:
                print(f"⚠️ No se pudo subir la miniatura: {e}")

        print("⏳ Limpiando archivos temporales...")
        del upload_req
        del media
        time.sleep(2)

        try:
            os.remove(filename)
            registrar_subida(video_id_original)
            print(f"🎉 ¡Éxito! Clonado completo: https://youtu.be/{video_id_nuevo}")
        except Exception as e:
            print(f"⚠️ Error al borrar temporal: {e}")
            registrar_subida(video_id_original)

if __name__ == "__main__":
    youtube = get_authenticated_service()
    if os.path.exists("videos.txt"):
        with open("videos.txt", "r") as f:
            urls = [line.strip() for line in f.readlines() if line.strip()]
        for url in urls:
            try:
                procesar_video(youtube, url)
            except Exception as e:
                print(f"❌ Error con {url}: {e}")

📖 Paso 3: Cómo usarlo

  1. Archivo de texto: Crea un archivo llamado videos.txt en la misma carpeta. Pega allí las URLs de los vídeos de YouTube (una por línea).

  2. Primera ejecución: Al ejecutar el script por primera vez, se abrirá tu navegador. Debes elegir la cuenta de Google de tu canal y aceptar todos los permisos.

  3. Memoria: El script genera un archivo subidos.log. Esto sirve para que, si vuelves a ejecutar el script, no suba los mismos vídeos dos veces.


⚠️ Notas importantes

  • Límites de Cuota: Google te permite subir aproximadamente 6 vídeos al día con una cuenta gratuita de la API. Si intentas subir más, recibirás un error de «Cuota excedida».

  • Copyright: Ten cuidado con el contenido que clonas. YouTube detecta contenido duplicado y podrías recibir avisos de derechos de autor si no eres el dueño del material.

  • Privacidad: Por defecto, el script sube los vídeos como Privados. Puedes cambiarlos a «Public» o «Unlisted» en el código si lo prefieres.

¡Espero que este tutorial te sea útil para automatizar la gestión de tu contenido! Si tienes dudas con la configuración de la consola de Google Cloud, déjamelo en los comentarios.


Categories:

Tags:


Comments

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies