FFmpeg是一款强大的音视频处理的开源软件,既可以使用FFmpeg提供的Api对音视频进行处理,也可以使用它提供的工具来编辑音视频文件。
一、音视频处理基本流程
1、 输入文件,解封装拿到编码数据。
平时所看到的音视频文件,mp3、flv等,本身是一个容器。在这个容器中,存放着音视频数据。可以把这个容器 当作一个盒子。物品只有打包在盒子中,才能够方面运输。如果要对音视频做处理,只能先打开这个盒子(容器),拿到里面的编码数据。
2、 编码数据经过解码器解码之后产生未压缩的帧。
解封装之后的数据,是经过编码的数据,比较常见的视频编码有H264、H265。不同的编码格式,具有不同的压缩率。就像新型的H265编码,可以让视频文件在不损失画质的情况下,大大压缩文件体积。
通过解码器解码产生未压缩的帧数据,高度还原的原始数据。真正的原始数据是摄像头麦克风的采集数据。这里的数据和原始数据还是有差异的。
3、通过过滤对帧数据处理,完成音视频的编辑。
4、将帧数据通过编码器进行编码。
5、编码数据再封装成播放器可以认识的容器。
二、Mac系统上安装FFmpeg
// 下载FFmpeg
git clone https://git.ffmpeg.org/ffmpeg.git
// 进入ffmpeg目录
cd ffmpeg
// 执行配置命令
./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-nonfree --enable-libfdk-aac --enable-libx264 --enable-libx265 --enable-filter=delogo --enable-debug --disable-optimizations --enable-libspeex --enable-videotoolbox --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --cc=clang --host-cflags= --host-ldflags=
// 执行安装
sudo make && sudo make install
// 环境变量配置
vi ~/.bash_profile
// .bash_profile最后一行添加
export PATH=$PATH:/usr/local/ffmpeg/bin
// 环境变量配置文件生效
source ~/.bash_profile
如果在配置的时候出现错误,可能是缺少某些重要以来,根据报错提示,依次安装即可。
安装命令必须添加sudo
权限,否则报错该用户没有操作目录的权限。
如果在/usr/local/ffmpeg/bin
文件夹中没有ffplay
,表示ffplay
没有安装成功,可能是没有安装SDL2
库导致的,brew install ffplay
之后,重新执行配置、安装命令即可。
接下来,就可以使用ffmpeg
命令编辑音视频文件了。
三、FFmpeg常用命令
1. 基本信息查询命令
// 显示版本
ffmpeg -version
// 显示可用的格式
ffmpeg -formats
// 显示可用的解封装
ffmpeg -demuxers
// 显示可用的封装
ffmpeg -muxers
// 显示可用的设备
ffmpeg -devices
// 显示所有的编解码器
ffmpeg -codecs
// 显示所有的解码器
ffmpeg -decoders
// 显示所有的编码器
ffmpeg -encoders
// 显示所有的比特流filter
ffmpeg -bsfs
// 显示可用的协议
ffmpeg -protocols
// 显示可用的滤镜
ffmpeg -filters
// 显示可用的像素格式
ffmpeg -pix_fmts
// 显示可用的采样格式
ffmpeg -sample_fmts
// 显示可用的channel
ffmpeg -layouts
// 显示识别的颜色名称
ffmpeg -colors
2、音视频处理命令
音视频的处理命令,都是按照以下基本格式。
ffmpeg [global options] [input options] -i [input url] [output options] [output url]
全局参数:
参数 | 说明 |
---|---|
-y | 输出文件已存在,不再询问,覆盖输出文件 |
-n | 输出文件已存在,不再询问,直接退出程序 |
输入/输出通用参数
参数 | 说明 |
---|---|
-f | format,规定输入输出的文件格式。文件格式通常是从数据文件的数据和输出文件的后缀推断出来,所以大多数情况下不需要这个参数 |
-c:[v|a] | 等同于-[v|a]codec。选择一个编码器或者解码器,取决于在输入还是输出参数。视频编解码器为-c:v,音频编解码器为-c:a |
-t | 时长,单位s。输入参数中,限制文件输入时间。输出参数中,到达时间之后停止输出。如果输入参数中-t参数为3,输出参数中-t为5。输出的文件总时长为3s。 |
-ss | 起始时间,格式hh:mm:ss。输入参数中,文件输入起始位置。输出参数中,解码但丢弃输入,直到到达指定位置 |
-r | 帧率,Hz值分数或缩写,视频参数。输入参数中,忽略存储在文件中的任何时间戳,根据速率生成新的时间戳。输出参数中,复制或丢弃输入帧,以实现恒定输出帧频fps |
-s | 视频尺寸 |
-ar | 音频采样率,音频参数 |
-ac | 音频通道的数量 |
输出通用参数
参数 | 说明 |
---|---|
-vf | 视频过滤器 |
-af | 音频过滤器 |
-aspect | 视频宽高比,w:h或者宽高比1.777 |
-vn | 禁用视频 |
-an | 禁用音频 |
输入通用参数
参数 | 说明 |
---|---|
-filter | 创建由filgergraph指定的过滤器图,并使用它来过滤流 |
-aspect | 视频宽高比,w:h或者宽高比1.777。 |
录制:
// 查看都有哪些设备
ffmpeg -f avfoundation -list_devices true -i ""
// 录屏
ffmpeg -f avfoundation -i 1 -r 30 output.mp4
// 附带声音录屏
ffmpeg -f avfoundation -i 1:0 -r 29.97 -c:v libx264 -crf 0 -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k output.flv
// 录制视频
ffmpeg -framerate 30 -f avfoundation -i 0 output.mp4
// 附带声音录制视频
ffmpeg -framerate 30 -f avfoundation -i 0:0 output.mp4
// 录音
ffmpeg -f avfoundation -i :0 out.wav
- -f 指定使用avfoundation采集数据
- -i 指定从哪采集数据,从第一个命令中能查看到设备索引。录制音频和视频的时候,冒号前面代表视频索引,后面代表音频索引。
- -r 指定帧率
- -crf x264参数,0代表无损压缩。
分解与复用:
// 抽取音频流
ffmpeg -i input.mp4 -c:a copy -vn out.aac
// 抽取视频流
ffmpeg -i input.mp4 -an -c:v copy out.h264
// 转格式
ffmpeg -i input.mp4 -c:a copy -c:v copy out.m3u8
// 音视频合并
ffmpeg -i video.h264 -i sound.aac -c:v copy -c:a copy out.mp4
处理原始数据:
// 提取YUV数据
ffmpeg -i input.mp4 -c:v rawvideo -pixel_format yuv420p out.yuv
// YUV转h264
ffmpeg -f rawvideo -pix_fmt yuv420p -s 1280x720 -r 30 -i out.yuv -c:v libx264 -f rawvideo out.h264
// 提取PCM数据
ffmpeg -i input.mp4 -vn -ar 44100 -ac 2 -f s16le out.pcm
// PCM转WAV
ffmpeg -f s16le -ar 44100 -ac 2 -c:a pcm_s16le -i out.pcm output.wav
滤镜:
// 添加水印
ffmpeg -i input.mp4 -vf "movie=jianshu.png,scale=64*64[watermask];[in][watermask] overlay= 100:20 [out]" out.mp4
// 去水印
// 先通过ffplay找到需要删除的水印位置
ffplay -i out.mp4 -vf delogo=x=100:y=20:w=64:h=64:show=1
// 通过delogo删除水印
ffmpeg -i out.mp4 -vf delogo=x=100:y=20:w=64:h=64 nowater.mp4
// 视频缩小一倍
ffmpeg -i input.mp4 -vf scale=iw/2:-1 output.mp4
// 视频裁剪
ffmpeg -i input.mp4 -vf crop=iw/2:ih/2:0:0 -c:v libx264 -c:a copy output.mp4
// 倍速播放
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4
// 对称视频
ffmpeg -i input.mp4 -filter_complex "[0:v]pad=w=2*iw[a];[0:v]hflip[b];[a][b]overlay=x=w" output.mp4
// 画中画
ffmpeg -i input.mp4 -i input.mp4 -filter_complex "[1:v]scale=w=120:h=80:force_original_aspect_ratio=decrease[ckout];[0:v][ckout]overlay=x=W-w-10:y=0[out]" -map "[out]" -movflags faststart output.mp4
// 录制画中画
ffmpeg -f avfoundation -i "1" -framerate 30 -f avfoundation -i "0:0" -r 30 -c:v libx264 -preset ultrafast -c:a libfdk_aac -profile:a aac_he_v2 -ar 44100 -ac 2 -filter_complex "[1:v]scale=w=320:h=180:force_original_aspect_ratio=decrease[a];[0:v][a]overlay=x=W-w-100:y=H-h-100[out]" -map "[out]" output.mp4
// 音视频裁剪
ffmpeg -i input.mp4 -ss 00:00:10 -t 10 output.mp4
// 合并
// 创建一个包含视频列表的text文件
// input.txt
input.mp4
input.mp4
// 执行裁剪命令
ffmpeg -f concat -i input.txt -c:v copy -c:a copy output.mp4
// 视频转图片
ffmpeg -i input.mp4 -r 1 -f image2 image/%3d.jpg
// 视频转gif
ffmpeg -i input.mp4 -ss 00:00:05 -t 5 output.gif
// 图片转视频
ffmpeg -f image2 -i images/image-%3d.jpg output.mp4
直播相关:
// 推流
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://xxx
// 拉流保存
ffmpeg -i rtmp://xxx -c copy output.mp4
// 转流
ffmpeg -i rtmp://xxx -c copy -f flv rtmp://yyy
// 实时推送
ffmpeg -framerate 15 -f avfoundation -i "1" -s 1280*720 -c:v libx264 -f flv rtmp://xxx
网友评论