1.FFmpeg简介

1.FFmpeg简介

序言

在阅读前请参考FFmpeg安装与编译
FFmpeg入门到精通的系列文章,希望能有所收获,作者会竭尽全力更新和总结,一起进步一起加油!!

1.组成模块

  • libavformat
  • libavcodec
  • libavfilter
  • libavdevice
  • libavutil
  • libswresample
  • libswscale
  • libpostproc

接下来会由浅到深的介绍每一个模块基本作用

libavformat

libavformat 中实现了目前多媒体领域中绝大部分多媒体的封装格式,包括封装和解封装,如MP4、FLV、KV、TS等文件封装格式,RTMP、RTSP、MMS、HLS等网络协议封装格式。FFmpeg是否支持某种媒体封装格式,取决于编译时是否包含了该格式的封装库

libavcodec

libavcodec中实现了目前多媒体领域大多数常用的编码格式,即支持编码,也支持解码。
libavcodec吃了支持MPEG4、AAC、MJPEG等自带的媒体编码格式之外,还支持第三方的编解码器,如H.264(AVC)编码,需要使用V264编码器;H.265(HEVC)编码,需要使用H.265编码器;MP3(mp3lame)编码,需要使用libmp3lame编码器。

libavfilter

libavfilter库提供一个通用的音频视频、字幕等滤镜处理框架。在libavfilter中,滤镜框架可有由多个输入输出,如下图所示:

如图所示滤镜处理将输入的视频切割成两部分流,一部分抛给crop滤镜与vflip滤镜处理模块进行操作,另一部分保持原样,当crop滤镜与vflip滤镜处理模块操作完成后,将合并到原有的overlay图层中,并显示在最上层,输出新的视频

libswresample

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

libswscale

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

2.FFmpeg的编解码工具ffmpeg

ffmpeg是FFmpeg源代码编译后生成的一个可执行程序,其可以作为命令行工具使用
先举一个简单的例子:

ffmpeg -i input.mp4 output.avi

input.mp4 为视频路径
这是题条简单的ffmpeg命令,ffmpeg通过 -i参数将input.mp4作为输入源输入,然后进行转码与转封装操作,输出到output.avi中,这条命令主要做了如下工作

  • 获得输入源input.mp4
  • 转码
  • 输出文件output.avi

看似简单的两部工作,其实远远不止是从后缀名为MP4的文件输出成后缀名为AVI的文件,因为在ffmpeg中,MP4与AVI是两种文件封装格式,并不是后缀名就可以决定的,例如上面的命令行就可写成这样:

ffmpeg -i input.mp4 -f avi output.dat

条命令行执行过程输出如下:

