32blogby Studio Mitsu

fqmpeg Estabilización y Limpieza: 8 Verbos de Restauración

Ocho verbos de fqmpeg para estabilización, denoise, deblock, borrado de logo, y detección de fotograma negro/congelado — defaults verificados en código.

by omitsu21 min read
Contenido

El cluster C7 de fqmpeg es la caja de herramientas de limpieza: ocho verbos para arreglar lo que está mal en un clip, en lugar de cambiar cómo se ve. Dos estabilizan material movido (stabilize, deshake). Tres reducen ruido, parpadeo y artefactos de compresión (denoise, deflicker, deblock). Uno borra un logo o marca de agua de una región fija (delogo). Dos son solo análisis: imprimen marcas de tiempo a stderr sin generar archivo (blackdetect, freeze-detect), útiles para encontrar fallos en una captura larga antes de meterla al editor.

Esta guía recorre cada verbo contra su fuente en src/commands/ de fqmpeg 3.0.3: el filtro FFmpeg subyacente, los defaults, el nombre del archivo de salida, y las trampas que --help por sí solo no muestra (stabilize es de 2 pasadas y deja un .trf temporal, denoise --target audio cambia a un filtro completamente distinto, deflicker --size tiene que ser impar, blackdetect y freeze-detect no producen archivo alguno).

Qué te llevas de esta guía

  • Una tabla de decisión para los 8 verbos por tarea (estabilizar / limpiar / quitar / detectar)
  • La invocación FFmpeg exacta que genera cada verbo (verificada con --dry-run)
  • Defaults, rangos y nombres de salida para cada comando
  • Tres recetas de extremo a extremo, incluida la de "rescatar un clip en mano oscuro y movido"

Los 8 Verbos de un Vistazo

El cluster se divide en cuatro grupos de tarea. Elige el grupo, luego el verbo.

GrupoVerbosQué hacen
Estabilizaciónstabilize, deshakeSuavizan el movimiento de cámara — vidstab 2 pasadas (máxima calidad) o deshake 1 pasada (más rápido)
Ruido y artefactosdenoise, deflicker, deblockReducen grano de video o siseo de audio, igualan parpadeo de brillo, quitan bloques de compresión
Quitar objetosdelogoCubre una región rectangular fija (logo, marca de agua, bug) interpolando los píxeles circundantes
Detección (solo análisis)blackdetect, freeze-detectImprimen tiempos de escenas negras o fotogramas congelados — sin archivo de salida, solo stderr

Tres cosas que vale saber antes de seguir:

  1. stabilize es de 2 pasadas y escribe un archivo temporal. Corre primero vidstabdetect (análisis de movimiento) y deposita un .fqmpeg-transforms-<timestamp>.trf junto al input, luego corre vidstabtransform que lee ese archivo. El temporal se borra solo al terminar el proceso — pero si matas con kill -9 a mitad de camino, te queda un .trf huérfano que hay que borrar a mano. deshake es la alternativa de una sola pasada que no necesita archivo temporal.
  2. denoise --target audio es un filtro completamente distinto. El default --target video corre hqdn3d (denoise espacio-temporal de video). --target audio cambia a afftdn (reducción de ruido de audio basada en FFT) con un mapeo distinto de --strength. Mismo verbo, dos filtros, dos significados — no llegues a denoise esperando hqdn3d y descubrir que copiaste --target audio de otra línea.
  3. blackdetect y freeze-detect no producen archivo. Usan -f null - para que FFmpeg procese el input y descarte todo excepto la salida del filtro en stderr (marcas de tiempo y duraciones de los eventos detectados). Pásalo por grep para capturar solo las coincidencias.

Estabilización

stabilize — vidstab 2 pasadas (máxima calidad)

