如何优化使用x264的ffmpeg以输出多个比特率的文件

13

目标是从单个源文件创建多个仅比特率不同的输出文件。已经记录的解决方案有效,但存在一些效率问题。我发现最有效的解决方案似乎没有被任何人记录过。在此发布并请求审查,同时询问其他人是否知道可以进行的其他优化。

Source file       MPEG-2 Video (Letterboxed) 1920x1080 @>10Mbps
                  MPEG-1 Audio @ 384Kbps
Destiation files  H264 Video 720x400 @ multiple bitrates
                  AAC Audio @ 128Kbps
Machine           Multi-core Processor

为了保证每个码率下的视频质量,我们使用“medium”预设模式运行2-pass模式。

VIDEO_OPTIONS_P2 = -vcodec libx264 -preset medium -profile:v main -g 72 -keyint_min 24 -vf scale=720:-1,crop=720:400

最初的方法是使用并行进程对所有视频进行编码。

ffmpeg -y -i $INPUT_FILE $AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 250k -threads auto -f mp4 out-250.mp4 &
ffmpeg -y -i $INPUT_FILE $AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 500k -threads auto -f mp4 out-500.mp4 &
ffmpeg -y -i $INPUT_FILE $AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 700k -threads auto -f mp4 out-700.mp4 &

显然存在一些低效问题,即对于每个进程,源文件都会被读取、解码、缩放和裁剪。如何只进行一次这些操作,然后将结果提供给编码器呢?

希望通过在单个ffmpeg命令中生成所有编码来优化重复步骤。

ffmpeg -y -i $INPUT_FILE \
$AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 250k -threads auto -f mp4 out-250.mp4 \
$AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 500k -threads auto -f mp4 out-500.mp4 \
$AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 700k -threads auto -f mp4 out-700.mp4

然而,编码时间几乎与之前的多进程方法相同。这让我相信,所有步骤再次被重复执行。

为了强制ffmpeg只读取、解码和缩放一次,我将这些步骤放在一个ffmpeg进程中,并将结果传送到另一个ffmpeg进程中进行编码。这将整体处理时间提高了15%-20%。

INPUT_STREAM="ffmpeg -i $INPUT_FILE -vf scale=720:-1,crop=720:400 -threads auto -f yuv4mpegpipe -"

$INPUT_STREAM | ffmpeg -y -f yuv4mpegpipe -i - \
$AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 250k -threads auto out-250.mp4 \
$AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 500k -threads auto out-500.mp4 \
$AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2 -b:v 700k -threads auto out-700.mp4

有人看到用这种方法可能存在问题吗,或者知道更好的方法吗?


最近的ffmpeg已经默认使用libx264时应用了-threads auto选项,因此它已经变得多余。你所有的输入都将是1920x1080吗?为什么输出要720宽度?我没有看到你的音频选项。 - llogan
音频编码时间可以忽略不计,所以我没有提及它。我通过对音频进行一次编码,然后将结果混合到每个输出文件中来避免重复编码,从而获得了一些优化。步骤1:执行音频编码'ffmpeg -y -i $INPUT_FILE -acodec libvo_aacenc -ab 128000 -vn -threads auto out-aud.mp4'步骤2:将其混合到输出文件中'$AUDIO_OPTIONS_P2 = -i out-aud.mp4 -acodec copy' - Jonesy
2个回答

4
如果您将音频/视频选项应用于第一个进程的管道输出,则可以节省一些CPU,因为它会将三种编码交换为单个编码。
ffmpeg -i $INPUT_FILE -vf scale=720:-1,crop=720:400 $AUDIO_OPTIONS_P2 $VIDEO_OPTIONS_P2  -f yuv4mpegpipe -\
    | ffmpeg -y -f yuv4mpegpipe -i - \
          -b:v 250k out-250.mp4 \
          -b:v 500k out-500.mp4 \
          -b:v 700k out-700.mp4

这是旧版本ffmpeg的推荐方法。自本月早些时候以来,有一种较新的方法(未经测试)可用:http://ffmpeg.org/trac/ffmpeg/wiki/Creating%20multiple%20outputs。请注意保留HTML标记。

如何通过UDP输出?!不是out-250.mp4,out-500.mp4和out-700.mp4。 - Dr.jacky

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接