ffmpeg version git-2020-08-12-b40dd2f Copyright (c) 2000-2020 the FFmpeg developers  built with Apple clang version 11.0.3 (clang-1103.0.32.62)  configuration: --prefix=/usr/local/Cellar/ffmpeg/HEAD-b40dd2f --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack  libavutil      56. 58.100 / 56. 58.100  libavcodec     58.100.100 / 58.100.100  libavformat    58. 50.100 / 58. 50.100  libavdevice    58. 11.101 / 58. 11.101  libavfilter     7. 87.100 /  7. 87.100  libavresample   4.  0.  0 /  4.  0.  0  libswscale      5.  8.100 /  5.  8.100  libswresample   3.  8.100 /  3.  8.100  libpostproc    55.  8.100 / 55.  8.100Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '1.MP4':  Metadata:    minor_version   : 512    major_brand     : isom    compatible_brands: isomiso2avc1mp41    comment         : vid:v0300f7c0000btf11kkcutbj5aiu5kt0    encoder         : Lavf58.20.100  Duration: 00:01:52.62, start: 0.000000, bitrate: 2214 kb/s    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 720x1280 [SAR 1:1 DAR 9:16], 2078 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)    Metadata:      handler_name    : VideoHandler    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)    Metadata:      handler_name    : SoundHandlerStream mapping:  Stream #0:0 -> #0:0 (h264 (native) -> mpeg4 (native))  Stream #0:1 -> #0:1 (aac (native) -> mp3 (libmp3lame))Press [q] to stop, [?] for helpOutput #0, avi, to 'output3.dat':  Metadata:    minor_version   : 512    major_brand     : isom    compatible_brands: isomiso2avc1mp41    ICMT            : vid:v0300f7c0000btf11kkcutbj5aiu5kt0    ISFT            : Lavf58.50.100    Stream #0:0(und): Video: mpeg4 (FMP4 / 0x34504D46), yuv420p, 720x1280 [SAR 1:1 DAR 9:16], q=2-31, 200 kb/s, 30 fps, 30 tbn, 30 tbc (default)    Metadata:      handler_name    : VideoHandler      encoder         : Lavc58.100.100 mpeg4    Side data:      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A    Stream #0:1(und): Audio: mp3 (libmp3lame) (U[0][0][0] / 0x0055), 44100 Hz, stereo, fltp (default)    Metadata:      handler_name    : SoundHandler      encoder         : Lavc58.100.100 libmp3lameframe=  190 fps=0.0 q=31.0 size=     768kB time=00:00:06.45 bitrate= 975.1kbits/frame=  399 fps=399 q=31.0 size=    2048kB time=00:00:13.45 bitrate=1247.1kbits/frame=  616 fps=410 q=24.8 size=    3072kB time=00:00:20.66 bitrate=1217.9kbits/frame=  819 fps=409 q=31.0 size=    4352kB time=00:00:27.48 bitrate=1297.3kbits/frame= 1020 fps=408 q=24.8 size=    5376kB time=00:00:34.16 bitrate=1288.9kbits/frame= 1210 fps=403 q=31.0 size=    6656kB time=00:00:40.48 bitrate=1346.7kbits/frame= 1416 fps=404 q=31.0 size=    7680kB time=00:00:47.36 bitrate=1328.4kbits/frame= 1610 fps=402 q=31.0 size=    8960kB time=00:00:53.81 bitrate=1364.0kbits/frame= 1806 fps=401 q=31.0 size=   10240kB time=00:01:00.34 bitrate=1390.2kbits/frame= 1976 fps=395 q=31.0 size=   11776kB time=00:01:06.01 bitrate=1461.4kbits/frame= 2175 fps=395 q=24.8 size=   13056kB time=00:01:12.64 bitrate=1472.3kbits/frame= 2358 fps=393 q=31.0 size=   14592kB time=00:01:18.75 bitrate=1517.8kbits/frame= 2540 fps=390 q=31.0 size=   15872kB time=00:01:24.81 bitrate=1532.9kbits/frame= 2721 fps=388 q=24.8 size=   17152kB time=00:01:30.85 bitrate=1546.5kbits/frame= 2903 fps=387 q=31.0 size=   18432kB time=00:01:36.91 bitrate=1558.0kbits/frame= 3086 fps=385 q=31.0 size=   19456kB time=00:01:43.00 bitrate=1547.4kbits/frame= 3274 fps=385 q=31.0 size=   20480kB time=00:01:49.29 bitrate=1535.0kbits/frame= 3377 fps=388 q=31.0 Lsize=   21275kB time=00:01:52.58 bitrate=1548.0kbits/s speed=12.9x    video:19324kB audio:1760kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.909878%

这条ffmpeg命令相对于前面的那条命令做了一些改变,加了一个“-f”进行约束,“-f”参数的工作非常重要,它指定了文件的容器格式,所以可以看出输出的文件为output.dat,文件后缀为.dat,但是主要的工作依然与之前的指令相同
分析以上两个输出信息中的Output #0部分,可以看到输出的都是AVI,只是输出的文件名不同,其他内容均相同
ffmpeg的主要工作流程相对比较简单,具体如下:

  • 解封装(Demuxing)
  • 解码(Decoding)
  • 编码(Encoding)
  • 封装(Muxing)

其中需要进过6个步骤,具体如下:

  • 读取输入源
  • 进行音视频的解封装
  • 解码每一帧的音视频数据
  • 编码每一帧的音视频数据
  • 进行音视频的重新封装
  • 输出到目标

如下图所示:

如上图所示,ffmpeg首先读取输入源;然后通过Demuxer将音视频包进行解码,这个动作通过调用libavformat中的接口即可实现,接下来通过Decoder进行解码,将音视频Decoder解包成为YUV或者PCM这样的数据,Decoder通过libavcodec中的接口即可实现;然后通过Encoder见对应的数据进行编码,编码可以通过libavcodec中的接口来实现;接下来将编码后的音视频数据包通过Muxer进行封装,Muxer封装通过libavformat中的接口即可实现,输出为视频流

3.FFmpeg的多媒体分析器ffprobe