El estabilizador de referencia: analiza el movimiento en la pasada 1, aplica una transformación inversa suavizada en la pasada 2. Más calidad que deshake porque ve el clip entero antes de decidir el suavizado.

  • Fuente: src/commands/stabilize.js
  • Filtro (pasada 1): vidstabdetect=shakiness=N:result=<tmpfile>
  • Filtro (pasada 2): vidstabtransform=smoothing=M:input=<tmpfile>
  • Requiere: FFmpeg construido con --enable-libvidstab
Argumento / OpciónDefaultRangoNotas
<input>requeridoVideo de entrada
--strength <n>10130Fuerza de suavizado en la pasada 2 (mayor = más suave pero recorta más)
--shakiness <n>5110Estimación en la pasada 1 de cuánto se mueve el input
-o, --output <path><nombre>-stabilized.<ext>Sobrescribir salida
bash
$ npx fqmpeg stabilize input.mp4 --strength 10 --shakiness 5 --dry-run

  # Pass 1: Analyze motion
  ffmpeg -i input.mp4 -vf vidstabdetect=shakiness=5:result=transforms.trf -f null -
  # Pass 2: Apply stabilization
  ffmpeg -i input.mp4 -vf vidstabtransform=smoothing=10:input=transforms.trf -c:a copy input-stabilized.mp4

Una corrida real imprime Pass 1/2: Analyzing motion... y luego Pass 2/2: Applying stabilization.... El .trf intermedio se escribe en el mismo directorio del input como .fqmpeg-transforms-<timestamp>.trf y se borra al salir el proceso. Si tu build no incluye --enable-libvidstab, la pasada 1 falla con Unknown filter 'vidstabdetect' — usa un build estático de BtbN's FFmpeg-Builds que incluye vidstab, o cae a deshake.

--strength por encima de 15 suaviza muy agresivamente la trayectoria, lo que implica más recorte en los bordes (el estabilizador necesita holgura para correr el cuadro). Para una toma en mano de un sujeto en movimiento, 10 es el punto dulce; para un clip donde solo se golpeó el trípode, 20+ va bien porque hay menos movimiento que preservar.

deshake — Filtro deshake integrado de una sola pasada

Alternativa más rápida y de menor calidad a stabilize. Usa el filtro deshake integrado en FFmpeg, que trabaja en tiempo real por fotograma (sin pasada de análisis).

Argumento / OpciónDefaultRangoNotas
<input>requeridoVideo de entrada
--rx <n>64064Movimiento horizontal máximo en píxeles que el filtro corrige
--ry <n>64064Movimiento vertical máximo en píxeles
-o, --output <path><nombre>-deshake.<ext>Sobrescribir salida
bash
$ npx fqmpeg deshake input.mp4 --rx 64 --ry 64 --dry-run

  ffmpeg -i input.mp4 -vf deshake=rx=64:ry=64 -c:a copy input-deshake.mp4

El default de 64 píxeles cubre la mayoría del material en mano. Si tu clip tiene vibración pequeña (4K ligeramente movido), baja a --rx 16 --ry 16 para procesar más rápido y recortar menos. Comparado con stabilize: deshake es ~3-5× más rápido pero produce un resultado un poco menos suave, sobre todo en clips largos con movimiento direccional. Úsalo cuando la velocidad de iteración importa más que el pulido final.

Ruido y Artefactos

denoise — Reducción de ruido (video O audio, modo doble)

El verbo se comporta distinto según --target. El default --target video corre el filtro hqdn3d de FFmpeg (denoise espacio-temporal — preserva detalle, quita ruido de luma y croma). --target audio corre afftdn (reducción de ruido base por FFT). El preset de strength mapea a parámetros distintos en cada modo.

  • Fuente: src/commands/denoise.js
  • Filtro (video): hqdn3d=<luma_spatial>:<chroma_spatial>:<luma_temporal>:<chroma_temporal>
  • Filtro (audio): afftdn=nf=<piso_ruido_dB>
