FFmpeg音视频处理工具介绍及应用

1 FFmpeg介绍

FFmpeg项目由 Fabrice Bellard在2000年创立。到目前为止,FFmpeg项目的开发者仍然与VLC、MPV、dav1d、x264等多媒体开源项目有着广泛的重叠。Ffmpeg(FastForward Mpeg)是一款遵循GPL的开源软件,在音视频处理方面表现十分优秀,几乎囊括了现存所有的视音频格式的编码,解码、转码、混合、过滤及播放。作为最受欢迎的视频和图像处理软件,它被来自各行各业的不同公司所广泛使用。同时也是一款跨平台的软件,完美兼容Linux、Windows、Mac OSX等平台。其实它由3大部件组成,号称音视频处理工具三剑客:

  • Ffmpeg:由命令行组成,用于多媒体格式转换
  • Ffplay:基于ffmpeg开源代码库libraries做的多媒体播放器
  • Ffprobe:基于ffmpeg做的多媒体流分析器

       Ffmpeg 应该是 FFmpeg 工具集中最核心的利器,支持多种多样的编码器、解码器、封装格式、滤镜功能。FFmpeg框架的基本组成包含AVFormat、AVCodec、AVFilter、AVDevice、AVUtil等模块库,结构图如下:

 (1)AVFormat–FFmpeg的封装模块

AVFormat中实现了目前多媒体领域中的绝大多数媒体封装格式,包括封装和解封装,如MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库。根据实际需求,可进行媒体封装格式的扩展,增加自己定制的封装格式,即在AVFormat中增加自己的封装处理模块。

(2)AVCodec–FFmpeg的编解码模块

AVCodec中实现了目前多媒体领域绝大多数常用的编解码格式,即支持编码,也支持解码。AVCodec除了支持MPEG4、AAC、MJPEG等自带的媒体编解码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用x264编码器;H.265(HEVC)编码,需要使用x264编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。如果希望增加自己的编码格式,或者硬件编解码,则需要在AVCodec中增加相应的编解码模块。

(3)AVFilter–FFmpeg的滤镜模块

AVFilter库提供了一个通用的音频、视频、字幕等滤镜处理框架。在AVFilter中,滤镜框架可以有多个输入和多个输出。

(4)swresample–FFmpeg的音频转换计算模块

swresample模块提供了高级别的音频重采样API。例如允许操作音频采样、音频通道布局转换与布局调整。

(5)swscale–FFmpeg的视频图像转换计算模块

swscale模块提供了高级别的图像转换API,例如它允许进行图像缩放和像素格式转换,常见于将图像从1080p转换成720p或者480p等的缩放,或者将图像数据从YUV420p转换成YUYV,或者YUV转RGB等图像格式转换。

2 conda环境安装ffmpeg

(1)annoconda环境安装

安装方法详见:annoconda安装

(2)ffmpeg安装

conda install ffmpeg

3 ffmpeg命令

FFMPEG提供的命令行(CLI)工具ffmpeg,其使用方法如下(方括号表示可选项,花括号表示必选项目):

ffmpeg [global options] {[infile options]['-i' 'infile'] ...} {[outfile options] 'outfile' ...}

参数选项由三部分组成:可选的一组全局参数、一组或多组输入文件参数、一组或多组输出文件参数,其中,每组输入文件参数以‘-i’为结束标记;每组输出文件参数以输出文件名为结束标记。

(1)能力集列表

  • -formats:列出支持的文件格式。

  • -codecs:列出支持的编解码器。

  • -decoders:列出支持的解码器。

  • -encoders:列出支持的编码器。

  • -protocols:列出支持的协议。

  • -bsfs:列出支持的比特流过滤器。

  • -filters:列出支持的滤镜。

  • -pix_fmts:列出支持的图像采样格式。

  • -sample_fmts:列出支持的声音采样格式。

使用方法:

ffmpeg configure -encoders

(2)常用输入选项

  • -i filename:指定输入文件名。

  • -f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。

  • -ss hh:mm:ss[.xxx]:设定输入文件的起始时间点,启动后将跳转到此时间点然后开始读取数据。

