[视频] FFMpeg 基本组成和入门示例

FFmpeg基本组成

  • AVFormat
    封装了大多数媒体格式:如MP4、FLV等文件格式,RTMP、RTSP、MMS、HLS等网络协议。

  • AVCodec
    支持常见编解码格式:MPEG4、AAC等。支持第三方:

    • H.263(AVC)->需x264编码器;
    • H265(HEVC)->需x265编码器;
    • MP3(mp3lame)->需libmp3lame编码器;
  • AVFilter
    通用滤镜处理框架。可以有多个输入和多个输出。

ffmpeg -i 1.jpg -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip];[main][flip] overlay=0:H/2" 2.jpg

说明:

  1. 相同的Filter线性链之间用逗号分隔
  2. 不同的Filter线性链之间用分号分隔
  3. 方括号[]括起来的部分是标签
  4. 上面的命令行,图片换成视频也可以正常转换,比如 1.jpg 改为 1.mp4, 2.jpg 改为 2.mp4
  • AVDevice

  • AVUtil

  • swresample
    音频转换计算模块

  • swscale
    视频图像转换计算模块

编解码工具 ffmpeg.exe

ffmpeg -i 1.mp4 2.avi
  • -i 参数将1.mp4作为输入源
  • mp4和avi是两种文件封装格式,但不是后缀名就可以决定的。
ffmpeg -i 1.mp4 -f avi 2.dat
  • -f进行约束,指定了输出文件的容器格式,其过程和上一个命令一样,仅仅输出的文件名不同。

ffmpeg.exe的工作流程

  1. ffmpeg读取输入源文件
  2. 将音视频包Demuxer(解封装),调用libavformat中的接口即可
  3. Decoder(解码)每一帧音视频数据,成为YVU或者PCM这样的数据,通过libavcodec中的接口即可
  4. 转换参数
  5. Encoder(编码)对应数据,依然通过libavcodec中的接口来实现
  6. 然后通过libavformat中的接口进行Muxer(封装)
  7. 输出到目标,文件或数据流

可以通过下面的命令查看默认支持格式

ffmpeg -formats

查看支持的编解码情况

ffmpeg -codecs
ffmpeg -encoders
ffmpeg -decoders

Decoders:
 V..... = Video
 A..... = Audio
 S..... = Subtitle
 .F.... = Frame-level multithreading
 ..S... = Slice-level multithreading
 ...X.. = Codec is experimental
 ....B. = Supports draw_horiz_band
 .....D = Supports direct rendering method 1

输出信息的第一列包含6个字段:

  1. 表示这个编码器是视频、音频还是字幕;
  2. 表示帧级别的多线程支持;
  3. 表示分片级别的多线程支持;
  4. 表示为试验版本;
  5. draw_horiz_band模式支持;这是一个数据结构;
  6. 直接渲染模式支持;

查看支持哪些滤镜

ffmpeg -filters

查看flv解封装器的参数支持

ffmpeg -h demuxer=flv

查看H.264的编码器的参数支持

ffmpeg -h encoder=h264

查看过滤器的参数支持

ffmpeg -h filter=colorkey

播放器 ffplay.exe

这个一般我们用来做测试工具

多媒体分析器 ffprobe

ffprobe -show_streams 1.mp4

附加示例

改变格式

ffmpeg -i 2.avi -vcodec mpeg4 -b:v 200k -r 15 -an 15.mp4

说明:

  • 参数b为音频和视频的码率,可以认为是两者加起来的码率。默认200kbit/s
    可以工具b:v设置视频码率,b:a设置音频码率
  • 参数r为视频帧率fps
  • 参数an,转码后的文件不包括音频

改变分辨率

ffmpeg -i 1.mp4 -vf scale=320:240 2.mp4

拼接视频

  1. 对于 MPEG 格式的视频,可以直接连接:
//视频尺寸要一致
ffmpeg -i concat:"1.mpg|2.mpg|3.mpg" -c copy output.mp4
  1. 对于非 MPEG 格式容器,但是是 MPEG 编码器(H.264、DivX、XviD、MPEG4、MPEG2、AAC、MP2、MP3 等),可以包装进 TS 格式的容器再合并。在新浪视频,有很多视频使用 H.264 编码器,可以采用这个方法(视频尺寸可以不一致)

ts全称为MPEG2-TS。ts即"Transport Stream"的缩写。MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的。

ffmpeg -i 1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts 1.ts
ffmpeg -i 2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts 2.ts
ffmpeg -i 3.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts 3.ts
ffmpeg -i "concat:1.ts|2.ts|3.ts" -c copy -bsf:a aac_adtstoasc -movflags +faststart ts.mp

保存 QuickTime/MP4 格式容器的时候,建议加上 -movflags +faststart。这样分享文件给别人的时候可以边下边看。

  1. FFmpeg concat 分离器
    这种方法成功率很高,也是最好的,但是需要 FFmpeg 1.1 以上版本。先创建一个文本文件filelist.txt:
file 'input1.mkv'
file 'input2.mkv'
file 'input3.mkv'
ffmpeg -f concat -i filelist.txt -c copy output.mkv

注意:使用 FFmpeg concat 分离器时,如果文件名有奇怪的字符,要在 filelist.txt 中转义

测试了一下,不同尺寸的视频可以正常合成,但是不同格式的合成有问题

  1. 使用concat滤镜(filter)进行视频文件的合并:
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex '[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] concat=n=3:v=1:a=1 [v] [a]' -map '[v]' -map '[a]’  output.mp4

上面的命令合并了三种不同格式的文件,FFmpeg concat 过滤器会重新编码它们。注意这是有损压缩。
[0:0] [0:1] [1:0] [1:1] [2:0] [2:1] 分别表示第一个输入文件的视频、音频、第二个输入文件的视频、音频、第三个输入文件的视频、音频。
concat=n=3:v=1:a=1 表示有三个输入文件,输出一条视频流和一条音频流。[v] [a] 就是得到的视频流和音频流的名字,注意在 bash 等 shell 中需要用引号,防止通配符扩展。

测试了一下,不同格式正常,不同尺寸会报错。

调整音视频播放速度

  1. 调整视频速率
    调整视频速率的原理为:修改视频的pts,dts;此过程由于不用进行解码编码,所以费时很少
ffmpeg -i input.mkv -an -filter:v "setpts=0.5*PTS" output.mkv
  • 调整速度倍率范围[0.25, 4]
  • 如果只调整视频的话最好把音频禁掉
  • 对视频进行加速时,如果不想丢帧,可以用-r 参数指定输出视频FPS
ffmpeg -i input.mkv -an -r 60 -filter:v "setpts=2.0*PTS" output.mkv
  1. 调整音频速率
    简单的方法是调整音频采样率,但是这种方法会改变音色,一般采用通过对原音进行冲采样,差值等方法。
ffmpeg -i input.mkv -filter:a "atempo=2.0" -vn output.mkv
  • 倍率调整范围为[0.5, 2.0]
  • 如果需要调整4倍可采用以下方法:
ffmpeg -i input.mkv -filter:a "atempo=2.0,atempo=2.0" -vn output.mkv
  1. 同时调整
ffmpeg -i input.mkv -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mkv
posted @ 2021-01-20 16:01  哆啦梦乐园  阅读(325)  评论(2编辑  收藏  举报