--strengthVideo (hqdn3d)Audio (afftdn piso de ruido)
light3:2:3:2-20 dB
medium5:4:5:4-30 dB
strong7:6:7:6-40 dB
Argumento / OpciónDefaultOpcionesNotas
<input>requeridoArchivo de entrada
--target <type>videovideo / audioConmuta entre hqdn3d y afftdn
--strength <level>mediumlight / medium / strongMapeo de preset (tabla arriba)
-o, --output <path><nombre>-denoised.<ext>Sobrescribir salida
bash
$ npx fqmpeg denoise input.mp4 --target video --strength medium --dry-run

  ffmpeg -i input.mp4 -vf hqdn3d=5:4:5:4 -c:a copy input-denoised.mp4
bash
$ npx fqmpeg denoise input.mp4 --target audio --strength medium --dry-run

  ffmpeg -i input.mp4 -af afftdn=nf=-30 -c:v copy input-denoised.mp4

Para video en mano con poca luz, --strength medium (default) acierta en el balance — reducción visible de ruido sin suavizar de más. --strength strong (7:6:7:6) está más cerca de "suavizar" que de "denoise" y se nota en superficies con textura (piel, tela, follaje). Para ruido de audio, afftdn es el estándar moderno: -30 dB quita el siseo típico; sube a -40 (strong) para zumbido o aire acondicionado de fondo.

Repaso del cambio de modo: --target audio re-encodea video haciendo copia (-c:v copy), y --target video re-encodea audio haciendo copia (-c:a copy). Encadénalos en serie si necesitas ambos: denoise input.mp4 --target video -o tmp.mp4 && denoise tmp.mp4 --target audio.

deflicker — Igualar variaciones de brillo (timelapse)

El arreglo para timelapses grabados con luz inconsistente (modo prioridad apertura cazando entre fotogramas, o cambio manual de exposición). Promedia el brillo de cada fotograma contra una ventana deslizante de N.

  • Fuente: src/commands/deflicker.js
  • Filtro: deflicker=size=N
  • Rango: --size es 2129 fotogramas (límite del filtro FFmpeg, fqmpeg lo valida antes de invocar)
Argumento / OpciónDefaultNotas
<input>requeridoVideo de entrada
--size <n>5Tamaño de ventana de promediado en fotogramas (rango 2129)
-o, --output <path><nombre>-deflickered.<ext>Sobrescribir salida
bash
$ npx fqmpeg deflicker input.mp4 --size 5 --dry-run

  ffmpeg -i input.mp4 -vf deflicker=size=5 -c:a copy input-deflickered.mp4

--size 5 (default) suaviza el parpadeo en 5 fotogramas consecutivos — suficiente para igualar caza de apertura sin emborronar transiciones reales de luz. Sube a --size 7 o 9 para parpadeo severo (timelapses de atardecer donde la cámara no alcanzó al sol). fqmpeg pre-valida --size al rango del filtro FFmpeg 2129 y rechaza valores fuera de rango con un error claro antes de invocar FFmpeg (Error: size must be between 2 and 129). Valores pares funcionan — los tamaños impares (5, 7, 9, 11) son convencionales para promedios móviles porque la ventana se centra en el fotograma actual, pero FFmpeg no lo requiere. Si necesitas deflicker en un clip corto donde la ventana cubre casi toda la duración, la salida del filtro se vuelve inestable en cabeza/cola — recorta primero la parte central con trim.

deblock — Quitar bloques de compresión

El arreglo para la rejilla de macrobloques que se ve en repostes pesadamente comprimidos de YouTube o videos viejos de WhatsApp. Aplica el filtro deblock de FFmpeg en modo weak con un alpha/beta mapeado desde strength.

Argumento / OpciónDefaultRangoNotas
<input>requeridoVideo de entrada
--strength <n>501100Mapea linealmente a alpha y beta (ambos = strength / 100)
-o, --output <path><nombre>-deblocked.<ext>Sobrescribir salida
bash
$ npx fqmpeg deblock input.mp4 --strength 50 --dry-run

  ffmpeg -i input.mp4 -vf deblock=filter=weak:alpha=0.50:beta=0.50 -c:a copy input-deblocked.mp4

