Cortar videos en cuadros exactos con el filtro de selección ffmpeg

16

En lugar de usar -ssy -tobuscar parámetros, que no parecen muy precisos, ¿puedo cortar videos para números de cuadros dados? Por ejemplo;

ffmpeg -i video.webm -startingframe 80 -endingframe 560 output.webm

[Marco 80 y marco 560 incluidos. Entonces, como total, hace (560 - 80 +1) fotogramas]

Después de las respuestas y un poco de búsqueda, he probado algunos comandos. Pero hasta ahora no pude encontrar una manera aceptable.

Si alguien quiere cortar la transmisión de video entre 250 y 750 cuadros, este es el camino a seguir. Dará 501 cuadros como salida:

Nota: movie.mp4 tiene 25 fps y su frecuencia de muestreo de audio 48k

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm

Como se esperaba, la salida dura 20 segundos, exactamente.

Usando el mismo método para audio:

ffmpeg -i movie.mp4 -vn -af "aselect=between(n\,480\,1440),setpts=PTS-STARTPTS" a_stream.webm

Inesperadamente, este tiene una precisión muy pobre. Debería haberme dado 960001 (960k + 1) muestras que equivalen a 20 segundos de audio. Pero en cambio, la producción fue de 20.505 segundos de duración y tiene 984240 muestras. Además, si aumento la duración, el error también aumenta.

Luego intenté usar los parámetros -ss -to para cortar la secuencia de audio:

ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm

La vieja forma clásica funciona mucho mejor. La producción fue de 20.003 segundos y tiene 960144 muestras. Además, aumentar la duración no aumenta el error, el error es constante, siempre hay un excedente de 144 muestras con ese archivo de entrada.

En resumen: el selectfiltro funciona bien la mayor parte del tiempo, pero una selección no lo es. Los -ssparámetros clásicos funcionan mejor para audio pero no con precisión de muestra. Además, no es posible usar -vf selecty -ssparámetros juntos, ya -ssque afectará tanto las transmisiones de audio como las de video, mientras que queremos que solo afecte el audio.

Entonces, para cortar con precisión un archivo multimedia, tengo que hacer estos 3 pasos:

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm 
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm 
ffmpeg -i v_stream.webm -i a_stream.webm -c:v copy -c:a copy  movie-between_10th_and 20th_seconds.webm

Esto da los resultados más precisos. El video tiene una duración de 20.000 segundos y el audio con precisión de cuadro tiene una duración de 20.003 segundos y tiene una muestra de 960144. No coincide exactamente con la transmisión de video, pero está bien. Solo hay 144 muestras excedentes. El mayor inconveniente es que, cada vez que quiero cortar un archivo, tengo que enviar 3 comandos para un trabajo simple y crea dos archivos innecesarios: a_stream.webm y v_stream.webm. Y el selectfiltro no funciona en algunos archivos de entrada que he probado. Realiza el trabajo correctamente (?) Pero nunca detiene el proceso de codificación, por lo que tengo que cerrar el símbolo del sistema cada vez.

destor
fuente
He leído esa página antes de publicar esta pregunta. Esa página no me ayudó. Si una entrada tiene fps variables, ¿podemos simplemente calcular usando esa ecuación? No lo creo. Además, todavía no creo que '-ss' me dé una posición precisa. La búsqueda cuadro por cuadro sería mejor, supongo.
destor
Tenga en cuenta que -sses con precisión de cuadro (ver aquí ). ¿Realmente tienes entrada variable-fps? Mi respuesta enlaza con el hilo de la lista de correo que menciona el uso de selectfiltros donde puede especificar el número de cuadro. ¿Has intentado eso?
slhck
He intentado usar selecty aselectfiltros para transmisiones de video y audio. Selecttiene una precisión de fotograma para el video, pero aselectno tiene precisión de muestra. En realidad, está lejos de ser exacto. Da resultados mucho peores que usar los -ss -toparámetros simples . Por eso, por ahora, uso una combinación de selectfiltro y -ss -toparámetros para lograr el corte más preciso. Pero es una forma sucia de hacerlo. Mire mi primera publicación. He agregado algunas
líneas de
versión ffmpeg?
fie
¿Por qué estás tratando de cortar por un número de cuadro de todos modos? Si uno necesita ese tipo de precisión, ¿por qué no usar avidemux? ¿Quizás también sus problemas originales se deben a que selecciona el cuadro clave más cercano?
fie

Respuestas:

3

El audio proviene de segundos, no de cuadros, por lo que si desea cortar un video, debe calcular el video fps × 20 segundos de esta manera: 20 segundos de 23.97 fps = 479.4

El corte de fotogramas no es preciso porque no puede obtener fps completos durante el último segundo, por lo que el audio obtendrá más segundos o solo medio segundo o un poco más o menos. Tal vez debería usar segundos en lugar de cuadros para obtener un corte exacto, le dice al ffmpeg que lo haga por usted. Y si obtienes 1 fotograma adicional, ¿qué tal si cambias los fotogramas 250 y 750 a 250 y 749? ¡Use menos 1 allí para obtener siempre la cantidad de cuadros que solicita!

Mojtaba Golestani
fuente
En realidad, el audio proviene de muestras, no segundos ...
Anubioz