对于输入,以下选项通常是自动识别的,但也可以强制设定。

  • -c codec:指定解码器,需使用能力集列表中的名称。

  • -acodec codec:指定声音的解码器,需使用能力集列表中的名称。

  • -vcodec codec:指定视频的解码器,需使用能力集列表中的名称。

  • -b:v bitrate:设定视频流的比特率,整数,单位bps。

  • -r fps:设定视频流的帧率,整数,单位fps。

  • -s WxH : 设定视频的画面大小。也可以通过挂载画面缩放滤镜实现。

  • -pix_fmt format:设定视频流的图像格式(如RGB还是YUV)。

  • -ar sample rate:设定音频流的采样率,整数,单位Hz。

  • -ab bitrate:设定音频流的比特率,整数,单位bps。

  • -ac channels:设置音频流的声道数目。

(3)常用输出选项

  • -f fmt:强制设定文件格式,需使用能力集列表中的名称(缺省是根据扩展名选择的)。

  • -c codec:指定编码器,需使用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。

  • -acodec codec:指定声音的编码器,需使用能力集列表中的名称(编码器设定为”copy“表示不进行编解码)。

  • -vcodec codec:指定视频的编码器,需使用能力集列表中的名称(编解码器设定为”copy“表示不进行编解码)。

  • -r fps:设定视频编码器的帧率,整数,单位fps。

  • -pix_fmt format:设置视频编码器使用的图像格式(如RGB还是YUV)。

  • -ar sample rate:设定音频编码器的采样率,整数,单位Hz。

  • -b bitrate:设定音视频编码器输出的比特率,整数,单位bps。

  • -ab bitrate:设定音频编码器输出的比特率,整数,单位bps。

  • -ac channels:设置音频编码器的声道数目。

  • -an 忽略任何音频流。

  • -vn 忽略任何视频流。

  • -t hh:mm:ss[.xxx]:设定输出文件的时间长度。

  • -to hh:mm:ss[.xxx]:如果没有设定输出文件的时间长度的画可以设定终止时间点。

(4)流标识

FFMPEG的某些选项可以对一个特定的媒体流起作用,这种情况下需要在选项后面增加一个流标识。流标识允许以下几种格式:

  • 流序号。譬如“:1”表示第二个流。

  • 流类型。譬如“:a“表示音频流,流类型可以和流序号合并使用,譬如“:a:1”表示第二个音频流。

  • 节目。节目和流序号可以合并使用。

  • 流标识。流标识是一个内部标识号。

假如要设定第二个音频流为copy,则需要指定-codec:a:1 copy

(5)音频选项

  • -aframes:等价于frames:a,输出选项,用于指定输出的音频帧数目。

  • -aq:等价于q:a,老版本为qscale:a,用于设定音频质量。

  • -atag:等价于tag:a,用于设定音频流的标签。

  • -af:等价于filter:a,用于设定一个声音的后处理过滤链,其参数为一个描述声音后处理链的字符串。

(6)视频选项

  • -vframes:等价于frames:v,输出选项,用于指定输出的视频帧数目。

  • -aspect:设置宽高比,如4:3、16:9、1.3333、1.7777等。

  • -bits_per_raw_sample:设置每个像素点的比特数。

  • -vstats:产生video统计信息。

  • -vf:等价于filter:v,用于设定一个图像的后处理过滤链,其参数为一个描述图像后处理链的字符串。

  • -vtag:等价于tag:v,用于设定视频流的标签。

  • -force_fps:强制设定视频帧率。

  • -force_key_frames:显式控制关键帧的插入,参数为字符串,可以是一个时间戳,也可以是一个“expr:”前缀的表达式。如“-force_key_frames 0:05:00”、“-force_key_frames expr:gte(t,n_forced*5)”

(7)高级选项

  • -re:要求按照既定速率处理输入数据,这个速率即是输入文件的帧率。

  • -map:指定输出文件的流映射关系。例如 “-map 1:0 -map 1:1”要求将第二个输入文件的第一个流和第二个流写入到输出文件。如果没有-map选项,ffmpeg采用缺省的映射关系。

4 ffmpeg使用示例

(1)视频播放

  • 播放视频

        ffplay input.mp4

  • 播放完自动退出

        ffplay -autoexit input.mp4

  • 设置视频的屏幕高宽比

        ffmpeg -i input.mp4 -aspect 16:9 output.mp4