--strength 50 (default) es moderada — reduce visiblemente los bordes de bloque sin emborronar detalle fino. --strength 80+ ya parece "foco suave en todo el cuadro", que casi nunca es lo que quieres; --strength 2030 queda mejor para fuentes con poca compresión donde solo necesitas limpiar cielo y gradientes de piel. El modo filter=weak está fijado en código — fqmpeg no expone strong porque en nuestras pruebas suaviza de más. Si quieres filter=strong, copia la salida de --dry-run y edítala antes de correr FFmpeg directamente.

Quitar Objetos

delogo — Quitar un logo de una región fija

Cubre una región rectangular interpolando desde los píxeles que están justo afuera del cuadro. Úsalo para logos fijos, bugs de canal o marcas de agua que no se mueven.

  • Fuente: src/commands/delogo.js
  • Filtro: delogo=x=X:y=Y:w=W:h=H
  • Argumentos posicionales — archivo de entrada y región x:y:w:h
Argumento / OpciónDefaultNotas
<input>requeridoVideo de entrada
<region>requeridoRegión del logo como x:y:w:h (píxeles desde la esquina superior izquierda)
-o, --output <path><nombre>-delogo.<ext>Sobrescribir salida
bash
$ npx fqmpeg delogo input.mp4 10:10:120:60 --dry-run

  ffmpeg -i input.mp4 -vf delogo=x=10:y=10:w=120:h=60 -c:a copy input-delogo.mp4

El formato de región es estricto: x:y:w:h con cuatro enteros positivos. Cualquier otra cosa (negativos, decimales, partes faltantes) falla con Error: region must be x:y:w:h. x y y son la esquina superior izquierda; w y h son ancho y alto. No agregues margen al cuadro — el filtro interpola desde los píxeles inmediatamente afuera, así que un cuadro ajustado da el resultado más limpio. Si el logo tiene bordes con antialiasing, expande el cuadro 2-3 píxeles a cada lado.

Funciona bien con logos estáticos y bugs de canal. No funciona con logos animados, marquesinas o cualquier cosa que se mueva — para eso necesitas un pipeline de tracking fuera de fqmpeg. Para una región que cubre casi todo el cuadro, la interpolación no puede reconstruir lo que falta; delogo rinde mejor cuando la región es una fracción pequeña del cuadro.

Detección (Solo Análisis)

Estos dos verbos no producen archivo de salida. Pasan la fuente por un filtro de detección, descartan la salida (-f null -) e imprimen los hallazgos del filtro a stderr. El caso de uso: escanear una captura larga buscando defectos (una grabación de pantalla de 90 minutos que se congeló en algún punto; una transferencia de TV con fotogramas negros entre segmentos) antes de meterla al editor.

blackdetect — Encontrar escenas negras

Detecta tramos donde la imagen es mayormente negra. Útil para encontrar cortes a negro en una captura larga, o para detectar tramos de "señal perdida" en una transferencia de TV.

  • Fuente: src/commands/blackdetect.js
  • Filtro: blackdetect=d=<duración>:pix_th=<umbral>
  • Salida: sin archivo — las marcas de tiempo se imprimen a stderr como [blackdetect @ ...] black_start:N black_end:M black_duration:D
Argumento / OpciónDefaultRangoNotas
<input>requeridoVideo de entrada
--threshold <n>0.980.01.0Fracción de píxeles que deben ser casi negros para contar como fotograma negro
--duration <sec>0.5número positivoDuración mínima del tramo a reportar (segundos)
bash
$ npx fqmpeg blackdetect input.mp4 --threshold 0.98 --duration 0.5 --dry-run

  ffmpeg -i input.mp4 -vf blackdetect=d=0.5:pix_th=0.98 -f null -

Pasa stderr por grep para capturar solo las coincidencias:

bash
npx fqmpeg blackdetect input.mp4 2>&1 | grep "black_start"
# [blackdetect @ 0x...] black_start:12.345 black_end:14.567 black_duration:2.222
# [blackdetect @ 0x...] black_start:120.0 black_end:121.5 black_duration:1.5

