目标是创建多个输出文件,这些输出文件仅在比特率上与单个源文件不同。记录在案的解决方案有效,但效率低下。我发现最有效的解决方案没有记录在我能看到的任何地方。我将其发布在这里以供审查,并询问其他人是否知道可以进行的其他优化。
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
每个比特率的视频质量很重要,因此我们在 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
有没有人看到这样做的潜在问题,或者知道更好的方法?