代码之家  ›  专栏  ›  技术社区  ›  stevendesu

ffmpeg:固定低运动区域的结巴

  •  0
  • stevendesu  · 技术社区  · 6 年前

    我正在尝试使用ffmpeg创建具有非常特殊要求的视频:

    • 关键帧速率必须非常低(理想情况下小于0.5秒)
    • 必须具有较低的(~1Mbps)比特率
    • 必须以合理的(~24fps)帧速率运行
    • 宽度必须是4的倍数
    • 不能有任何B帧
    • 必须是H.264基线编码
    • 必须是FLV

    编码速度无关紧要。如果需要2分钟对1秒钟的视频进行编码,那绝对是好的。重要的是输出将质量保持在尽可能低的比特率。

    为此,我目前有以下ffmpeg命令:

    ffmpeg \
        -fflags +genpts \
        -i big_buck_bunny_1080p_stereo.avi \
        -vf "scale=trunc(360*iw/ih/4)*4:360" \
        -vf "settb=1/1000" \
        -r 24 \
        -g 6 \
        -keyint_min 6 \
        -force_key_frames "expr:gte(t,n_forced/4)"\
        -c:v libx264 \
            -preset veryslow \
            -tune zerolatency \
            -profile:v baseline \
            -pix_fmt yuv420p \
        -b:v 1000k \
        -c:a speex \
            -ar 16000 \
            -ac 1 \
        -b:a 64k \
        -f flv bbb_lo.flv
    

    我想试验各种编码选项( me_method , subq 等)看看它们如何影响质量和比特率。不过,在这之前,我有一个直接的质量问题需要通过上面的命令来解决。

    See the video here on YouTube

    我只剪辑了视频的一部分,这部分内容确实说明了这个问题。当屏幕的某个区域颜色发生微小变化时,就没有运动矢量。这意味着视频的某些部分会在下一个关键帧之前取消更新。这可以在视频开头左边的树上或兔子还在睡觉的时候看到。如果一个观看者盯着屏幕的某些区域看,可能看起来视频只有每秒4帧的速度(我的关键帧速率),即使视频实际上是每秒24帧的速度——它只是没有更新整个屏幕。

    我会没事的,如果这些区域的屏幕变得非常模糊,只要运动保持。做了一点调查我认为 -flags2 -fastpskip 将修复此问题,但此选项不适用于我:

    [libx264 @ 0x55b63e32c760] [Eval @ 0x7ffea2a7a830] Undefined constant or missing '(' in 'fastpskip'
    [libx264 @ 0x55b63e32c760] Unable to parse option value "fastpskip"
    [libx264 @ 0x55b63e32c760] Error setting option flags2 to value -fastpskip.
    

    如何修复此问题以保持图像质量为代价的运动?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Gyan    6 年前

    运动矢量由编码器(X264)计算,而不是由ffmpeg计算。你的视频仍然是1080p,而不是360p,因为给定的比特率很低,所以在量化过程中,细微的变化会被压平。

    每个输出流只能有一个简单的筛选图,因此

    -vf "scale=trunc(360*iw/ih/4)*4:360" \
    -vf "settb=1/1000" \
    

    必须成为

    -vf "scale=trunc(360*iw/ih/4)*4:360,settb=1/1000" \
    

    否则只应用时基筛选器。

    对于一个大小为 6 也可以跳过键控和强制KFS。