Baja --threshold a 0.95 si el "negro" es realmente gris oscuro (ruido de compresión, fugas de baja luz). Sube --duration a 2 o más si solo quieres pausas largas (fundidos de intro/outro), no los cortes breves de 0.5 s entre escenas. Siguiente paso útil: alimenta las marcas de tiempo a un trim o split para cortar en los puntos negros.

freeze-detect — Encontrar fotogramas congelados

Detecta tramos donde la imagen deja de cambiar (el cuadro se "congela"). Útil para grabaciones de pantalla que se quedaron colgadas, o archivos con un encode con glitch donde el mismo fotograma se repite varios segundos.

  • Fuente: src/commands/freeze-detect.js
  • Filtro: freezedetect=n=<noise>:d=<duración>
  • Salida: sin archivo — freeze_start, freeze_duration, freeze_end se imprimen a stderr
Argumento / OpciónDefaultRangoNotas
<input>requeridoVideo de entrada
--duration <n>2número positivoDuración mínima del tramo a reportar (segundos)
--noise <n>0.00101Tolerancia de diferencia entre píxeles — fotogramas dentro de este delta cuentan como idénticos
bash
$ npx fqmpeg freeze-detect input.mp4 --duration 2 --noise 0.001 --dry-run

  ffmpeg -i input.mp4 -vf freezedetect=n=0.001:d=2 -f null -
bash
npx fqmpeg freeze-detect input.mp4 2>&1 | grep "freeze_"
# [freezedetect @ 0x...] lavfi.freezedetect.freeze_start: 45.5
# [freezedetect @ 0x...] lavfi.freezedetect.freeze_duration: 8.3
# [freezedetect @ 0x...] lavfi.freezedetect.freeze_end: 53.8

El default --noise 0.001 es sensible — útil para cazar duplicados exactos (la firma típica de una captura colgada). Sube a 0.01 si quieres encontrar tramos "casi congelados" (un webinar donde la diapositiva no cambió por minutos pero el encoder siguió produciendo fotogramas ligeramente distintos). --duration 2 ignora pausas cortas legítimas; baja a 0.5 para detección más fina.

Recetas del Mundo Real

Cada receta encadena varios verbos en un flujo de trabajo real.

Receta 1: Rescatar un clip en mano oscuro y movido

Grabaste un clip al atardecer en mano — vibración visible, ruido notable en las sombras, y algo de macroblocking por el bitrate bajo de la cámara. Meta: estabilizar, después limpiar.

bash
# Paso 1: estabilizar primero — denoise quiere input estable para el promediado temporal
npx fqmpeg stabilize clip.mp4 --strength 10 --shakiness 5
# → clip-stabilized.mp4

# Paso 2: denoise de video con strength medium
npx fqmpeg denoise clip-stabilized.mp4 --target video --strength medium
# → clip-stabilized-denoised.mp4

# Paso 3 (opcional): deblock si la fuente aún muestra bloques
npx fqmpeg deblock clip-stabilized-denoised.mp4 --strength 30
# → clip-stabilized-denoised-deblocked.mp4

El orden importa. Estabilizar antes que denoise: hqdn3d promedia temporalmente entre fotogramas, y si la cámara está vibrando, cada fotograma está en un ángulo ligeramente distinto, lo que hace que el componente temporal del denoise sea menos efectivo (promedia píxeles desalineados). Con una fuente estable, el componente temporal funciona como se diseñó.

Si la fuente fue grabada con luz genuinamente baja, después de este pipeline llega a corrección de brillo con el verbo color — denoise tiende a aplanar el contraste un poco, y un --gamma 1.1 recupera la chispa de los medios tonos.

Receta 2: Encontrar y recortar secciones malas de una grabación de pantalla larga

Tienes una grabación de pantalla de 4 horas donde la captura se congeló en algún punto del medio. Meta: encontrar los puntos de congelado, luego recortar alrededor.

