返回首页

FFmpeg 命令使用记录

FFmpeg 命令使用记录
  1. ffmpeg 处理音视频基本流程
  2. ffmpeg 信息查询
  3. ffmpeg 录制
  4. 文件格式转换(demuxer/muxer)
  5. 提取 yuv 或者 pcm 原始数据
  6. Filter
  7. 裁剪与合并
  8. 图片与视频转换

ffmpeg 是一个音视频相关操作的命令行工具,我日常在做一些文件转换的时候会用到,现在就顺带记录一下。

ffmpeg 处理音视频基本流程

下面是官方文档的处理大体流程

 _______              ______________
|       |            |              |
| input |  demuxer   | encoded data |   decoder
| file  | ---------> | packets      | -----+
|_______|            |______________|      |
                                           v
                                       _________
                                      |         |
                                      | decoded |
                                      | frames  |
                                      |_________|
 ________             ______________       |
|        |           |              |      |
| output | <-------- | encoded data | <----+
| file   |   muxer   | packets      |   encoder
|________|           |______________|

我们日常使用的 mp4,mp3 等文件作为输入输出文件。ffmpeg 将其进行类似解封装或者封装的操作,之后进行解码或者编码。当然如果只是修改外部封装格式,也可以不走解码编码直接进行 demuxer 和 muxer。

ffmpeg 信息查询

通过相关命令行参数查询相关的信息。

命令行参数 作用
-version 显示版本
-demuxers 显示可用 demuxer
-muxers 显示可用 muxer
-devices 显示可用设备
-codecs 显示所有编解码器
-decoders 显示可用解码器
-encoders 显示可用编码器
-bsfs 显示比特流 filter
-formats 显示可用格式
-protocoles 显示可用协议
-filters 显示可用过滤器
-pixfmts 显示可用像素格式
-samplefmts 显示可用的采样格式
-layouts 显示 channel 名称
-colors 显示识别的颜色名称

当需要查看当前 ffmpeg 是否支持某些编解码器等插件时可以使用这些来查看,一般的 Linux 发行版本通过包管理器安装的 ffmpeg 或者 windwos 版本的 exe 文件都不用担心这些问题。当 ffmpeg 是自己通过源码编译的时候可能因为编译选项或者依赖导致缺少一些东西。所以具体还是看情况吧。

ffmpeg 录制

在 Linux 上录制屏幕

ffmpeg -video_size 1024x768 -framerate 25 -f x11grab -i ${DISPLAY}+100,200 -f alsa -ac 2 -i hw:0 -t 30 -px_fmt yuv420p output.mkv

这里参数基本都是明写着的,`-videosize` 表示视频大小即分辨率,`-framerate` 表示帧率,-f 这里其实是 format 输入的格式,这里因为从设备获取相关数据,所以这里指定 x11grab 库抓取图像。`-i` 表示输入源,这里从 DISPLAY 中 100,200 位置读取图像数据,后面继续使用 alsa 库获取音频数据,`-ac` 代表使用双声道音频。 `-i` 表示输入设备。`-t` 表示录制 30s 的时间,`-pixfmts` 表示使用 yuv 的 420 格式存储数据,这个比较重要,这是最常用的格式。在之前的笔记里面说过具体的,最后 output.mkv 为输出文件。

整体上 ffmpeg 命令的用法就是如此,将需要的参数用命令行相应参数指定,最后 ffmpeg 捕获数据输入文件。 在 Linux 上使用 x11grab 获取图像数据,alsa 获取音频数据,在 Windwos 上可以使用 dshow 获取音视频(我记得好像是都可以),Mac 上使用 acfoundation 获取音视频数据。

这里插一句,除了命令行,Linux 下也有很好的录屏软件,比如 simplescreenrecorder。

文件格式转换(demuxer/muxer)

简单的格式转换,比如把 flv 格式转换为 mp4 格式

ffmpeg -i v1.flv -acodec copy -vcodec copy v1.mp4

单独将音频或者视频抽取,将对应的参数保留再将另一个设为 n 即可,下面是一个例子

# 抽取视频
ffmpeg -i v1.flv -an -vcodec copy v1.mp4
# 抽取音频
ffmpeg -i v1.flv -acodec copy -vn v1.aac

注意上面的参数顺序不能错

将 mp4 格式转换为 gif 图片(此处全部使用默认参数)

ffmpeg -i v1.mp4 v1.gif

提取 yuv 或者 pcm 原始数据