(2)视频压缩与拼接

  • 视频压缩

        ffmpeg -i demo.mp4 -vcodec h264 -vf scale=640:-2 -threads 4 result.mp4

        ffmpeg -i demo.mp4 -strict -2 -vcodec h264 result.mp4

  • 将4个视频拼接成一个很长的视频(无声音)

        ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex '[0:0][1:0] [2:0][3:0] concat=n=4:v=1 [v]' -map '[v]' output.mp4

  • 将3个视频拼接成一个很长的视频(有声音)

        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

  • 横向拼接2个视频

        ffmpeg -i 0.mp4 -i 1.mp4 -filter_complex "[0:v]pad=iw*2:ih*1[a];[a][1:v]overlay=w" out.mp4

  • 竖向拼接2个视频

        ffmpeg -i 0.mp4 -i 1.mp4 -filter_complex "[0:v]pad=iw:ih*2[a];[a][1:v]overlay=0:h" out_2.mp4

  • 横向拼接3个视频

        ffmpeg -i 0.mp4 -i 1.mp4 -filter_complex "[0:v]pad=iw:ih*2[a];[a][1:v]overlay=0:h" out_2.mp4

  • 竖向拼接3个视频

        ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]pad=iw:ih*3[a];[a][1:v]overlay=0:h[b];[b][2:v]overlay=0:2.0*h" out_v4.mp4

  • 4个视频2x2方式排列

        ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c];[c][3:v]overlay=w:h" out.mp4

(2)视频帧操作

  • 查看每帧的信息

        ffprobe -v error -show_frames gemfield.mp4

  • 从一个视频文件中抽取一帧图像

        ffmpeg -y -i demo.mp4 -ss 00:03:22.000 -vframes 1 -an result.jpg

  • 查看视频总帧数

        ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 gemfield.mp4

  • 查看视频总帧数

        ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 gemfield.mp4

  • 查看 key frame 帧数

        ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 -skip_frame nokey gemfield.mp4

  • 查看 key frame 所在的时间

        ffprobe -v error -skip_frame nokey -select_streams v:0 -show_entries frame=pkt_pts_time -of csv=print_section=0 gemfield.mp4

  • 查看 key frame 分布的情况

        ffprobe -v error -show_frames gemfield.mp4 | grep pict_type

  • 查看 key frame 所在的帧数

        ffprobe -v error -select_streams v -show_frames -show_entries frame=pict_type -of csv gemfield.mp4 | grep -n I | cut -d ':' -f 1

  • 重新设置 key frame interval

        ffmpeg -i gemfield.mp4 -vcodec libx264 -x264-params keyint=1:scenecut=0 -acodec copy out.mp4

  • 查看视频波特率

        ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 gemfield.mp4

(3)图片与视频

  • 从一个视频生成一个分辨率修改为640*640的新视频

        ffmpeg -i demo.avi -vf scale=640:640 result.avi 

  • 从视频中抽取视频(让视频静音)

        ffmpeg -i video_input.mp4 -an -video_output.mp4
        ffmpeg -i input.mp4 -vcodec copy -an output.mp4

  • 截取一张352x240尺寸大小的,格式为jpg的图片

       ffmpeg -i test.asf -y -f image2 -t 0.001 -s 352x240 a.jpg

  • 把视频的前30帧转换成一个Animated Gif

       ffmpeg -i test.asf -vframes 30 -y -f gif a.gif

  • 截取指定时间的缩微图

       ffmpeg -i test.avi -y -f image2 -ss 8 -t 0.001 -s 350x240 test.jpg

  • 将一个avi文件转成mp4格式

        ffmpeg -i demo.avi -acodec copy -vcodec copy result.mp4

  • 为视频增加字幕

        ffmpeg -i video.mp4 -i subtitles.srt -c:v copy -c:a copy -preset veryfast -c:s mov_text -map 0 -map 1 output.mp4

  • 转换文件为3GP格式

       ffmpeg -y -i test.mpeg -bitexact -vcodec h263 -b 128 -r 15 -s 176x144
-acodec aac -ac 2 -ar 22500 -ab 24 -f 3gp test.3gp

  • 将一个mp4文件的音视频流实时转码之后发送给某个远程设备,远程设备可以通过http获取的sdp文件来接收rtp媒体数据。

        ffmpeg -re -i demo.mp4 -acodec copy -vcodec libx264 -s 480x270 -map 0:0 -f rtp rtp://10.10.10.100:1234 -map 0:1 -f rtp rtp://10.10.10.100:1238 > /var/www/live.sdp

  • 使用ffmpeg录像屏幕

        ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s 1024x768 ~/test.avi

  • 重新调整视频尺寸大小

        ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -i ~/test.avi -s 800×600 ~/test-800-600.avi

  • 把摄像头的实时视频录制下来,存储为文件

        ffmpeg  -f video4linux -s 320*240 -r 10 -i /dev/video0  test.asf

  • 图片转视频(规则的名称)

        ffmpeg -f image2 -i 'in%6d.jpg' -vcodec libx264 -r 25 -b 200k test.mp4

  • 图片转视频(不规则的名称)

        方法1:不规则图片名称合成视频文件

        ffmpeg -framerate 10 -pattern_type glob -i '*.jpg' out.mp4

        cat *.png | ffmpeg -f image2pipe -i - output.mp4

        方法2:先动手把不规则文件重命名规则图片名。

