FFmpeg es la navaja suiza del vídeo: puede convertir, cortar, comprimir, poner efectos, extraer audio… Pero su sintaxis es brutal. Un solo comando puede tener 30 parámetros y si te equivocas en uno, el vídeo sale corrupto o pesadísimo.
midu.sh es un wrapper que simplifica todo: 33 modos de operación donde solo tienes que decirle “cortame esto de aquí a aquí” y él se encarga del resto. Pero para que funcione, necesitas instalarlo correctamente. Aquí te explico cómo, por qué cada paso importa, y dónde configurar cada cosa.
1. Por qué FFmpeg + yt-dlp (y no otra cosa)
| Herramienta | Qué hace | Por qué esta y no otra |
|---|---|---|
| FFmpeg | Convertir, cortar, comprimir, editar vídeos | Estándar de facto, soporta todo codec, gratuito, potente. No hay alternativa real comparable |
| yt-dlp | Descargar de YouTube y 1000+ sitios | Fork de youtube-dl activo, más rápido, más sitios soportados, mejor mantenido |
| midu.sh | Wrapper de ambos con 33 modos | Simplifica la sintaxis de ffmpeg, añade presets para redes sociales, auto-detección de GPU |
¿Por qué no Handbrake? Handbrake es GUI y no se automatiza. No puedes ponerlo en un pipeline Docker. ¿Por qué no otras? Ninguna otra herramienta combina descarga + conversión + edición + automatización en un solo script.
2. Requisitos previos
| Requisito | Para qué | Cómo obtenerlo |
|---|---|---|
| Docker (recomendado) | Ejecutar todo sin instalar nada en el sistema | docker.com/products/docker-desktop |
| FFmpeg (sin Docker) | Motor de conversión de vídeo | sudo apt install ffmpeg (Ubuntu/Debian) |
| yt-dlp (sin Docker) | Descarga de videos | pip install yt-dlp |
| Python 3 (sin Docker) | Para scripts auxiliares | sudo apt install python3 |
3. Instalación con Docker (recomendado)
La forma más fácil. Docker trae todo preinstalado: ffmpeg, yt-dlp, bash, python3.
# 1. Clonar el repo
git clone https://github.com/jorbencas/devjobs.git
cd devjobs/ffmpeg-yt-dlp
# 2. Construir la imagen
docker compose build
# 3. Ejecutar (menú interactivo)
docker compose up
¿Qué hace docker compose build? Descarga una imagen base Alpine Linux y le instala ffmpeg, yt-dlp, bash y python3. Tarda ~2 minutos la primera vez.
¿Qué hace docker compose up? Arranca el contenedor downloader con el menú interactivo de midu.sh. Puedes seleccionar entre los 33 modos.
Verificar que funciona
# Comprobar que ffmpeg está instalado
docker compose run --rm downloader ffmpeg -version
# Salida esperada: ffmpeg version 6.x.x ...
# Comprobar que yt-dlp funciona
docker compose run --rm downloader yt-dlp --version
# Salida esperada: 2024.x.x ...
# Probar una descarga
docker compose run --rm downloader ./midu.sh -d "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
# Se descargará el vídeo en test_video/
4. Instalación sin Docker
Si prefieres instalar en tu sistema directamente:
# 1. Instalar dependencias (Ubuntu/Debian)
sudo apt update
sudo apt install ffmpeg python3 python3-pip
# 2. Instalar yt-dlp
pip install yt-dlp
# 3. Ejecutar
cd devjobs/ffmpeg-yt-dlp/test_video
bash midu.sh
¿Por qué no se recomienda? Porque ffmpeg cambia de versión frecuentemente y yt-dlp también. Docker te da una versión fija y reproducible. Sin Docker, si actualizas ffmpeg, algo podría romperse.
5. Configurar el monitor de compresión automática
El monitor es un daemon que vigila una carpeta y comprime automáticamente los vídeos nuevos. Es la pieza central del pipeline “Grabar → Comprimir → Subir a Telegram”.
5.1. Arrancar el monitor
cd ffmpeg-yt-dlp
# Arrancar el monitor en background
docker compose up -d monitor
# Ver logs en tiempo real
docker compose logs -f monitor
# Parar solo el monitor
docker compose stop monitor
5.2. Configurar carpetas
El monitor vigila por defecto data/pipeline/grabaciones/test/ y comprime en data/pipeline/comprimidos/. Estas rutas están configuradas en docker-compose.yml:
environment:
- OUTPUT_DIR=/comprimidos
- POLL_INTERVAL=30 # Cada 30 segundos comprueba si hay vídeos nuevos
- DIRECTO_COMPLETO=true # Procesar directos completos (no dividir)
¿Puedo cambiar las rutas? Sí, edita docker-compose.yml y cambia los volúmenes:
volumes:
- /ruta/que/quieras/vigilar:/grabaciones
- /ruta/de/salida:/comprimidos
¿Qué pasa si la carpeta de entrada no existe? El monitor la crea automáticamente al arrancar.
5.3. Parámetros del monitor
| Parámetro | Default | Descripción | Cuándo cambiarlo |
|---|---|---|---|
-t, --threads N | 4 | Hilos de ffmpeg (parallel encoding) | Si tienes CPU potente (8+ cores), sube a 8 |
--completed-only | off | Solo procesar *_completed.* | Actívalo si quieres que solo comprima directos terminados |
--directo-completo | off | Procesar directos completos | Actívalo si no quieres dividir en partes |
--codec NAME | libx264 | Códec de vídeo | Cámbialo si tu dispositivo soporta NVENC o VAAPI |
-c, --crf VALUE | 28 | Calidad (menor = mejor) | Baja a 23 si quieres más calidad (pero más peso) |
-p, --preset NAME | fast | Velocidad | Cambia a medium si tu PC es potente y quieres mejor calidad |
-r, --resolution N | sin reescalar | Escalar altura a N píxeles | Pon 720 si quieres 720p fijo |
¿Qué es CRF? Es el “Constant Rate Factor”: un valor de 0-51 donde 0 es calidad perfecta y 51 es basura. 28 es un buen balance entre calidad y tamaño. 18 es prácticamente indistinguible del original.
¿Qué es el preset? Controla la velocidad de codificación. ultrafast es rápido pero pesa más. veryslow tarda mucho pero pesa menos. fast es un buen balance.
6. Configurar el Preview Watcher (WSL / Linux nativo)
El watcher abre automáticamente los vídeos en VLC, mpv o xdg-open cuando midu.sh los genera. Funciona tanto en WSL como en Linux nativo.
6.1. Arrancar el watcher
# En una terminal (no en Docker)
cd devjobs/ffmpeg-yt-dlp
bash preview_watcher.sh --daemon
6.2. Verificar que funciona
# Ver estado
bash preview_watcher.sh --status
# Debería decir: "Watcher running (PID: xxxx)"
# Ver logs
bash preview_watcher.sh
# Parar
bash preview_watcher.sh --stop
6.3. Cómo funciona
midu.shescribe la ruta del vídeo entest_video/.midu_preview_req- El watcher detecta el archivo (poling cada 2 segundos)
- Convierte la ruta Linux a Windows (
/mnt/c/...→C:\...) - Abre el vídeo en VLC (o el reproductor por defecto)
- Elimina el archivo de petición
¿Por qué funciona así? Porque Docker en WSL no puede abrir aplicaciones de Windows directamente. El watcher hace de puente entre el contenedor y el sistema host.
¿Qué pasa si no tengo VLC? Instálalo: sudo apt install vlc o descárgalo de videolan.org.
7. Notificaciones (opcional)
Si quieres que te avisen cuando termine una conversión, puedes configurar notificaciones push con ntfy.sh:
# 1. Crear un topic en ntfy.sh (gratis)
# Ve a https://ntfy.sh y elige un nombre de topic (ej: "mi-devjobs")
# No necesitas cuenta, solo elegir un nombre único
# 2. Crear .env en ffmpeg-yt-dlp/
cat > ffmpeg-yt-dlp/.env << EOF
NTFY_URL=https://ntfy.sh/mi-devjobs
EOF
# 3. Instalar la app de ntfy.sh en tu móvil (opcional)
# Disponible en App Store (iOS) y Google Play (Android)
# Suscríbete al mismo topic que configuraste arriba
¿Cómo funciona? Cuando midu.sh termina, envía un POST a ntfy.sh con el resultado. Si tienes la app, recibes una notificación push en el móvil.
8. Uso típico
# 1. Descargar un vídeo de YouTube
docker compose run --rm downloader ./midu.sh -d "https://youtube.com/watch?v=..."
# 2. Cortar (lossless, sin re-encoding — muy rápido)
docker compose run --rm downloader ./midu.sh --cut -ss 00:05:00 -e 00:10:00
# 3. Convertir para Telegram (720p, CRF 28)
docker compose run --rm downloader ./midu.sh --convert -s telegram
# 4. Comprimir para el pipeline
docker compose run --rm downloader ./midu.sh --convert -s telegram -crf 28
9. Cómo funciona el monitor por dentro
El monitor (scripts/monitor_folder.sh) es el eslabón compresor del pipeline “Grabar → Comprimir → Subir”. Vigila grabaciones/test/ cada POLL_INTERVAL (30s) y su flujo completo es:
9.1. El ciclo de compresión paso a paso
LEER grabaciones/test/*_completed.mp4
│
▼
1. INTEGRIDAD: ffprobe → duración
├─ falla o < MIN_DURACION (60s) → mover a .corruptos/
└─ OK → continúa
│
▼
2. SIDECAR: ¿existe <nombre>_descripcion.json al lado?
├─ SÍ con "descripcion" → caption propio, SIN OCR y SIN corte
├─ SÍ con "detectar":false → SIN OCR (ni corte)
├─ SÍ con "corte":false → hace OCR (para caption) pero SIN cortar
└─ NO → sigue al paso 3
│
▼
3. DETECCIÓN DE EPISODIOS (solo si no hay descripcion):
detectar_episodios.py → cada OCR_STEP (180s) extrae la franja superior 20%,
la escala x2, preprocesa (gris+contraste+sharp+treshold) y la pasa por
[tesseract](https://github.com/tesseract-ocr/tesseract) (inglés), buscando patrones:
• "Episodio 3" / "Ep 3" / "cap 3"
• "S02E05" (temporada+episodio)
• "1x03" (formato serie)
• "Película · TÍTULO" (≥2 menciones → extrae el título por frecuencia)
Genera <nombre>_episodios.json
│
▼
4. CORTE DE EXTREMOS: si se detecta la franja de episodios, el vídeo se corta
con margen CORTE_MARGEN (5 min): -ss INICIO -t DURACIÓN
│
▼
5. COMPRESIÓN: libx264, CRF 28, preset fast, AAC 128k, solo 0:v:0 + 0:a:0
(descarta subs/otros streams → más compatibilidad con Telegram)
resolución opcional -r 720 → scale=Hx720 + pad a 16:9
escribe a <salida>.tmp y renombra al terminar (escritura atómica)
│
▼
6. ¿El resultado supera TAMANO_MAX_MB (1900MB)?
├─ NO → listo
└─ SÍ → RE-COMPRIME en 2 pasadas:
paso 1: -pass 1 -an (solo análisis, sin audio)
paso 2: -pass 2 con el bitrate calculado para caber en el límite
(borra ffmpeg2pass-* al terminar)
│
▼
7. POST: renombra a <nombre>_compressed.mp4 → comprimidos/
mueve el original a comprimidos/.processed/
borra el archivo auxiliar *_descripcion.json
avisa al bot vía pipeline_ipc.sh (escribe en pipeline_status.json)
9.2. Los archivos auxiliares: el “contrato” con el grabador
El archivo auxiliar _descripcion.json lo escribe el TwitchRecorder siempre que graba, y el monitor lo respeta al pie de la letra:
| Archivo auxiliar | Efecto en el monitor |
|---|---|
{"titulo": "..."} | Usa el título como caption de Telegram (se guarda siempre) |
{"titulo": "...", "descripcion": "..."} | Usa el título como caption, guarda la descripción completa |
{"detectar": false} | Omite OCR y corte (típico de cutetas sin franjas) |
{"corte": false} | Hace OCR para generar el caption, pero no corta el vídeo |
El archivo auxiliar viaja con el archivo: al concatenar partes, se copia al archivo final, y al mover a test/, va pegado al *_completed.mp4.
9.3. Dónde deja las cosas y quién las consume
grabaciones/test/*_completed.mp4 → MONITOR (entrada)
comprimidos/*_compressed.mp4 → UPLOADER de Telegram (lo sube y borra)
comprimidos/*_episodios.json → UPLOADER (caption con "Episodio 1-4")
comprimidos/.processed/ → originales ya comprimidos (el uploader limpia)
comprimidos/log_YYYY-MM-DD.txt → log diario del monitor
10. Estructura de archivos
ffmpeg-yt-dlp/
├── docker-compose.yml # Servicios: downloader + monitor
├── .env # Configuración (ntfy.sh, opcional)
├── preview_watcher.sh # Abre vídeos en VLC/mpv (WSL + Linux nativo)
├── scripts/
│ ├── backup_youtube.sh # Backup de canales de YouTube
│ └── monitor_folder.sh # Monitor de compresión (usado por Docker)
└── test_video/
├── midu.sh # Script principal (~6000 líneas, 33 modos)
├── optimizados/ # Vídeos convertidos
└── test/ # Vídeos de entrada
Troubleshooting
| Problema | Causa | Solución |
|---|---|---|
ffmpeg: not found | No está instalado (sin Docker) | sudo apt install ffmpeg |
yt-dlp: not found | No está instalado (sin Docker) | pip install yt-dlp |
Permission denied | Falta permiso de ejecución | chmod +x midu.sh |
VLC no abre | Watcher no está corriendo | Ejecutar bash preview_watcher.sh --daemon en otra terminal |
Monitor no vigila | Monitor no está arrancado | docker compose up -d monitor |
Vídeo muy pesado | CRF muy bajo | Subir CRF a 28 o 32 |
Conversión muy lenta | Usando CPU en lugar de GPU | Instalar NVIDIA drivers o usar --hw-accel |
¿Quieres ver cómo funciona el pipeline completo? Consulta los posts de los proyectos que usan este compresor:
- Instalación del Ecosistema Devjobs: Pipeline Completo desde Cero
- FFmpeg + yt-dlp Pipeline: Conversor y Descargador de Vídeo
- Telegram Ultimate Toolbox: Descargador y Uploader con Docker
🪜 Siguiente nivel
Una vez tienes FFmpeg + yt-dlp funcionando, el siguiente paso es integrarlo en un pipeline completo:
- Docker de 0 a 100 — domina el contenedor que acabas de usar para que nada dependa de tu sistema: Guía de Docker: De 0 a 100.
- Más comandos de FFmpeg y yt-dlp — profundiza en descargas, formatos y presets: Guía de comandos de yt-dlp y FFmpeg.
- Automatizar en Bash — scripts para unir, comprimir y procesar en lote: Scripts Bash para unir vídeo y audio con FFmpeg.
- El pipeline completo — desde la grabación hasta subir a Telegram: Instalación del Ecosistema Devjobs.
