百科

[!IMPORTANT]

如果用 svtav1 编码器请使用最新版ffmpeg,因为真的新版速度更快,快得多。 使用 github 新版速度是 apt 默认安装速度的 1.2 倍。

容器格式

格式 备注
MP4 推荐也不推荐,推荐是因为应用非常广泛,老设备支持广泛;不推荐是因为改元数据得完全重写一遍文件。
MKV 啥都能装,缺点是老设备可能不太支持
Webm 只推荐插入在网页中使用
FLV 好多年没见了
RMVB 好多年没见了

视频编码格式

[!NOTE]

关于付费:商用,也就是各大视频网站之类的需要付费,个人使用当然没人管啦。

格式 时间 授权 别名 说明
H.264 2003 付费 MPEG-4 Part 10 / Advanced Video Coding / AVC / 高级视频编码 目前广泛使用的格式
H.265 2013 付费 MPEG-H Part 2 / High Efficiency Video Coding / HEVC / 高效率视频编码 H.264 继任者,编码效率几乎翻倍,推广中
H.266 2020 付费 MPEG-I Part 3 / Versatile Video Coding / VVC / 多功能视频编码 H.265 继任者,还没什么人用,至少我本人还没见过对应片源
VP9 2012 免费 谷歌开发,AV1 前身
AV1 2018 免费 AOMedia Video 1 VP9 继任者,推广中,效率与 H.265 接近,不如 H.265 出名

音频编码格式

格式 全称 无损 时间 备注
MP3 MPEG-2 Audio Layer III 有损 1995 一般不用
aac Advanced Audio Coding / MPEG-4 Part 3 有损 1997 现在各大视频网站,视频转码等一般都用这个
alac Apple Lossless Audio Codec 无损 2004 很少用,偏大
flac Free Lossless Audio Codec 无损 2001 有些人压制用,偏大
DTS Digital Theater Systems 1993 原片一般用这个
AC-3 Dolby Digital 1986 原片也可能有这个

电视广播制式

电视广播制式主要分为 PALNTSC

除了北美、东亚部分地区使用 NTSC 制式,中东、法国及东欧采用 SECAM 制式以外,世界上大部分地区都是采用 PAL 制式。

中国、香港、英国:PAL

台湾、韩国、日本、美国:NTSC

PAL 主要参数:576i (720x576) 29.97FPS 1080i (1920x1080)

说明:虽然 576i 分辨率是 720x576=5:4,但是显示比例通常为 4:3

NSTC 主要参数:480i(640x480) 60FPS 59.94FPS(日本)

所以,如果是国产和香港老电视剧,理论上应该都是576i,其它分辨率、比例的片源大概都是根据某些需求重编码的。4k的老剧我选择压回576i,假4k也没意义。

视频编码

youtube的直播视频编码建议

提取分辨率/帧速率 针对 AV1 和 H.265 的最小码率设置 (Mbps) 针对 AV1 和 H.265 的最大码率设置 (Mbps) 针对 H.264 的建议码率设置 (Mbps)
4K/2160p @60fps 10 Mbps 40 Mbps 35 Mbps
4K/2160p @30fps 8 Mbps 35 Mbps 30 Mbps
1440p @60fps 6 Mbps 30 Mbps 24 Mbps
1440p @30fps 5 Mbps 25 Mbps 15 Mbps
1080p @60fps 4 Mbps 10 Mbps 12 Mbps
1080p @30fps 3 Mbps 8 Mbps 10 Mbps
720p @60fps 3 Mbps 8 Mbps 6 Mbps
240p - 720p @30fps 3 Mbps 8 Mbps 4 Mbps

youtube的直播视频编码器设置

协议: RTMP/RTMPS 流式传输
视频编解码器: H.264 / H.265 (HEVC)(推荐)/ AV1(推荐)
帧速率: 最高 60 fps
关键帧频率: 建议为 2 秒,不超过 4 秒
音频编解码器: AAC 或 MP3,(RTMP/RTMPS 仅支持 AAC 格式的 5.1 环绕声音频)
码率编码方式: CBR

AV1 编码

编码器

  • libaom-av1 (速度非常非常慢,0.0x 吧,如果不是有超高性能服务器或永生者,则不建议考虑)
  • libsvtav1(Intel,速度正常,libx265 差不多吧)
  • rav1e (没用过,不太流行)
  • dav1d (没用过,不太流行)
  • libgav1 (Google, 没用过,不太流行)
  • ......还有好几个,更不流行

[!IMPORTANT]

H.264 H.265 AV1 等是编码标准,libx264 libx265 libaom-av1 libsvtav1 等是具体的实现方式。

CRF 最低 我的选择 默认 最高
x.264 0 18 19 23 51
x.265 0 22 23 28 51
svtav1 0 20(细节丰富)24(细节不多)28(576i) 26 35 63

