Automatizando la conversión de video a 720p con find, ffprobe y HandBrake

Written by

in

Script para reducir automáticamente la resolución de una biblioteca de video de 1080p (o superior) a 720p, aprovechando la aceleración por hardware de una GPU AMD para acelerar la codificación — útil para liberar espacio en disco en una biblioteca personal grande sin monopolizar la CPU durante horas.

El script completo

#!/bin/bash

CARPETA_DESTINO="./Pelis_720p"

# 1. Crear la carpeta de destino si no existe
mkdir -p "$CARPETA_DESTINO"

echo "=========================================================================="
# 2. Buscar videos >= 1080p y procesarlos uno a uno
find . -type f \( -name "*.mp4" -o -name "*.mkv" -o -name "*.avi" \) -exec sh -c '
    for f; do
        # Obtener el ancho del video de forma rápida
        w=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=nw=1:nk=1 "$f")

        # Filtrar solo si es igual o mayor a 1920px (1080p o superior)
        if [ "$w" -ge 1920 ] 2>/dev/null; then
            base=$(basename "$f" | sed "s/\.[^.]*$//")
            ext="${f##*.}"
            out="./Pelis_720p/${base}_converted.${ext}"

            # Si el archivo ya existe en el destino, saltarlo (protección anti-interrupciones)
            if [ -f "$out" ]; then
                echo "Saltando (ya existe): $base"
                continue
            fi

            echo "------------------------------------------------------------------"
            echo "Procesando: $f ($w px)"
            echo "------------------------------------------------------------------"

            # Ejecución optimizada con HandBrakeCLI + GPU AMD + baja prioridad de CPU
            nice -n 19 HandBrakeCLI --encoder-encoder-fallback \
                -e vce_h264 \
                -q 22 \
                -w 1280 -l 720 \
                --audio-lang-list any \
                --aencoder copy \
                -i "$f" \
                -o "$out"
        fi
    done
' _ {} +

echo "=========================================================================="
echo "Proceso finalizado. Revisa la carpeta '$CARPETA_DESTINO'."
echo "=========================================================================="

Cómo funciona cada parte

find + exec: procesar archivos en lote de forma segura

find . -type f \( -name "*.mp4" -o ... \) -exec sh -c '...' _ {} + busca recursivamente todos los archivos de video con esas extensiones, y en vez de ejecutar el comando una vez por archivo (lo cual sería lento con bibliotecas grandes), usa -exec ... + para agrupar múltiples archivos en menos invocaciones del subshell. El sh -c '...' _ {} + es el patrón estándar para pasar una lista de archivos a un script embebido dentro de find, donde _ ocupa el lugar de $0 (el nombre del script, no usado aquí) y {} se expande a la lista real de archivos encontrados.

ffprobe: detectar la resolución sin decodificar el video completo

ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=nw=1:nk=1 "$f"

ffprobe (parte del proyecto ffmpeg) lee únicamente los metadatos del contenedor de video, sin decodificar los fotogramas — esto lo hace extremadamente rápido incluso en archivos grandes. -select_streams v:0 apunta específicamente al primer stream de video (ignorando pistas de audio o subtítulos embebidos), -show_entries stream=width pide solo el ancho en píxeles, y -of default=nw=1:nk=1 formatea la salida como un valor plano, sin encabezados ni etiquetas — listo para asignarse directamente a una variable de Bash.

Filtrar solo videos de 1080p o superior

La condición [ "$w" -ge 1920 ] compara el ancho detectado contra 1920 píxeles (el ancho estándar de 1080p) — cualquier video ya en 720p o menor se salta automáticamente, evitando procesar (y perder calidad innecesariamente) contenido que ya está en una resolución igual o menor a la deseada.

Protección contra interrupciones

La verificación if [ -f "$out" ]; then ... continue; fi es clave para bibliotecas grandes que pueden tardar horas en procesarse: si el script se interrumpe (por un corte de energía, un cierre accidental de la terminal) y se vuelve a ejecutar, salta automáticamente los archivos que ya fueron convertidos exitosamente, retomando el trabajo donde quedó sin reprocesar nada innecesariamente.

HandBrakeCLI: los parámetros de codificación

ParámetroFunción
-e vce_h264Usa el encoder por hardware VCE (Video Coding Engine) de AMD para H.264, en vez del encoder por software (x264) — mucho más rápido, a costa de una eficiencia de compresión ligeramente menor
-q 22Factor de calidad constante (menor número = mayor calidad y mayor tamaño de archivo). 22 es un valor moderado, buen balance para HD
-w 1280 -l 720Fuerza el ancho y alto de salida a 720p exacto
--audio-lang-list anyIncluye todas las pistas de audio disponibles, sin filtrar por idioma
--aencoder copyCopia el audio original sin recodificarlo — solo se recomprime el video, preservando la calidad de audio intacta y acelerando el proceso al evitar una recodificación innecesaria

Aceleración por hardware: por qué usar la GPU

Codificar video en H.264 por software (usando la CPU) es una tarea intensiva que puede tardar varias veces la duración real del video, especialmente en equipos sin muchos núcleos. Las GPUs modernas (AMD VCE, Intel Quick Sync, NVIDIA NVENC) tienen bloques de hardware dedicados específicamente para codificación/decodificación de video, capaces de procesar la misma tarea en una fracción del tiempo — el costo es una eficiencia de compresión ligeramente menor a igual calidad percibida, comparado con encoders por software altamente optimizados como x264 en su configuración más lenta.

nice -n 19: prioridad mínima de CPU

nice -n 19 ejecuta el proceso con la prioridad de CPU más baja posible en Linux (el rango va de -20, máxima prioridad, a 19, mínima). Aunque la codificación se hace principalmente en la GPU, el proceso HandBrakeCLI sigue usando CPU para tareas de coordinación, demuxing y manejo de audio — nice -n 19 asegura que esas tareas cedan el paso a cualquier otra aplicación que esté usando el equipo activamente en primer plano, dejando la conversión corriendo en segundo plano sin afectar la experiencia de uso normal de la máquina.

Notas

  • El script mantiene el archivo original intacto — el resultado se guarda en ./Pelis_720p/ con el sufijo _converted, por lo que la limpieza de los originales (si se desea liberar espacio) debe hacerse manualmente después de verificar la calidad del resultado.
  • --encoder-encoder-fallback permite que HandBrake recurra al encoder por software si la GPU no está disponible o falla, evitando que el script se detenga por completo ante un problema puntual con el driver de video.
  • Este enfoque es ideal para bibliotecas grandes de video donde se prioriza velocidad de conversión y ahorro de espacio en disco por encima de exprimir al máximo la eficiencia de compresión.