音视频文件原始数据格式为 yuv(视频) 或者 pcm(音频)。使用 ffmpeg 只提取视频原始数据。

ffmpeg -i v1.mp4 -an -c:v rawvideo -pix_fmts yuv420p v1.yuv

`-c:v` 用于指定视频编码器,要指定音频编码器可以用 `-c:a`

播放使用 ffplay

ffplay -video_size 1920x1080 v1.yuv

只提取 pcm 数据

ffmpeg -i v1.mp4 -vn -ar 44100 -ac 2 -f s16le out.pcm

`-ar` 表示采样率,`-ac` 则如同上面所述为声道数,`-f` 表示存储格式,`s16le` 中 `s` 表示有符号存储,`16` 表示 16 位存储,`le` 则表示小端存储。

播放 pcm 数据

ffplay -ar 44100 -ac 2 -f s16le out.pcm

综上所处,在提取处相关的原始数据之后,在播放时需要提供相关参数才能正常播放。

Filter

                [main]
input --> split ---------------------> overlay --> output
            |                             ^
            |[tmp]                  [flip]|
            +-----> crop --> vflip -------+

这个过滤图将输入流分成两个流,然后将其中一个流送过 crop 过滤器和 vflip 过滤器,然后将其与另一个流叠加在一起,再将其合并。(悄悄说一下,这一句直接翻译的官方文档)

简单命令

ffmpeg -i v1.mp4 -vf crop=in_w-500:in_h-500 -c:v libx264 -c:a copy v2.mp4

`-vf` 表示使用视频 filter。`inw` 表示视频宽度,`inh` 表示视频高度,这里分别减去 500

使用 ffmpeg 给视频添加水印(overlay)

ffmpeg -i vi.flv -i pic.png -filter_complex 'overlay=main_w-overlay_w-10:main_h-overlay_h-10'  -c:a copy -c:v libx264  output.mp4

overlay 参数后面表示在视频右下角距离 10 像素的位置放置 overlay 图像。具体参考文档(http://ffmpeg.org/ffmpeg-filters.html#overlay-1)

裁剪与合并

从视频开始剪裁视频 30s

ffmpeg -i v1.mp4 -ss 00:00:00 -t 30 output.mp4

删除视频中指定时间区域的视频

ffmpeg -i input.mp4 -vf "select='not(between(t,35,50))',setpts=N/FRAME_RATE/TB" -af "aselect='not(between(t,35,50))',asetpts=N/SR/TB" -c:v h264 -c:a aac -strict -2 output.mp4

这个命令解释如下

-i input.mp4: 指定输入视频文件的名称。

-vf "select='not(between(t,35,50))',setpts=N/FRAME_RATE/TB": 视频滤镜选项。select 滤镜用于选择视频帧,这里使用 not(between(t,35,50)) 表示不选择35秒到50秒之间的帧。setpts=N/FRAME_RATE/TB 用于重新计算时间戳。

-af "aselect='not(between(t,35,50))',asetpts=N/SR/TB": 音频滤镜选项。aselect 滤镜用于选择音频样本,这里使用 not(between(t,35,50)) 表示不选择35秒到50秒之间的样本。asetpts=N/SR/TB 用于重新计算时间戳。

-c:v h264: 指定视频编解码器为H.264。

-c:a aac: 指定音频编解码器为AAC。

-strict -2: 禁用严格性检查,允许使用一些实验性的编解码器。

output.mp4: 指定输出视频文件的名称。

这个命令的核心在于使用 select 和 aselect 滤镜来排除指定时间范围的视频和音频部分,然后使用 setpts 和 asetpts 来重新计算时间戳,最后使用指定的编码器保存输出视频文件。这样可以删除指定时间范围内的视频和音频。

音视频简单合并

ffmpeg -f concat -i videos.txt output.mp4

`videos.txt` 中记录了所有需要拼接文件的名字格式为:`file filename`。并且一个文件作为一行。这里 file 是直接写 file,filename 是具体文件名。 例如: file video1.mp4 file video2.mp4

图片与视频转换

视频转为图片

ffmpeg -i v1.mp4 -r 1 -f image2 image-%3d.jpeg

`-r` 表示帧率,即这里每一秒生成一张图片。使用格式为 image2,生成的文件名为 image-%3d.jpeg,%3d 将会生成长度为 3 为的数字,001 开始。

图片转换为视频

直接

ffmpeg -i image-%3d.jpeg out.mp4

评论 (...)

加载中...