基于以上 crf 选择,对于 1080p,如果码率远大于3M,微调到3M码率左右的crf

对于4k,如果码率远大于8M,微调到8k码率左右crf

  • -c:v 指定编码器
  • -crf 指定编码质量
  • -preset 指定预设质量
  • -g 关键帧组的大小,通常为1-5倍整数帧率,最直观的表现就是快进时有时不能快进到想到的点,因为只能快进到最近的关键帧。
  • -pix_fmt yuv420p10le 使用10bit,即使是8bit视频,质量更好。
  • -c:a 指定音频编码格式,copy为直接复制,因为音频通常只占文件百分之几,所以没必要编码省那么点。
ffmpeg \
	-i "输入文件.mp4" \
	-c:v "libsvtav1" \
	-crf "24" \
	-preset "6" \
	-g 30 \
	-pix_fmt yuv420p10le \
	-c:a copy \
	"输出文件.mkv"

音频编码

因为音频流通常很小,占比很小,所以通常直接复制,不编码。编码的话推荐 -q:a 2.0。

-q:a 值 预期码率范围(kbps) 0.1 ~64kbps 0.5 ~96kbps 1.0 ~128kbps 1.5 ~160-192kbps 2.0 ~256kbps

画质比对

人眼比对

video-compare:该工具会在鼠标线两侧同步播放两个视频,通过移动鼠标可实时观测两边差别。

数据比对

WMAF视频多方法评估融合 (Video Multimethod Assessment Fusion),是 Netflix 和 几所大学共同开发的客观的全参考视频质量指标。

[!NOTE]

debian apt 安装的默认不带该编码器

ffmpeg -i '原始视频.mp4' -i '编码视频.mp4' -lavfi libvmaf -f null -

比对视频比编码视频更慢,也可以考虑对比对应帧

在 potplayer 里按 G 输入时间戳定位到相同位置截图

ffmpeg -loop 1 -t 1 -i '原始帧.png' \
	   -loop 1 -t 1 -i '编码帧.png' \
	   -filter_complex "[0:v]format=yuv420p[ref];[1:v]format=yuv420p[dist];[ref][dist]libvmaf" \
	   -f null -

执行结果中会有一句

VMAF score: 87.961308e=N/A speed=0.308x elapsed=0:00:02.59

score 值就是相似度

通常认为

90 以上为优秀

95 以上人眼难以察觉

99 以上如假包换

MSU Video Quality Measurement Tool:一个 windwos 下的质量检测工具,甚至可以生成差异度视频。

Linux处理脚本

一个自写的 ffmpeg bash 脚本,转码指定文件夹下的所有视频文件。

用法

bash run.sh -i '/mnt/media'

bash run.sh # 查看帮助信息
#!/bin/bash

set -e

# 用法说明
help_str=$(cat <<-EOF
	说明:该脚本转码指定文件夹下的所有视频文件
	
	用法: $0 [选项]
	    -i, --input DIR       输入目录          [必选]
	    -o, --output DIR      输出目录          [默认:输入目录/output]
	    -c, --codec CODEC     视频编码器        [默认:libsvtav1]
	    -q, --crf VALUE       CRF 值            [默认:24]
	    -g, --gopx VALUE      GOP 倍率          [默认:2]
	    -p, --preset VALUE    预设质量          [默认:6]
	    -e, --ext SUFFIX      输出文件格式      [默认:mkv]
	    -h, --help            显示此帮助信息
EOF
)

function timed_echo() {
	local timestamp
	timestamp=$(date '+%Y-%m-%d %H:%M:%S')
	echo -e "[$timestamp] $*"
}


# ------------------------------
# 支持格式字典(key=扩展名,value=1)
# ------------------------------
declare -A video_formats=(
	["mp4"]=1
	["mpg"]=1
	["mkv"]=1
	["avi"]=1
	["mov"]=1
	["flv"]=1
	["wmv"]=1
	["webm"]=1
	["m4v"]=1
)

# ------------------------------
# 默认参数
# ------------------------------
input_dir=""
output_dir=""
ext="mkv"
vcodec="libsvtav1"
crf="24"
gopx="1"
preset="6"
# ------------------------------
# 没有任何参数就显示用法
# ------------------------------
[ $# -eq 0 ] && echo -e "$help_str" && exit 1;

# ------------------------------
# 参数解析
# ------------------------------
ARGS=$(getopt \
	-o i:o:c:q:g:e:h \
	-l input:,output:,codec:,crf:,gopx:,ext:,help \
	-n "$0" \
	-- "$@")
[ $? != 0 ] && echo -e "$help_str" && exit 1;

eval set -- "$ARGS"

while true; do
	case "$1" in
		-i|--input)
			input_dir="$2";		shift 2;;
		-o|--output)
			output_dir="$2";	shift 2;;
		-c|--codec)
			vcodec="$2";		shift 2;;
		-q|--crf)
			crf="$2";			shift 2;;
		-g|--gopx)
			gopx="$2";			shift 2;;
		-p|--preset)
			$preset="$2";		shift 2;;
		-e|--ext)
			ext="$2";			shift 2;;
		-h|--help)
			usage;;
		-h | --help)
			echo -e "$help_str"; exit  0;;
		--)
			shift; break;;
		*)
			echo "未知选项: $1"; usage;;
	esac