ffprobe是FFmpeg编译后的可执行文件。ffprobe是一个非常强大的多媒体分析工具,可以从媒体文件或媒体流中获得你想要的信息,比如音频的参数,视频的参数,媒体容器的参数,音视频的编码格式、媒体文件中媒体总时常、复合码率等信息等。
据一个简单例子,先有一个概念:

j@xjdeMacBook-Pro 视频处理 % ffprobe -show_streams 1.mp4ffprobe version git-2020-08-12-b40dd2f Copyright (c) 2007-2020 the FFmpeg developers  built with Apple clang version 11.0.3 (clang-1103.0.32.62)  configuration: --prefix=/usr/local/Cellar/ffmpeg/HEAD-b40dd2f --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack  libavutil      56. 58.100 / 56. 58.100  libavcodec     58.100.100 / 58.100.100  libavformat    58. 50.100 / 58. 50.100  libavdevice    58. 11.101 / 58. 11.101  libavfilter     7. 87.100 /  7. 87.100  libavresample   4.  0.  0 /  4.  0.  0  libswscale      5.  8.100 /  5.  8.100  libswresample   3.  8.100 /  3.  8.100  libpostproc    55.  8.100 / 55.  8.100Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '1.mp4':  Metadata:    minor_version   : 512    major_brand     : isom    compatible_brands: isomiso2avc1mp41    comment         : vid:v0300f7c0000btf11kkcutbj5aiu5kt0    encoder         : Lavf58.20.100  Duration: 00:01:52.62, start: 0.000000, bitrate: 2214 kb/s    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 720x1280 [SAR 1:1 DAR 9:16], 2078 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)    Metadata:      handler_name    : VideoHandler    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)    Metadata:      handler_name    : SoundHandler[STREAM]index=0codec_name=h264codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10profile=Highcodec_type=videocodec_time_base=1/60codec_tag_string=avc1codec_tag=0x31637661width=720height=1280coded_width=720coded_height=1280closed_captions=0has_b_frames=2sample_aspect_ratio=1:1display_aspect_ratio=9:16pix_fmt=yuv420plevel=31color_range=tvcolor_space=bt709color_transfer=bt709color_primaries=bt709chroma_location=leftfield_order=unknowntimecode=N/Arefs=1is_avc=truenal_length_size=4id=N/Ar_frame_rate=30/1avg_frame_rate=30/1time_base=1/15360start_pts=0start_time=0.000000duration_ts=1729024duration=112.566667bit_rate=2078684max_bit_rate=N/Abits_per_raw_sample=8nb_frames=3377nb_read_frames=N/Anb_read_packets=N/ADISPOSITION:default=1DISPOSITION:dub=0DISPOSITION:original=0DISPOSITION:comment=0DISPOSITION:lyrics=0DISPOSITION:karaoke=0DISPOSITION:forced=0DISPOSITION:hearing_impaired=0DISPOSITION:visual_impaired=0DISPOSITION:clean_effects=0DISPOSITION:attached_pic=0DISPOSITION:timed_thumbnails=0TAG:language=undTAG:handler_name=VideoHandler[/STREAM][STREAM]index=1codec_name=aaccodec_long_name=AAC (Advanced Audio Coding)profile=LCcodec_type=audiocodec_time_base=1/44100codec_tag_string=mp4acodec_tag=0x6134706dsample_fmt=fltpsample_rate=44100channels=2channel_layout=stereobits_per_sample=0id=N/Ar_frame_rate=0/0avg_frame_rate=0/0time_base=1/44100start_pts=0start_time=0.000000duration_ts=4964293duration=112.569002bit_rate=128001max_bit_rate=128001bits_per_raw_sample=N/Anb_frames=4850nb_read_frames=N/Anb_read_packets=N/ADISPOSITION:default=1DISPOSITION:dub=0DISPOSITION:original=0DISPOSITION:comment=0DISPOSITION:lyrics=0DISPOSITION:karaoke=0DISPOSITION:forced=0DISPOSITION:hearing_impaired=0DISPOSITION:visual_impaired=0DISPOSITION:clean_effects=0DISPOSITION:attached_pic=0DISPOSITION:timed_thumbnails=0TAG:language=undTAG:handler_name=SoundHandler[/STREAM]

根据输出内容可以看到,使用ffmpeg能够查看MP4文件容器中的流信息,其包含了一个视频流和一个音频流,流相关的信息通过[STREAM][/STREAM]的方式展示出来。当视频文件容器中包含音频流与视频流或者更多路流时,会通过[STREAM]与[/STREAM]进行多个流的分割,分割后采用index来进行流的索引信息的区分

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部