目标是从单个源文件创建多个仅比特率不同的输出文件。已经记录的解决方案有效,但存在一些效率问题。我发现最有效的解决方案似乎没有被任何人记录过。在此发布并请求审查,同时询问其他人是否知道可以进行的其他优化。
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
有人看到用这种方法可能存在问题吗,或者知道更好的方法吗?
-threads auto
选项,因此它已经变得多余。你所有的输入都将是1920x1080吗?为什么输出要720宽度?我没有看到你的音频选项。 - llogan