Tengo un gran conjunto de archivos jpgs que quiero convertir a un video sin pérdidas (o, al menos, muy cerca de sin pérdidas, siempre y cuando el tiempo de codificación no sea mucho mayor que lo contrario).
Ingenuamente, pensaría que debería haber algún códec que pueda almacenar cada fotograma jpg individual tal como está (sin recompresión), y tal vez lograr una buena compresión al reemplazar algunos de los fotogramas solo por la información del delta del fotograma anterior. En mi caso, hay muchas secuencias de cuadros que son idénticas entre sí, o que tienen una pequeña diferencia entre ellas.
¿Hay algún códec y configuraciones adecuadas para ffmpeg que puedan lograr esto?
Respuestas:
Solo mux las imágenes
Simplemente puede modificar las imágenes JPG para hacer un video:
Tenga en cuenta que si omite , se aplicará
-framerate
un valor predeterminado de-framerate 25
a la entrada.Optimización sin pérdidas
Puede usar
jpegtran
para realizar una optimización sin pérdidas en cada marco que puede proporcionar ahorros significativos en el tamaño del archivo:Ahora mux con
ffmpeg
como se muestra arriba.Comprobando que en realidad no tiene pérdidas
El framehash muxer se puede utilizar para comparar el hash único de cada cuadro para garantizar que el resultado sea realmente sin pérdidas:
En los ejemplos anteriores, cada cuadro asociado para la entrada y la salida comparten el mismo hash asegurando que los cuadros sean idénticos y que la salida no tenga pérdidas.
Ver también
fuente
framemd5
se supone que deben lograr los dos comandos más allá de simplemente enumerar los hashes? ¿Cómo obtendría una compresión adicional cuando se identifican cuadros idénticos?Esto generará un video H.264 sin pérdidas donde los cuadros usarán información de otros cuadros
ffmpeg -f image2 -r 30 -i %09d.jpg -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast a.mp4
Explicación de opciones:
-f image2
- le dice a ffmpeg que seleccione un grupo de imágenes-r 30
- le dice a ffmpeg que codifique a 30 cuadros (o imágenes) por segundo (cambie esto a la velocidad de cuadros deseada)-i %09d.jpg
- le dice a ffmpeg que use las imágenes 000000000.jpg a 999999999.jpg como entrada. Cambiar el9
en%09d.jpg
que el número de ceros los nombres de su secuencia de imágenes tiene. Si sus nombres de archivo son, por ejemplo, img0001.jpg, esto se expresaría como img% 04d.jpg-vcodec libx264
- le dice a ffmpeg que envíe a un archivo compatible con H.264-profile:v high444
- le dice a libx264 que use el perfil 4: 4: 4 predictivo sin pérdidas, lo que permite la codificación sin pérdidas-refs 16
- le dice a libx264 que tenga 16 imágenes almacenadas en un búfer, para que otras imágenes en el video puedan hacer referencia a ellas-crf 0
- le dice a libx264 que realice una codificación sin pérdidas-preset ultrafast
- le dice a libx264 que priorice la velocidad de codificación sobre el tamaño del archivo de salidaa.mp4
- le dice a ffmpeg que guarde la salida en un archivo MP4 llamado a.mp4. Cambie esto al nombre de archivo y al formato que desea usarfuente
-f image2
es superfluo aquí. El archivo de imagen demuxer debe usar en-framerate
lugar de-r
. libx264 elegirá automáticamente el apropiado-profile
para sin pérdidas, y-preset
se ocupará de ello-refs
.-refs 5
como máximo, a menos que sepa que su contenido tiene imágenes idénticas separadas por varias otras, eso podría causar que x264 pierda la referencia antes de que llegue al duplicado. Más alto queultrafast
hace poco diferente en el modo sin pérdida, aparte de la ganancia de ~ 10% de CABAC sobre CAVLC (por un alto costo de CPU a las tasas de bits requeridas para sin pérdida). En serio, en algunos 720x480p60 de acción en vivo (salida de desentrelazado),superfast
era de 28 GB,slower
era de 27 GB. Si el tiempo de codificación no importa, pero el tiempo de decodificación sí, asegúrese de evitar CABAC. Quizás incluso-tune fastdecode
. El recuento moderado de referencia no debería doler.-preset placebo
algunas fracciones adicionales de porcentaje.-vcodec libx265 -x265-params lossless=1
Es la opción equivalente. (Pero en mi experiencia (= grabación de presentaciones de diapositivas de Powerpoint), no es necesariamente mejor, y es mucho más lento que h264) Manténgase sintonizado para AV1 de AOMedia / NETVC1 de IETF / Daala de Xiph / lo que sea que vaya a cambiar de nombre para entonces ... el modo sin pérdidasPuede crear una
avi
animación como una serie depng
imágenes (nopng
tiene pérdidas, por lo que lajpeg => png
conversión no debería degradar sus imágenes):si tus imágenes tienen un nombre
img_0001.jpg
donde "25" es la velocidad de fotogramas que desea en el video resultante.
-start_number
no es necesario si es 1, pero es útil si su primer número de video no es 1.Si desea codificar
mjpeg
con la línea de comandos de mayor calidad es:Y lo bueno de esto es que puedes convertir el video a una serie de imágenes:
etc ...
fuente
Para ampliar la respuesta de LordNeckbeard, sí, solo mux los datos JPEG en una transmisión de video MJPEG. Esa será la representación más pequeña de la secuencia exacta de imágenes de salida, a pesar de que MJPEG es un códec terriblemente ineficiente para los estándares actuales. (sin redundancia temporal, y ni siquiera una predicción intra.
Puede hacer un video MJPEG de velocidad de fotogramas variable para aprovechar las imágenes duplicadas en su entrada.
Hrm, esto no va a funcionar, ya que mpdecimate no funcionará en datos comprimidos, y no podemos dejar que ffmpeg decodifique y luego vuelva a jpeg los datos de imagen sin pérdida y costo de CPU.
¿Tal vez si reemplaza los archivos fuente duplicados jpg con archivos vacíos con ese número de secuencia, o algo así?
Como esta pregunta ni siquiera es reciente, no me tomaré el tiempo para descubrir cómo hacerlo a menos que alguien responda y pregunte cómo. Pero como MJPEG puede entrar en un contenedor mkv, estoy seguro de que es posible tener un archivo que no duplique los datos jpeg para cuadros repetidos, sino que simplemente no tiene un cuadro de salida para decodificar hasta que la secuencia de duplicados sea encima.
Oh, aquí hay una idea:
Luego, elimine (o mueva a un lado) todos los archivos jpegs de los marcos que mpdecimate quiere eliminar (¿probablemente tiene algunas opciones de registro? los archivos JPEG caídos?). muje eso a un MJPEG.mkv, luego haga algo con mkvmerge para reemplazar las marcas de tiempo del marco en eso con las marcas de tiempo de
mpdecimate.timestamps
.Si estuviera codificando, en lugar de simplemente enviar datos jpeg a MJPEG, esto sería MUCHO más fácil, ya que simplemente usaría mi primer comando con mpdecimate y cualquier códec que no sea
copy
, y simplemente Funcionaría (tm).No he intentado nada de esto, ya que esta era una vieja pregunta. También la razón por la que no he rellenado los vacíos de cómo filtrar realmente su directorio de archivos JPEG en función de la salida mpdecimate, o cómo usar realmente la secuencia de marca de tiempo.
fuente