使用 FFmpeg ffv1 对 jpeg 图像进行无损视频不压缩但扩展

使用 FFmpeg ffv1 对 jpeg 图像进行无损视频不压缩但扩展

FFmpeg / ffv1.3 / mkv 能否制作出不大于其各部分总和的无损视频(如果可以,如何制作)?如果不可以,有什么好的替代方案可以接近其大小?视频必须是无损的。

我正在尝试使用 FFmpeg 在一组类似的 jpeg 图像(来自网络摄像头的图像)上创建带有 ffv1.3 的 mkv。我能够创建视频,但是它的大小至少是 jpeg 图像集合的 2 倍。我本来期望压缩程度大致相同或更好。

我明白 jpeg 本身针对压缩进行了优化。但是,大量非常相似的图像应该能够进一步压缩,或者在这种情况下将与原始图像相似的图像相加。

我用来创建文件的命令是:

ffmpeg -pattern_type glob -i '*.jpg' -vcodec ffv1 -level 3 -an -pass 1 -passlogfile passlog -f matroska /dev/null

ffmpeg -pattern_type glob -i '*.jpg' -vcodec ffv1 -level 3 -an -pass 2 -passlogfile passlog -f matroska ~/foo.mkv

输入文件总共 24M,但生成的 mkv 为 96M(每个 du -h)。

第二遍的结果:

ffmpeg version N-79053-g7eedad9 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.6 (Debian 4.6.3-14+rpi1)
  configuration: --enable-cross-compile --cross-prefix= --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff
  libavutil      55. 19.100 / 55. 19.100
  libavcodec     57. 28.103 / 57. 28.103
  libavformat    57. 28.101 / 57. 28.101
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 39.102 /  6. 39.102
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
Input #0, image2, from '*.jpg':
  Duration: 00:00:21.32, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc
File '/home/pi/foo.mkv' already exists. Overwrite ? [y/N] y
[swscaler @ 0x3671f30] deprecated pixel format used, make sure you did set range correctly
Output #0, matroska, to '/home/pi/foo.mkv':
  Metadata:
    encoder         : Lavf57.28.101
    Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), yuv422p, 640x480, q=2-31, pass 2, 200 kb/s, 25 fps, 1k tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.28.103 ffv1
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> ffv1 (native))
Press [q] to stop, [?] for help
frame=  533 fps=4.2 q=-0.0 Lsize=   97815kB time=00:00:21.32 bitrate=37584.4kbits/s speed=0.168x
video:97808kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.006607%

每个 jpeg 大约为 43143 字节(每个 ls -al),但运行以下命令,该工具显示每个图像为 614400 字节(视频和独立 jpeg 图像均如此)。我假设这是图像的解压大小(640x480x2)。

ffmpeg -pattern_type glob -i'*.jpg'-f framemd5-

以下结果是针对图像的,报告的 mkv 尺寸相同。

ffmpeg version N-79053-g7eedad9 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.6 (Debian 4.6.3-14+rpi1)
  configuration: --enable-cross-compile --cross-prefix= --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff
  libavutil      55. 19.100 / 55. 19.100
  libavcodec     57. 28.103 / 57. 28.103
  libavformat    57. 28.101 / 57. 28.101
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 39.102 /  6. 39.102
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
Input #0, image2, from '*.jpg':
  Duration: 00:00:21.32, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc
#format: frame checksums
#version: 1
#hash: MD5
#software: Lavf57.28.101
#tb 0: 1/25
#stream#, dts,        pts, duration,     size, hash
Output #0, framemd5, to 'pipe:':
  Metadata:
    encoder         : Lavf57.28.101
    Stream #0:0: Video: rawvideo (Y42B / 0x42323459), yuvj422p, 640x480, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
    Metadata:
      encoder         : Lavc57.28.103 rawvideo
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> rawvideo (native))
Press [q] to stop, [?] for help
0,          0,          0,        1,   614400, 2148ff8b95296f4bacc1099d13235063
0,          1,          1,        1,   614400, da330e2acd2f7d7a1e79fe79fccc90cf
0,          2,          2,        1,   614400, f55563c13a9f232ce32419fa26e37214
0,          3,          3,        1,   614400, c53d994fff0a9b26529fa8763deae520

编辑: 最好的压缩(和良好的速度)来自于 jpeg 图像本身的容器:

ffmpeg -pattern_type glob -i'*.jpg'-vcodec copy -an -f matroska~/foo.mkv

生成的文件刚好超过 24M(而 ffv1 为 96M)。此外,解压后的 jpeg 图像为 312M,在两种情况下,压缩效果都相当好。如果我从 jpeg 以外的任何格式开始,ffv1 将是理想的选择,但在我的例子中,有损 jpeg 也是无损初始图像。

答案1

我通常发现使用无损编解码器编码有损视频会导致文件大小变大。FFmpeg 必须先解压缩您的输入,然后才能编码为 ffv1,因此它是从您的 jpeg 的未压缩版本开始工作的。该过程概述如下:https://ffmpeg.org/ffmpeg.html#Detailed-description

相关内容