FFmpeg自动化2次编码方案:CRF首转后用首转平均码率再转可行吗?
FFmpeg自动化二次编码优化码率分配方案
你的场景是通过CRF 22保证恒定画质,但单遍编码的maxrate设置偏高导致码率冗余,手动调整maxrate后能在画质不变的前提下降低平均码率。以下是可自动化实现的二次编码方案:
核心思路
首次以CRF模式编码并统计实际平均码率,二次编码时将该平均码率设为新的maxrate,让码率分配更贴合影片实际需求,消除冗余。
步骤1:首次编码并统计平均码率
无需生成完整编码文件,用FFmpeg的空输出模式仅分析编码过程,提取日志中的平均码率:
ffmpeg -i input.mp4 -c:v libx264 -vf format=yuv420p,scale=1280:-2 -crf 22 -maxrate 1400k -bufsize 7000k -f null - 2>&1 | grep "bitrate:" | awk '{print $6}' > avg_bitrate.txt
- 若日志中
bitrate字段的位置不同,可调整awk的$6参数(比如部分环境为$5)。 - 也可先生成临时编码文件,再用
ffprobe提取平均码率,结果更准确:ffmpeg -i input.mp4 -c:v libx264 -vf format=yuv420p,scale=1280:-2 -crf 22 -maxrate 1400k -bufsize 7000k temp.mp4 ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 temp.mp4 | awk '{print int($1/1000)"k"}' > avg_bitrate.txt
步骤2:读取码率并执行二次编码
通过脚本自动读取统计的平均码率,完成二次编码:
Linux/macOS 脚本示例
#!/bin/bash # 统计平均码率 ffmpeg -i input.mp4 -c:v libx264 -vf format=yuv420p,scale=1280:-2 -crf 22 -maxrate 1400k -bufsize 7000k -f null - 2>&1 | grep "bitrate:" | awk '{print $6}' > avg_bitrate.txt # 提取纯数字码率(去掉k后缀) AVG_BITRATE=$(cat avg_bitrate.txt | sed 's/k//') # 二次编码:maxrate设为平均码率,bufsize保持5倍比例 ffmpeg -i input.mp4 -c:v libx264 -vf format=yuv420p,scale=1280:-2 -crf 22 -maxrate ${AVG_BITRATE}k -bufsize $((AVG_BITRATE*5))k output.mp4
Windows 批处理示例
@echo off :: 统计平均码率到日志文件 ffmpeg -i input.mp4 -c:v libx264 -vf format=yuv420p,scale=1280:-2 -crf 22 -maxrate 1400k -bufsize 7000k -f null - 2> log.txt :: 提取平均码率并去掉k后缀 for /f "tokens=6 delims= " %%a in ('findstr "bitrate:" log.txt') do set AVG_BITRATE=%%a set AVG_BITRATE=%AVG_BITRATE:k=% :: 执行二次编码 ffmpeg -i input.mp4 -c:v libx264 -vf format=yuv420p,scale=1280:-2 -crf 22 -maxrate %AVG_BITRATE%k -bufsize %AVG_BITRATE%5k output.mp4
注意事项
- bufsize保持maxrate的5倍比例(和你原参数的比例一致),可保证码率控制的平滑性。
- 若影片存在大量高动态场景,可适当将二次编码的maxrate在平均码率基础上提升10%-15%,避免画质损失。
内容的提问来源于stack exchange,提问作者Alireza Rinan
相关产品推荐
相关产品推荐