bash
# Paso 1: escanear por congelados de más de 5 segundos
npx fqmpeg freeze-detect recording.mp4 --duration 5 2>&1 | grep "freeze_"
# [freezedetect @ ...] freeze_start: 7230.5
# [freezedetect @ ...] freeze_duration: 45.2
# [freezedetect @ ...] freeze_end: 7275.7

# Paso 2: recortar la sección justo antes del congelado
npx fqmpeg trim recording.mp4 --start 0 --end 7230
# → recording-trimmed.mp4

# Paso 3 (opcional): también revisa fotogramas negros (señal perdida)
npx fqmpeg blackdetect recording.mp4 --duration 1 2>&1 | grep "black_start"

grep filtra solo las líneas de detección para que no tengas que leer el ruido del progreso de FFmpeg. Si quieres ambas detecciones en una sola pasada, tienes que invocar FFmpeg directamente con los dos filtros encadenados — fqmpeg corre un filtro por verbo por diseño. Para capturas más largas, considera primero dividir con npx fqmpeg split recording.mp4 --chunks 4 y correr la detección en cada chunk en paralelo.

Receta 3: Quitar el logo de un canal en una transferencia de TV

Estás limpiando una grabación que tiene un bug de estación en la esquina superior derecha. Meta: quitar el logo y limpiar un poco los artefactos de compresión, en una sola pasada.

bash
# Paso 1: identifica las coordenadas del logo con una captura de cuadro + visor
npx fqmpeg snapshot recording.mp4 --time 5 -o frame.png
# Abre frame.png, mide el cuadro del logo en píxeles.
# Por ejemplo: en x=1750 y=20, de 150x80 píxeles.

# Paso 2: quitar el logo
npx fqmpeg delogo recording.mp4 1750:20:150:80
# → recording-delogo.mp4

# Paso 3 (opcional): deblock para limpiar macroblocking de la transferencia original
npx fqmpeg deblock recording-delogo.mp4 --strength 40
# → recording-delogo-deblocked.mp4

Agrega 2-3 píxeles de margen al cuadro del logo en cada lado (así 1748:18:154:84 en vez del ajustado 1750:20:150:80) si el logo tiene bordes suaves — la interpolación necesita píxeles de referencia limpios justo afuera del cuadro. Para un bug animado que pulsa o gira, delogo no funciona limpio — tendrías que capturar el bounding box completo de la animación, lo que deja un parche visible.

Preguntas Frecuentes

stabilize o deshake — ¿cuál uso?

stabilize es el flujo vidstab de 2 pasadas y da un resultado notoriamente más suave, especialmente en clips largos con movimiento direccional (toma caminando, montaje en vehículo). Necesita FFmpeg construido con --enable-libvidstab. deshake es de una pasada, viene integrado en FFmpeg estándar, y es ~3-5× más rápido. Usa deshake para iterar (probar fuerzas rápido) o cuando tu build no tiene vidstab; usa stabilize para el render final de material que importa.

stabilize deja un .fqmpeg-transforms-*.trf — ¿es un bug?

No — el temporal está registrado para borrarse al salir el proceso normalmente. Si mataste el proceso con kill -9 o SIGKILL, el hook de limpieza no corre y el .trf queda. Es seguro borrarlo a mano (rm .fqmpeg-transforms-*.trf en el directorio del input). El archivo contiene los datos de detección de movimiento de la pasada 1; la pasada 2 los lee, así que no lo borres a mitad de corrida.

¿Cuál es el rango válido para deflicker --size?

El filtro deflicker de FFmpeg acepta valores size de 2 a 129 fotogramas (default 5) — verificado contra FFmpeg 6.1.1 con ffmpeg -h filter=deflicker. fqmpeg pre-valida este rango y rechaza valores fuera de rango con un error claro antes de invocar FFmpeg. Los valores pares como --size 4 son aceptados por el filtro; los tamaños impares (5, 7, 9, 11) son convencionales para promedios móviles porque la ventana se centra en el fotograma actual, pero es una convención, no un requisito.