done

# ------------------------------
# 绝对路径处理
# ------------------------------
input_dir="$(realpath "$input_dir")"

if [ -z "$output_dir" ]; then
	output_dir="$input_dir/output"
fi

output_dir="$(realpath -m "$output_dir")"

echo -e "\e[32m[输入目录] $input_dir\e[0m"
echo -e "\e[32m[输出目录] $output_dir\e[0m"
echo -e "\e[32m[视频编码] $vcodec\e[0m"
echo -e "\e[32m[编码质量] $crf\e[0m"
echo -e "\e[32m[GOP 倍率] $gopx\e[0m"
echo -e "\e[32m[预设质量] 6\e[0m"
echo -e "\e[32m[输出后缀] $output_ext\e[0m"

# ------------------------------
# 遍历目录下所有文件,判断格式是否支持
# ------------------------------
for input in "$input_dir"/*; do
	[ -e "$input" ] || continue

	# 获取文件扩展名,转换为小写
	file_ext="${input##*.}"
	file_ext="${file_ext,,}"

	if [[ -z "${video_formats[$file_ext]}" ]]; then
		# 不支持格式,跳过
		continue
	fi
	
	
	
	[ ! -d "$output_dir" ]  && mkdir -p "$output_dir"

	fps=$(ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate "$input" | bc)
	if ! [[ $fps =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
		echo "无法解析帧率: $fps"
		exit 1
	fi
	fps_int=$(awk "BEGIN {print int($fps + 0.5)}")
	gop=$(( fps_int * gopx ))
	if [ "$gop" -lt 10 ] || [ "$gop" -gt 300 ]; then
		echo "警告:自动计算的 GOP=$gop 可能不合理"
	fi
	filename=$(basename "$input")
	base="${filename%.*}"
	output="$output_dir/${base}.${ext}"
	output_tmp="$output_dir/${base}.tmp.${ext}"

	# 存在则跳过
	if [ -f "$output" ]; then
		timed_echo "\e[33m[已存在,跳过] $output\e[0m"
		continue
	fi

	# 删除旧的临时文件
	[ -f "$output_tmp" ] && rm -f "$output_tmp"

	timed_echo "\e[32m[开始编码] $input\e[0m"
	start_time=$(date +%s)

	ffmpeg \
		-i "$input" \
		-c:v "$vcodec" \
		-crf "$crf" \
		-preset "$preset" \
		-g 30 \
		-r 29.97 \
		-pix_fmt yuv420p10le \
		-c:a copy \
		"$output_tmp"

	# v video 视频
	# a audio 音频
	# s subtitle 字幕
	# d data  额外数据 如封面

	end_time=$(date +%s)
	duration=$(( end_time - start_time ))
	minutes=$(( duration / 60 ))
	seconds=$(( duration % 60 ))

	mv "$output_tmp" "$output"

	timed_echo "\e[32m[完成编码] [${minutes}分${seconds}秒] $output\e[0m"
done

合并视频

ffmpeg -f concat -safe 0 -i <(printf "file 'part1.mp4'\nfile 'part2.mp4'\n") -c copy output.mp4

经验

  • 如果那类影片帧率为59.94,那么通常能找到4k片源
  • 帧率为59.94帧的1080P影片通常也更清晰,原因是片源是真4k,所以1080p的视频不太清晰,是因为确实本身就是1080p标准。

mp4添加封面

ffmpeg -i input.mp4 -i cover.jpg -map 0 -map 1 -c copy -disposition:v:1 attached_pic output.mp4

其它

It is recommended to not use Film Grain for presets greater than 6 as it produces a significant compute overhead. This combination should only be used for debug purposes
Setting preset to M9 as it is the highest supported preset for 4k and higher resolutions in Random Access mode

x265文档

https://x265.readthedocs.io/en/stable/cli.html#quantization-options

svt-av1文档

https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/CommonQuestions.md#gop-size-selection

比较 SVT-AV1 预设:大小、质量和速度与 CRF 变化

https://ottverse.com/analysis-of-svt-av1-presets-and-crf-values/

AV1 文档

https://trac.ffmpeg.org/wiki/Encode/AV1