Ya hay preguntas con respecto a acelerar un video con FFmpeg, comoÉste.
Mi pregunta es: ¿Existe también una manera de especificar varias secciones que se acelerarán a través de un CSV externo?
Mi CSV se ve así:
start, end
00:00:03.296, 00:00:14.372,
00:00:16.388, 00:00:33.635,
00:00:33.693, 00:00:39.428,
00:00:39.460, 00:00:50.355,
00:00:50.355, 00:01:17.892,
00:01:17.892, 00:01:19.845,
00:01:19.845, 00:01:47.616,
Estas son las secciones exactas (una sección por línea, dos marcas de tiempo que definen el inicio y el final de cada sección) que se acelerarán 10 veces. El resto se mantendrá a la velocidad de reproducción original.
¿Hay alguna manera de hacer esto?
Respuesta1
Podemos establecer la marca de tiempo PTS deseada para cada cuadro de video, usandoajustesfiltro con if
expresión anidada elaborada.
La siguiente respuesta es solo una "prueba de concepto", suponiendo que tenga el conocimiento para crear la expresión más compleja que necesita mediante programación. La solución supone que el vídeo de entrada tiene una velocidad de fotogramas fija y que es sencillo calcular la marca de tiempo de entrada a partir del número de fotograma de entrada.
Nota:
Acelerar partes del video configurando las marcas de tiempo crea un video con velocidad de fotogramas variable (VFR), que puede no reproducirse correctamente en todos los reproductores de video.
Puede ser mejor crear un vídeo con una velocidad de fotogramas fija acelerando todo el vídeo en un factor de x10 y duplicando cada fotograma 10 veces en las partes de la velocidad original.
Tenga en cuenta que al usar un script de Python que lee el marco con OpenCV y escribe usando OpenCV (o mejor canalizado a FFmpeg), es relativamente sencillo duplicar los marcos.
Supongamos que tenemos el siguiente archivo de entrada (40 fotogramas a 1 fps):
ffmpeg -y -f lavfi -i testsrc=size=192x108:rate=1:duration=40 -c:v libx264 -g 1 input.mp4
Las marcas de tiempo del vídeo de entrada son:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
Supongamos que queremos acelerar en el rango [0, 19] y [30, 39] y obtener las siguientes marcas de tiempo de salida:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 21.1, 21.2, 21.3, 21.4, 21.5, 21.6, 21.7, 21.8, 21.9,
Podemos usar el siguiente comando FFmpeg:
ffmpeg -y -r 100 -i input.mp4 -fps_mode:v passthrough -vf "setpts='(if(lt(N,10), N, if(lt(N,20), ((N-10)/10)+10, if(lt(N,30), 11+(N-20), 21+(N-30)/10))))/TB'" -c:v libx264 -g 1 output.mp4
-r 100
se utiliza para configurar la duración del paquete en 10 ms (una duración corta del paquete permite una mayor resolución de las marcas de tiempo).-fps_mode:v passthrough
- pasa cada cuadro de entrada de entrada a salida (sin duplicar los cuadros debido a la velocidad de 100 fps).-vf "setpts='(if(lt(N,10), N, if(lt(N,20), ((N-10)/10)+10, if(lt(N,30), 11+(N-20), 21+(N-30)/10))))/TB'"
- Utilizaif
expresiones y algunas matemáticas para ajustar las marcas de tiempo.
Laif
expresión se aplica si (condición, valor si es verdadero, valor si es falso).
N
es el número de cuadro de entrada, comience a contar desde cero.
if(lt(N,10), N, ...
establece PTSN
para los primeros 10 fotogramas...
/TB
divide por el tiempo en segundos por la base de tiempo.-g 1
- Establezca el tamaño del GOP en 1 para realizar pruebas (eliminelo). Mantiene el PTS ordenado cuando se usa FFprobe.
Verificando las marcas de tiempo de salida usando FFprobe:
ffprobe -select_streams v:0 -of default=noprint_wrappers=1 -show_entries packet=pts_time output.mp4
El resultado es el esperado:
pts_time=0.000000
pts_time=1.000000
pts_time=2.000000
pts_time=3.000000
pts_time=4.000000
pts_time=5.000000
pts_time=6.000000
pts_time=7.000000
pts_time=8.000000
pts_time=9.000000
pts_time=10.000000
pts_time=10.100000
pts_time=10.190000
pts_time=10.300000
pts_time=10.400000
pts_time=10.500000
pts_time=10.600000
pts_time=10.700000
pts_time=10.800000
pts_time=10.900000
pts_time=11.000000
pts_time=12.000000
pts_time=13.000000
pts_time=14.000000
pts_time=15.000000
pts_time=16.000000
pts_time=17.000000
pts_time=18.000000
pts_time=19.000000
pts_time=20.000000
pts_time=21.000000
pts_time=21.100000
pts_time=21.200000
pts_time=21.300000
pts_time=21.400000
pts_time=21.500000
pts_time=21.600000
pts_time=21.700000
pts_time=21.800000
pts_time=21.900000
GIF animado que demuestra el resultado:
(Creado usando ffmpeg -y -i output.mp4 -filter_complex "[0:v]split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -r 1 output.gif
)