def getTpyeFile(filelist, type):     
    res = []     
    for item in filelist:
         name, suf = os.path.splitext(item) # 文件名,后缀
         if suf == type:
             res.append(item)
     return res
 
pwd = os.getcwd() # 返回当前目录的绝对路径
dirs = os.listdir() # 当前目录下所有的文件名组成的数组
typefiles = getTpyeFile(dirs, '.jpg')
 
for i in range(0,len(typefiles)):
     os.rename(typefiles[i],"./%d.jpg" % (i)) #将文件以数字规则命令

将需要合成的图片放在txt中,通过读取txt文件合并成视频。

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

  • 压缩视频文件

        ffmpeg -i video_input.mp4 -r 24 video_output.mp4

  • 通过压缩音频来降低视频文件的体积

        ffmpeg -i video_input.mp4 -c:v libx264 -ac 2 -c:a aac -strict -2 -b:a 128k -crf 28 video_output.mp4

(4)音频处理

  • 音频播放

        ffplay demo.ape

  • 显示波形图

        ffplay -showmode 1 demo.ape

  • 显示频谱图

        ffplay -showmode 2 demo.ape

  • 从视频中抽取音频

        ffmpeg -i video.mp4 -vn audio.mp3

  • 指定编码比特率从视频中抽取音频

        ffmpeg -i video.mp4 -vn -ab 128k audio.mp3

  • 为音频增加封面图片

        ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest output.mp4

  • 使用alsa接口录制一段音频存放到某个wav文件中

        ffmpeg -f alsa -i hw:0 -t 100 result.wav

  • 使用alsa接口搭建一个个人网络电台

        ffmpeg -f alsa -i default -acodec aac -strict -2 -b:a 128k -r 44100 /var/www/data/main.m3u8

  • 压缩媒体文件

        ffmpeg -i audio_input.mp3 -ab 128k audio_output.mp3
        ffmpeg -i audio_input.mp3 -b:a 192k audio_output.mp3

(5)格式转换

  • MPEG4编码转成H264编码

        ffmpeg -i input.mp4 -strict -2 -vcodec h264 output.mp4

  • H264编码转成MPEG4编码 

        ffmpeg -i input.mp4 -strict -2 -vcodec mpeg4 output.mp4

  • webp转换成jpg

        ffmpeg -i in.webp out.jpg

  • webp转换成png

        ffmpeg -i in.webp out.png

  • jpg转换成png

        ffmpeg -i in.jpg out.png

  • jpg转换成webp

        ffmpeg -i in.jpg out.webp

  •  png转换成webp

        ffmpeg -i in.png out.webp

  • png转换成jpg

        ffmpeg -i in.png out.jpg

(6)其它指令

  • 查看FFmpeg支持的编码器

        ffmpeg configure -encoders

  • 查看FFmpeg支持的解码器

        ffmpeg configure -decoders

  • 查看FFmpeg支持的通信协议

        ffmpeg configure -protocols

  • 查看FFmpeg所支持的音视频编码格式、文件封装格式与流媒体传输协议 

        ffmpeg configure --help

  • 从开始裁剪媒体文件

        ffmpeg -i input_video.mp4 -t 5 output_video.mp4
        ffmpeg -i input_audio.wav -t 00:00:05 output_audio.wav

  • 剪辑中间一段媒体文件

        通过 -ss 给出一个开始时间,-to 给出结束时间

        ffmpeg -i input_audio.mp3 -ss 00:01:14 output_audio.mp3
        ffmpeg -i input_audio.wav -ss 00:00:30 -t 10 output_audio.wav
        ffmpeg -i input_video.h264 -ss 00:01:30 -to 00:01:40 output_video.h264
        ffmpeg -i input_audio.ogg -ss 5 output_audio.ogg

猜你喜欢

转载自blog.csdn.net/lsb2002/article/details/131138257