¿Puedo correr denoise --target audio y --target video en un solo comando?

No — cada invocación maneja un solo target porque los filtros subyacentes (hqdn3d para video, afftdn para audio) necesitan ubicación distinta (-vf vs -af) y flags de copia distintos. Encadena dos llamadas: denoise clip.mp4 --target video -o tmp.mp4 && denoise tmp.mp4 --target audio. Si necesitas ambos en una pasada, la salida --dry-run de cada uno te da las cadenas de filtros para combinar en una invocación manual de FFmpeg.

blackdetect dice que no hay escenas negras pero las veo a simple vista, ¿qué pasa?

O --threshold está demasiado alto (el "negro" de tu fuente es realmente gris oscuro — típico de hardware grabador barato) o --duration es demasiado largo (los cortes son más cortos que el piso). Prueba --threshold 0.90 --duration 0.2 para ampliar la detección. El parámetro pix_th es la fracción de píxeles bajo el umbral de luma negra (default 0.10 luma) que debe estar presente — con 0.98 necesitas 98% de píxeles casi negros para registrar, lo que un fotograma "negro" con ruido podría no alcanzar.

La interpolación de delogo se ve como un parche borroso — ¿se puede arreglar?

El filtro reconstruye desde píxeles circundantes, así que no puede recuperar detalle que no ve. Tres tácticas que ayudan: (1) ajusta el cuadro justo al borde del logo — más margen significa más interpolación; (2) para fondos con mucho detalle (follaje, agua, texto), el parche se va a ver sí o sí — acéptalo o reemplaza la región con un fondo de stock; (3) si el logo está sobre un área plana (cielo, pared), delogo funciona bien — pruébalo primero antes de hacer un enmascarado manual en un editor real.

¿Estos verbos funcionan con una fuente VFR (variable frame rate)?

stabilize, denoise, deflicker y deblock procesan por fotograma, así que VFR no los rompe, pero el patrón VFR de salida puede no preservarse según los defaults de FFmpeg. blackdetect y freeze-detect reportan marcas de tiempo basadas en el PTS de la fuente, lo que funciona en VFR pero las duraciones son tiempo real, no conteo de fotogramas. Si necesitas detección con precisión de fotograma, convierte primero a CFR con npx fqmpeg fps input.mp4 --fps 30.

¿Puedo combinar varios verbos de limpieza en una sola pasada para evitar pérdida generacional?

No vía fqmpeg directamente — cada verbo produce una salida y re-encodea. La pérdida generacional de H.264 → H.264 con CRF 23 es pequeña pero real a lo largo de 3-4 pasadas. Dos atajos: (1) sube la calidad para los pasos intermedios editando el --dry-run para usar -crf 18 o lossless; (2) salta fqmpeg para la cadena — copia las cadenas de filtros del --dry-run de cada verbo y córrelos como un solo comando FFmpeg con -vf "filter1,filter2,filter3".

Conclusión

Los ocho verbos del C7 cubren las operaciones de restauración y detección a las que recurres antes del grading o la compresión:

  • stabilize, deshake para movimiento de cámara (vidstab 2 pasadas vs integrado 1 pasada — elige según calidad vs velocidad)
  • denoise, deflicker, deblock para ruido, parpadeo de brillo y macroblocking (denoise --target audio cambia a un filtro completamente distinto; deflicker --size debe ser impar)
  • delogo para borrado de objetos en región fija (funciona sobre fondos planos, sufre con detalle)
  • blackdetect, freeze-detect para escaneo solo-análisis de capturas largas (sin archivo de salida — pasa stderr por grep)

Cada verbo imprime la invocación FFmpeg subyacente con --dry-run, así que cuando los defaults no alcanzan (un deblock filter=strong, una cadena multi-filtro para evitar pérdida generacional, un delogo con máscara no rectangular), copia el comando, personalízalo y corre FFmpeg directamente. Para el mapa completo de fqmpeg, ve la guía completa de fqmpeg.