ffmpeg
视频编码格式转换工具,也支持剪裁和滤镜。
常用参数
-i- 指定输入文件
-t- 转换的时长,以秒为单位,或者是
hh:mm:ss[.xxx] -ss- 指定开始时间
-to- 指定结束时间
-acodec, -vcodec- 音视频编码器,
copy表示复制 -f- 指定文件格式。默认会从文件扩展名猜测
-vn- 禁用视频部分
-rc_mode CQP -qp 28- (AVC/HEVC/AV1)使用CQP模式(Constant Quantization Parameter)编码。对于 1080p 原神游戏录制为 HEVC 编码,
-qp值 28 质量已经很不错了(平均码率 20Mbps 以上),32 细节会有些糊(平均码率约 12Mbps),36 则明显糊掉(平均码率约 7Mbps)[1][2] -hwaccel vaapi- 使用 VAAPI 进行解码加速
-movflags +faststart- 花额外的过程将 moov 写到文件开头,以便流式播放。
提取音频
ffmpeg -i fichier.flv -f mp3 -vn -acodec copy fichier.mp3
# 转换成 vorbis 音频编码的 OGG 文件。不指定编码时会使用 FLAC 编码
ffmpeg -i input.flv -vn -acodec vorbis -strict -2 out.ogg
注意有些时候转换出来的音频不正确。另见mencoder#提取音频。
格式转换
ffmpeg -i input.flv output.avi
ffmpeg -i a.flv -strict experimental -s 480x320 -r 25 -vcodec mpeg4 -acodec aac a.mp4
ffmpeg -i 可不可以不勇敢.mp3 -acodec libvorbis 可不可以不勇敢.ogg
使用选项-b:v 1000k来控制输出视频的比特率为1000k。不指定该参数可能输出的质量会很差。
opus 转 vorbis
parallel --bar ffmpeg -loglevel warning -i "{}" -c:a libvorbis -aq 4 "{.}.ogg" ::: */*.opus
使用 VAAPI 加速转码
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i input.mp4 -c:v h264_vaapi output.mp4
vp9 编码
两步平均码率编码[6]。使用 -row-mt 来利用多核[7]。
ffmpeg -hwaccel vaapi -i input.mp4 -c:v libvpx-vp9 -b:v 512K -row-mt 1 -pass 1 -an -f null /dev/null && \
ffmpeg -hwaccel vaapi -i input.mp4 -c:v libvpx-vp9 -b:v 512K -row-mt 1 -pass 2 -c:a libopus -b:a 128K output.webm
SVT-AV1
ffmpeg -hwaccel vaapi -i input.mkv -vcodec libsvtav1 -crf 35 -preset 6 -svtav1-params tune=0 out.mp4
默认是 -crf 35 -preset 10 -svtav1-params tune=1。相比于默认的 CRF 会降低快速变化的内容质量,CQP 更适合需要慢速回放的场景(如游戏录屏)。
对于 1080p 原神游戏录屏,CQP -qp 28码率约 21Mbps。32(码率约 16Mbps)相当不错,并且与28质量非常接近,文件大小却减小了 30%。36(码率约 12Mbps)效果稍差。40(码率约 9Mbps)稍有模糊。存档建议32,分享可以40或以上。
色域扩张
scale_vaapi不小心忘记加:out_range=full时的修复方案:
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -init_hw_device vaapi=mydev -filter_hw_device mydev -i input.mp4 -filter:v hwdownload,format=nv12,scale=in_range=limited:out_range=full,hwupload -acodec copy -vcodec hevc_vaapi -rc_mode CQP -qp 30 output.mp4
与图片序列相互转换
ffmpeg -i out.ogv out/%03d.png
ffmpeg [-framerate 25] -i %02d.png -vb 20M a.ogv
# -vf 用于解决长宽不是2的倍数的问题
ffmpeg -r 10 -i sevp_%02d.jpg -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" a.mp4
注意:转换图像序列时,图像文件名一定要从 1 开始,并且按格式要求有前导的 0。
视频截取
截取前 118 秒:
ffmpeg -i 128115989931hd_clear-1.flv -acodec copy -vcodec copy -t 118 a.flv
截取指定时间区间:
ffmpeg -i Frozen.2013.720p.HDRip.XviD.AC3-RARBG.avi -acodec copy -vcodec copy -ss 30:58 -to 34:46 'Let It Go.avi'
媒体合并
ffmpeg -i "concat:$HOME/a.mp3|$HOME/b.mp3" c.ogg
# or, using a list
ffmpeg -f concat -i <(echo -e "file $HOME/a.mp3\nfile $HOME/b.mp3") c.ogg
文件名中如有单引号需要在单引号字符串外使用反斜线转义,即变为'\''[10][11]
录制桌面
x11
ffmpeg -f x11grab -s wxga -r 25 -i :0.0 /tmp/out.mpg
-f x11grabmakes ffmpeg to set the input video format asx11grab. The X11 framebuffer has a specific format it presents data in and it makes ffmpeg to decode it correctly.-s wxgamakes ffmpeg to set the size of the video to wxga which is shortcut for 1366x768. This is a strange resolution to use, I'd just write -s 800x600.-r 25sets the framerate of the video to 25fps.-i :0.0sets the video input file to X11 display 0.0 at localhost.
录制成 webm 或者 ogv,指定比特率:
ffmpeg -f x11grab -s wxga -r 15 -i :0.0 -b:v 10000k t.webm
指定录制的区域:[14]
ffmpeg -f x11grab -follow_mouse 200 -r 25 -s 1366x768 -i :0.0 -f alsa -i hw:0 -vcodec libx264 test.mp4
kmsgrab
截图:
sudo ffmpeg -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,hwdownload,format=bgr0' -frames 1 a.png
sudo ffmpeg -f kmsgrab -device /dev/dri/card1 -i - -vf 'hwmap=derive_device=vaapi,hwdownload,format=nv12' -frames 1 b.png
录制桌面:[15]
sudo ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,scale_vaapi=w=1920:h=1080:format=nv12' -c:v h264_vaapi -rc_mode CQP -qp 28 a.mp4
录像
ffmpeg -f alsa -ac 2 -i default -f video4linux2 -i /dev/video0 -f mp4 -strict -2 a.mp4
注意:使用其它参数可能会有音视频不同步、进程卡住等问题。
v4l2loopback 数据源
从 Android 手机通过 IP Webcam 获取视频,然后交给 v4l2loopback:
ffmpeg -fflags nobuffer -i http://PHONE_IP:8080/video -f v4l2 -vcodec rawvideo -pix_fmt yuv420p /dev/video2
视频剪裁+音频替换
-ss 需要在 -i 前以定位输入流[16]。无法直接使用 vaapi 剪裁视频。使用 -f lavfi -i anullsrc -acodec aac 生成静音流并替换。
ffmpeg -hwaccel vaapi \
-ss 1 -to 7 \
-i input.mkv \
-f lavfi -i anullsrc -acodec aac \
-shortest -map 0:v:0 -map 1:a:0 \
-filter:v "crop=540:540:1380:540" -vcodec h264 -rc_mode CQP -qp 28 \
out.mp4
使用 CPU 剪裁但是使用 vaapi 编码:
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi \
-ss 1 -to 7 \
-i input.mkv \
-f lavfi -i anullsrc -acodec aac \
-shortest -map 0:v:0 -map 1:a:0 \
-filter:v "hwdownload,crop=540:540:1380:540,format=nv12,hwupload" -vcodec h264_vaapi -rc_mode CQP -qp 28 \
out.mp4
剪裁的参数顺序为 w:h:x:y,也可以使用命名参数。[17]
多段剪裁
使用-filter_complex应用多个trim和atrim过滤器:
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i test-vaapi.mkv -filter_complex '
[0:v]trim=start=0:end=2\\:03.357,setpts=PTS-STARTPTS[v0];
[0:a]atrim=start=0:end=2\\:03.357,asetpts=PTS-STARTPTS[a0];
[0:v]trim=start=3\\:44.881:end=5\\:39.690,setpts=PTS-STARTPTS[v1];
[0:a]atrim=start=3\\:44.881:end=5\\:39.690,asetpts=PTS-STARTPTS[a1];
[0:v]trim=start=7\\:20.714,setpts=PTS-STARTPTS[v2];
[0:a]atrim=start=7\\:20.714,asetpts=PTS-STARTPTS[a2];
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa];
[outv]scale_vaapi=w=1920:h=1080:format=nv12[outv2]' -map "[outv2]" -map "[outa]" -vcodec hevc_vaapi -rc_mode CQP -qp 28 out.mp4
当有多个视频作为输入时,需要在每个setpts之后添加,hwupload以避免格式不匹配的问题。
视频打码
马赛克效果:第一个crop是要剪裁的区域。第二个crop是要打码的区域(在剪裁之后的坐标),overlay是打码的起始坐标。[18]
-filter_complex "[0:v]hwdownload,crop=1920:934:0:146,format=nv12,split[main][mask];[mask]crop=320:850:850:74,scale=iw/10:-1,scale=iw*10:-1:flags=neighbor[mos];[main][mos]overlay=850:74,hwupload"
添加字幕
以下命令将三份不同语种的字幕添加到视频,并延迟120ms:
ffmpeg -i input.webm \
-itsoffset 0.120 -i both.ass \
-itsoffset 0.120 -i ja.ass \
-itsoffset 0.120 -i zh_CN.ass \
-c copy -map 0:v:0 -map 0:a:0 \
-map 1:0 -metadata:s:a:0 language=jpn -metadata:s:s:0 title='简体中文+日文' \
-map 2:0 -metadata:s:s:1 language=jpn -metadata:s:s:1 title=Japanese \
-map 3:0 -metadata:s:s:2 language=zho -metadata:s:s:2 title='Chinese (Simplified)' \
out.mkv
注意只有 mkv 格式同时支持 vp9、opus 和 ass。而 ass 支持指定字体(ffmpeg 不支持 webm 所支持的 webvtt 之样式设置)。[19]
音频叠加
将音频叠加到现有视频的音频部分(短的延长,视频不够长的话会静止显示最后的画面)[20],同时做了视频压缩。
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i a.mp4 -i b.mp3 -filter_complex amix=inputs=2:duration=longest -vcodec hevc_vaapi -rc_mode CQP -qp 32 out.mp4
元数据
读取:[21]
ffmpeg -loglevel error -i FILE -f ffmetadata -
写入(与原文件中者合并):
ffmpeg -loglevel error -i FILE -i META_FILE -map_metadata 1 -codec copy OUTPUT
-map_metadata 0:s参数才能读到音频元数据。相关程序
- ffplay
- ffprobe
参见
外部链接
- Brilliant Place: 无损合并视频的多种方法
- Brilliant Place: Linux下流畅地录屏
- A FFmpeg Tutorial For Beginners已失效,存档
- ffmpeg使用说明 | Chronos
- Mixing speaker and slides recording with FFmpeg - Filippo.io
- 如何使用 FFmpeg 进行视频转码:首页 - FiveYellowMice's Wiki
- FancyFilteringExamples – FFmpeg
版权相关
参考资料
- ↑ 视频编码-码率控制CQP/CRF/ABR/CBR/VBV - 简书
- ↑ QSV対応ffmpegでエンコードー最適パラメータ設定 - Simple Life in the digital age
- ↑ Convertir .flv en .mp3 sous ubuntu [Résolu]
- ↑ Encode/HighQualityAudio – FFmpeg
- ↑ Hardware/VAAPI – FFmpeg
- ↑ Encode/VP9 – FFmpeg
- ↑ ffmpeg - VP9 encoding limited to 4 threads? - Stack Overflow
- ↑ AV1 quick encode with SVT-AV1
- ↑ How to concatenate (join, merge) media files – FFmpeg
- ↑ FFmpeg Utilities Documentation
- ↑ Filename quoting in ffmpeg concat - Super User
- ↑ LinuxTop: 10 个最酷的 Linux 单行命令
- ↑ Top Ten One-Liners from CommandLineFu Explained
- ↑ openSUSE 中文 • 查看主题 - 有没有什么视频录制软件推荐?
- ↑ kmsgrab - FFmpeg
- ↑ Seeking – FFmpeg
- ↑ [1]
- ↑ Gemini - FFmpeg 视频区域打码方法
- ↑ wikipedia:Comparison of video container formats
- ↑ How to overlay/downmix two audio files using ffmpeg - Stack Overflow
- ↑ FFmpeg Formats Documentation