文章目录

  • 2.FFmpeg工具使用基础
  • 2.1 ffmpeg常用命令
  •   2.1.1 ffmpeg的封装转换
  •   2.1.2 ffmpeg的转码参数
  •   2.1.3 ffmpeg的基本转码原理
  • 2.2 ffprobe常用命令
  • 2.3 ffplay常用命令
  •   2.3.1 ffplay常用参数
  •   2.3.2 ffplay高级参数
  •   2.3.3 ffplay的数据可视化分析应用
  • 2.4 小结


2.FFmpeg工具使用基础

  2.1 ffmpeg常用命令

    ffmpeg在做音视频编解码时非常方便,所以在很多场景下转码使用的是ffmpeg,通过ffmpeg --help可以看到ffmpeg常见的命令大概分为6个部分,具体如下。
    ·ffmpeg信息查询部分
    ·公共操作参数部分
    ·文件主要操作参数部分
·    视频操作参数部分
    ·音频操作参数部分
    ·字幕操作参数部分
    ffmpeg信息查询部分的主要参数具体如下:

ffmpeg version 5.1 Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-44)
  configuration: --prefix=/usr/local/ffmpeg --pkg-config-flags=--static --extra-libs=-lpthread --extra-libs=-lm --enable-gpl --enable-libfdk_aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Getting help:
    -h      -- print basic options
    -h long -- print more options
    -h full -- print all options (including all format and codec specific options, very long)
    -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf/protocol
    See man ffmpeg for detailed description of the options.

Print help / information / capabilities:
-L                  show license
-h topic            show help
-? topic            show help
-help topic         show help
--help topic        show help
-version            show version
-buildconf          show build configuration
-formats            show available formats
-muxers             show available muxers
-demuxers           show available demuxers
-devices            show available devices
-codecs             show available codecs
-decoders           show available decoders
-encoders           show available encoders
-bsfs               show available bit stream filters
-protocols          show available protocols
-filters            show available filters
-pix_fmts           show available pixel formats
-layouts            show standard channel layouts
-sample_fmts        show available audio sample formats
-dispositions       show available stream dispositions
-colors             show available color names
-sources device     list sources of the input device
-sinks device       list sinks of the output device
-hwaccels           show available HW acceleration methods
..............................................

    通过ffmpeg --help查看到的help信息是ffmpeg命令的基础信息,如果想获得高级参数部分,那么可以通过使用ffmpeg --help long参数来查看,如果希望获得全部的帮助信息,那么可以通过使用ffmpeg --help full参数来获得。
    通过-L参数,可以看到ffmpeg目前所支持的license协议;通过-version可以查看ffmpeg的版本,包括子模块的详细版本信息,如libavformat、libavcodec、libavutil、libavfilter、libswscale、libswresample的版本:

ffmpeg version 5.1 Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-44)
  configuration: --prefix=/usr/local/ffmpeg --pkg-config-flags=--static --extra-libs=-lpthread --extra-libs=-lm --enable-gpl --enable-libfdk_aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
This version of ffmpeg has nonfree parts compiled in.
Therefore it is not legally redistributable.

    使用ffmpeg转码,有时候可能会遇到无法解析的视频文件或者无法生成视频文件,报错提示不支持生成对应的视频文件,这时候就需要查看当前使用的ffmpeg是否支持对应的视频文件格式,需要使用ffmpeg -formats参数来查看:

File formats:
 D. = Demuxing supported
 .E = Muxing supported
 --
 D  3dostr          3DO STR
  E 3g2             3GP2 (3GPP2 file format)
  E 3gp             3GP (3GPP file format)
 D  4xm             4X Technologies
  E a64             a64 - video for Commodore 64
 D  aa              Audible AA format files
 D  aac             raw ADTS AAC (Advanced Audio Coding)
........
 D  xbm_pipe        piped xbm sequence
 D  xmv             Microsoft XMV
 D  xpm_pipe        piped xpm sequence
 D  xvag            Sony PS3 XVAG
 D  xwd_pipe        piped xwd sequence
 D  xwma            Microsoft xWMA
 D  yop             Psygnosis YOP
 DE yuv4mpegpipe    YUV4MPEG pipe

    根据上面输出的信息可以看到,输出的内容分为3个部分,具体如下。
    ·第一列是多媒体文件封装格式的Demuxing支持与Muxing支持
    ·第二列是多媒体文件格式
    ·第三列是文件格式的详细说明
    若想查看ffmpeg是否支持H.264编码或者解码,可以通过ffmpeg -codecs查看全部信息,也可以通过ffmpeg -encoders查看ffmpeg是否支持H.264编码器,或者通过ffmpeg -decoders查看ffmpeg是否支持H.264解码器。
    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
 V....D 012v                 Uncompressed 4:2:2 10-bit
 V....D 4xm                  4X Movie
 V....D 8bps                 QuickTime 8BPS video
 V....D aasc                 Autodesk RLE
 V....D agm                  Amuse Graphics Movie
 VF...D aic                  Apple Intermediate Codec
 V....D alias_pix            Alias/Wavefront PIX image
 V....D amv                  AMV Video
.........................
 S..... srt                  SubRip subtitle (codec subrip)
 S..... subrip               SubRip subtitle
 S..... subviewer            SubViewer subtitle
 S..... subviewer1           SubViewer1 subtitle
 S..... text                 Raw text subtitle
 S..... vplayer              VPlayer subtitle
 S..... webvtt               WebVTT subtitle
 S..... xsub                 XSUB

    输出信息中包含了三部分内容,具体如下。
    ·第一列包含6个字段,第一个字段用来表示此编码器为音频、视频还是字幕,第二个字段表示帧级别的多线程支持,第三个字段表示分片级别的多线程,第四个字段表示该编码为试验版本,第五个字段表示draw horiz band模式支持,第六个字段表示直接渲染模式支持
    ·第二列是编码格式
    ·第三列是编码格式的详细说明
    ffmpeg -encoders命令执行后,输出如下:

Encoders:
 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
 V....D a64multi             Multicolor charset for Commodore 64 (codec a64_multi)
 V....D a64multi5            Multicolor charset for Commodore 64, extended with 5th color (colram) (codec a64_multi5)
 V....D alias_pix            Alias/Wavefront PIX image
 V..... amv                  AMV Video
 ......................................
 S..... subrip               SubRip subtitle
 S..... text                 Raw text subtitle
 S..... ttml                 TTML subtitle
 S..... webvtt               WebVTT subtitle
 S..... xsub                 DivX subtitles (XSUB)

    输出信息中同样包含了三部分内容,具体如下。
    ·第一列包含6个字段,第一个字段用来表示此编码器为音频、视频还是字幕,第二个字段表示帧级别的多线程支持,第三个字段表示分片级别的多线程,第四个字段表示该编码为试验版本,第五个字段表示draw horiz band模式支持,第六个字段表示直接渲染模式支持
    ·第二列是编码格式
    ·第三列是编码格式的详细说明
    除了查看ffmpeg支持的封装(Muxer)格式与解封装(Demuxer)格式、编码(Encoder)类型与解码(Decoder)类型,还可以通过ffmpeg -filters查看ffmpeg支持哪些滤镜:

Filters:
  T.. = Timeline support
  .S. = Slice threading
  ..C = Command support
  A = Audio input/output
  V = Video input/output
  N = Dynamic number and/or type of input/output
  | = Source or sink filter
.........................
 ... avsynctest        |->AV      Generate an Audio Video Sync Test.
 ..C amovie            |->N       Read audio from a movie source.
 ..C movie             |->N       Read from a movie source.

    输出信息的内容分为四列,具体如下。
    ·第一列总共有3个字段,第一个字段是时间轴支持,第二个字段是分片线程处理支持,第三个字段是命令支持
    ·第二列是滤镜名
    ·第三列是转换方式,如音频转音频,视频转视频,创建音频,创建视频等操作
    ·第四列是滤镜作用说明
    通过ffmpeg --help full命令,可以查看ffmpeg支持的所有封装(demuxer、muxer)格式,编解码器(encoders、decoders)和滤镜处理器(filters)。如果要了解ffmpeg支持的具体某一种demuxer、muxer类型,可以通过ffmpeg -h查看该类型的详细参数,包括encoder、decoder所支持的操作参数,filter所支持的参数,下面就列举几个对应的例子。
    1)查看FLV封装器的参数支持(ffmpeg -h muxer=flv):

Muxer flv [FLV (Flash Video)]:
    Common extensions: flv.
    Mime type: video/x-flv.
    Default video codec: flv1.
    Default audio codec: mp3.
flv muxer AVOptions:
  -flvflags          <flags>      E.......... FLV muxer flags (default 0)
     aac_seq_header_detect        E.......... Put AAC sequence header based on stream data
     no_sequence_end              E.......... disable sequence end for FLV
     no_metadata                  E.......... disable metadata for FLV
     no_duration_filesize         E.......... disable duration and filesize zero value metadata for FLV
     add_keyframe_index           E.......... Add keyframe index metadata

    从输出的帮助信息中可以看到,FLV的muxer的信息包含两大部分,具体如下。
    ·第一部分为FLV封装的默认配置描述,如扩展名、MIME类型、默认的视频编码格式、默认的音频编码格式
    ·第二部分为FLV封装时可以支持的配置参数及相关说明
    2)查看flv解封装器的参数支持(ffmpeg -h demuxer=flv):

Demuxer flv [FLV (Flash Video)]:
    Common extensions: flv.
(live) flv/kux demuxer AVOptions:
  -flv_metadata      <boolean>    .D.V....... Allocate streams according to the onMetaData array (default false)
  -flv_full_metadata <boolean>    .D.V....... Dump full metadata of the onMetadata (default false)
  -flv_ignore_prevtag <boolean>   .D.V....... Ignore the Size of previous tag (default false)
  -missing_streams   <int>        .D.V..XR...  (from 0 to 255) (default 0)

    从帮助信息中可以看到,FLV的demuxer的信息包含两大部分,具体如下。
    ·第一部分为FLV解封装默认的扩展文件名
    ·第二部分为FLV解封装设置的参数及相关说明
    3)查看H.264(AVC)的编码参数支持(ffmpeg -h encoder=h264):

Encoder libx264rgb [libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB]:
    General capabilities: dr1 delay threads 
    Threading capabilities: other
    Supported pixel formats: bgr0 bgr24 rgb24
libx264rgb AVOptions:
  -preset            <string>     E..V....... Set the encoding preset (cf. x264 --fullhelp) (default "medium")
  -tune              <string>     E..V....... Tune the encoding params (cf. x264 --fullhelp)
  -profile           <string>     E..V....... Set profile restrictions (cf. x264 --fullhelp)
  -fastfirstpass     <boolean>    E..V....... Use fast settings when encoding first pass (default true)
  -level             <string>     E..V....... Specify level (as defined by Annex A)
  -passlogfile       <string>     E..V....... Filename for 2 pass stats
  -wpredp            <string>     E..V....... Weighted prediction for P-frames
  -a53cc             <boolean>    E..V....... Use A53 Closed Captions (if available) (default true)
  -x264opts          <string>     E..V....... x264 options
  -crf               <float>      E..V....... Select the quality for constant quality mode (from -1 to FLT_MAX) (default -1)

    从帮助信息可以看到,H.264(AVC)的编码参数包含两大部分,具体如下。
    ·第一部分为H.264所支持的基本编码方式、支持的多线程编码方式(例如帧级别多线程编码或Slice级别多线程编码)、编码器所支持的像素的色彩格式
    ·第二部分为编码的具体配置参数及相关说明
    4)查看H.264(AVC)的解码参数支持(ffmpeg -h decoder=h264):

Decoder h264 [H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10]:
    General capabilities: dr1 delay threads 
    Threading capabilities: frame and slice
H264 Decoder AVOptions:
  -is_avc            <boolean>    .D.V..X.... is avc (default false)
  -nal_length_size   <int>        .D.V..X.... nal_length_size (from 0 to 4) (default 0)
  -enable_er         <boolean>    .D.V....... Enable error resilience on damaged frames (unsafe) (default auto)
  -x264_build        <int>        .D.V....... Assume this x264 version if no x264 version found in any SEI (from -1 to INT_MAX) (default -1)

    从帮助信息可以看到,H.264(AVC)的解码参数查看包含两大部分,具体如下。
    ·第一部分为解码H.264时可以采用的常规支持、多线程方式支持(帧级别多线程解码或Slice级别多线程解码)
    ·第二部分为解码H.264时可以采用的解码参数及相关说明
    5)查看colorkey滤镜的参数支持(ffmpeg -h filter=colorkey),输出内容如下:

Filter colorkey
  Turns a certain color into transparency. Operates on RGB colors.
    slice threading supported
    Inputs:
       #0: default (video)
    Outputs:
       #0: default (video)
colorkey AVOptions:
   color             <color>      ..FV.....T. set the colorkey key color (default "black")
   similarity        <float>      ..FV.....T. set the colorkey similarity value (from 0.01 to 1) (default 0.01)
   blend             <float>      ..FV.....T. set the colorkey key blend value (from 0 to 1) (default 0)

This filter has support for timeline through the 'enable' option

    从帮助信息中可以看到,colorkey滤镜参数查看信息包含两大部分,具体如下。
    ·colorkey所支持的色彩格式信息,colorkey所支持的多线程处理方式,输入或输出支持
    ·colorkey所支持的参数及说明
    关于ffmpeg的帮助信息查询部分已介绍完毕,下面详细介绍ffmpeg的封装转换。

  2.1.1 ffmpeg的封装转换

    ffmpeg的封装转换(转封装)功能包含在AVFormat模块中,通过libavformat库进行Mux和Demux操作;多媒体文件的格式有很多种,这些格式中的很多参数在Mux与Demux的操作参数中是公用的,下面就来详细介绍一下这些公用的参数。

    通过查看ffmpeg --help full信息,找到AVFormatContext参数部分,该参数下的所有参数均为封装转换可使用的参数。下表列出了ffmpeg AVFormatContext的主要参数及说明。

gdigrab python利用ffmpeg进行实时图像处理_字段


    这些都是通用的封装、解封装操作时使用的参数,后续章节中介绍转封装操作、解封装操作、封装操作时,上述参数可以与对应的命令行参数搭配使用

  2.1.2 ffmpeg的转码参数

    ffmpeg编解码部分的功能主要是通过模块AVCodec来完成的,通过libavcodec库进行Encode与Decode操作。多媒体编码格式的种类有很多,但是还是有很多通用的基本操作参数设置,下面就来详细介绍一下这些公用的参数。

    通过命令ffmpeg --help full可以看到AVCodecContext参数列表信息,具体见下表,该选项下面的所有参数均为编解码可以使用的参数。

gdigrab python利用ffmpeg进行实时图像处理_封装_02


    ffmpeg还有一些更细化的参数,本节中并未详细提及,可以根据本节中提到的查看方法查看ffmpeg的帮助文件以查看更多的内容,本节中介绍的是重点及常用的通用参数,后续章节中介绍编码操作时,上述参数可以配合对应的例子使用。

  2.1.3 ffmpeg的基本转码原理

    ffmpeg工具的主要用途为编码、解码、转码以及媒体格式转换,ffmpeg常用于进行转码操作,使用ffmpeg转码的主要原理如图所示。
    通过前两节介绍的参数,可以设置转码的相关参数,如果转码操作涉及封装的改变,则可以通过设置AVCodec与AVFormat的操作参数进行封装与编码的改变,下面列举一个例子:

ffmpeg -i ~/Movies/input1.rmvb -vcodec mpeg4 -b:v 200k -r 15 -an output.mp4

命令行执行后输出的基本信息如下:

Input #0, rm, from 'input.rmvb':
  Metadata:
    comment         :
    ASMRuleBook     : #($Bandwidth >= 0),Stream0Bandwidth = 64082, Stream1Bandwidth = 385918;
    Audiences       : Easy RealMedia Tool's Audience;
    audioMode       : music
    Creation Date   : 3/18/2013 13:59:10
    Description     : This File is Created by Easy RealMedia Tools@!
    Email           : rick@redcheek.net
    Generated By    : Easy RealMedia Tools V1.8x
    HomeWeb         : http://redcheek.net
    Keywords        :
    Modification Date: 3/18/2013 13:59:10
    videoMode       : normal
  Duration: 00:43:31.78, start: 0.000000, bitrate: 463 kb/s
  Stream #0:0: Audio: cook (cook / 0x6B6F6F63), 44100 Hz, stereo, fltp, 64 kb/s
  Stream #0:1: Video: rv40 (RV40 / 0x30345652), yuv420p, 716x400, 386 kb/s, 23.98 fps, 23.98 tbr, 1k tbn
Stream mapping:
  Stream #0:1 -> #0:0 (rv40 (native) -> mpeg4 (native))
Press [q] to stop, [?] for help
Output #0, mp4, to 'output.mp4':
  Metadata:
    comment         :
    ASMRuleBook     : #($Bandwidth >= 0),Stream0Bandwidth = 64082, Stream1Bandwidth = 385918;
    Audiences       : Easy RealMedia Tool's Audience;
    audioMode       : music
    Creation Date   : 3/18/2013 13:59:10
    Description     : This File is Created by Easy RealMedia Tools@!
    Email           : rick@redcheek.net
    Generated By    : Easy RealMedia Tools V1.8x
    HomeWeb         : http://redcheek.net
    Keywords        :
    Modification Date: 3/18/2013 13:59:10
    videoMode       : normal
    encoder         : Lavf59.34.102
  Stream #0:0: Video: mpeg4 (mp4v / 0x7634706D), yuv420p(progressive), 716x400, q=2-31, 200 kb/s, 15 fps, 15360 tbn
    Metadata:
      encoder         : Lavc59.54.100 mpeg4
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A
frame=39165 fps=1801 q=31.0 Lsize=   64213kB time=00:43:30.93 bitrate= 201.5kbits/s dup=56 drop=22303 speed= 120x
video:64044kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.262970%

    从输出信息中可以看到,以上输出的参数中使用了前面介绍过的参数,具体如下。
    ·转封装格式从RMVB格式转换为MP4格式
    ·视频编码从RV40转换为MPEG4格式
    ·视频码率从原来的463kbit/s转换为201.5kbit/s
    ·视频帧率从原来的23.98fps转换为15fps
    ·转码后的文件中不包括音频(-an参数)
    可以分析出,这个例子的流程与前面提到的流程相同,首先解封装,需要解的封装为RMVB;然后解码,其中视频编码为RV40,音频编码为COOK;然后解码后的视频编码为MPEG4;最后封装为一个没有音频的MP4文件。更多详细的例子在后面的章节中将会有详细的介绍。

  2.2 ffprobe常用命令

    在FFmpeg套件中,除了ffmpeg作为多媒体处理工具之外,还有ffprobe多媒体信息查看工具,ffprobe主要用来查看多媒体文件的信息,下面就来看一下ffprobe中常见的基本命令。
    ffprobe常用的参数比较多,可以通过ffprobe --help来查看详细的帮助信息:

usage: ffprobe [OPTIONS] INPUT_FILE

Main options:
-L                  show license
-h topic            show help
-? topic            show help
-help topic         show help
--help topic        show help
-version            show version
-buildconf          show build configuration
-formats            show available formats
......................................................
-show_library_versions  show library versions
-show_versions      show program and library versions
-show_pixel_formats  show pixel format descriptions
-show_optional_fields  show optional fields
-show_private_data  show private data
-private            same as show_private_data
-bitexact           force bitexact output
-read_intervals read_intervals  set read intervals
-i input_file       read specified file

    这些输出的帮助信息既是ffprobe常用的操作参数,也是ffprobe的基础参数。例如查看log,查看每一个音频数据包信息或者视频数据包信息,查看节目信息,查看流信息,查看每一个流有多少帧以及每一个流有多少个音视频包,查看视频像素点的格式等。下面就来根据以上的输出参数重点列举几个例子。
    使用ffprobe -show_packets input.flv查看多媒体数据包信息:

[PACKET]
codec_type=video
stream_index=0
pts=31560
pts_time=31.560000
dts=31560
dts_time=31.560000
duration=40
duration_time=0.040000
size=949
pos=3675221
flags=__
[/PACKET]

    通过show_packets查看的多媒体数据包信息使用PACKET标签括起来,其中包含的信息主要如表所示。

gdigrab python利用ffmpeg进行实时图像处理_字段_03


    除了以上字段和信息之外,还可以通过ffprobe -show_data -show_packets input.flv组合参数来查看包中的具体数据:

[PACKET]
codec_type=audio
stream_index=1
pts=55
pts_time=0.055000
dts=55
dts_time=0.055000
duration=26
duration_time=0.026000
size=417
pos=70548
flags=K_
data=
00000000: fffb 9064 000f f000 0069 0000 0008 0000  ...d.....i......
00000010: 0d20 0000 0100 3c02 0007 8000 2000 0034  . ....<..... ..4
....................................,,
00000190: ad4d e1f4 e762 c5c0 47c4 081a 88de af05  .M...b..G.......
000001a0: 60      
[/PACKET]                                 `

    通过ffprobe读取packets来进行对应的数据分析,使用show_packets与show_data配合可以进行更加精确的分析。
    除了packets与data之外,ffprobe还可以分析多媒体的封装格式,通过ffprobe -show_format output.mp4命令可以查看多媒体的封装格式,其使用FORMAT标签括起来显示

[FORMAT]
filename=output.mp4
nb_streams=1
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=2611.000000
size=65753708
bit_rate=201466
probe_score=100
TAG:major_brand=isom
TAG:minor_version=512
TAG:compatible_brands=isomiso2mp41
TAG:encoder=Lavf59.34.102
TAG:description=This File is Created by Easy RealMedia Tools@!
[/FORMAT]

    下面对输出信息关键字段进行说明,

gdigrab python利用ffmpeg进行实时图像处理_字段_04


    参考表介绍的字段来解析输出,可以看到这个视频文件只有1个流通道,起始时间是0.000000,总时间长度为2611.000000,文件大小为65753708字节,码率为201466bit/s,这个文件的格式有可能是MOV、MP4、M4A、3GP、3G2或者MJ2,之所以ffprobe会这么输出,是因为这几种封装格式在ffmpeg中所识别的标签基本相同,所以才会有这么多种显示方式,而其他几种封装格式不一定是这样的,下面我们再来看一个WMV的封装格式:

[FORMAT]
filename=input.wmv
nb_streams=2
nb_programs=0
format_name=asf
format_long_name=ASF (Advanced / Active Streaming Format)
start_time=0.000000
duration=52.200000
size=2497423
bit_rate=382746
probe_score=100
TAG:FSCSettings=11
TAG:WMFSDKVersion=12.0.19041.2364
TAG:WMFSDKNeeded=0.0.0.0000
TAG:Buffer Average=11374
TAG:VBR Peak=464970
TAG:IsVBR=1
TAG:DeviceConformanceTemplate=@
[/FORMAT]

    这个input.wmv文件中包含一个流通道,文件封装格式为ASF
    通过ffprobe -show_frames input.flv命令可以查看视频文件中的帧信息,输出的帧信息将使用FRAME标签括起来

[FRAME]
media_type=audio
stream_index=1
key_frame=1
pts=4757
pts_time=4.757000
pkt_dts=4757
pkt_dts_time=4.757000
best_effort_timestamp=4757
best_effort_timestamp_time=4.757000
pkt_duration=26
pkt_duration_time=0.026000
duration=26
duration_time=0.026000
pkt_pos=634453
pkt_size=418
sample_fmt=fltp
nb_samples=1152
channels=2
channel_layout=stereo
[/FRAME]

    通过-show_frames参数可以查看每一帧的信息,下面就来介绍一下其中重要的信息,具体见表2-5。

gdigrab python利用ffmpeg进行实时图像处理_封装_05


gdigrab python利用ffmpeg进行实时图像处理_ffmpeg_06


    在Windows下常用的Elecard StreamEye工具中打开查看MP4时,会很直观地看到帧类型显示,用ffprobe的pict_type同样可以看到视频的帧是I帧、P帧或者B帧;每一帧的大小同样也可以通过ffprobe的pkt_size查看到。

    通过-show_streams参数可以查看到多媒体文件中的流信息,流的信息将使用STREAM标签括起来:

[STREAM]
index=0
codec_name=mpeg4
codec_long_name=MPEG-4 part 2
profile=Simple Profile
codec_type=video
codec_tag_string=mp4v
codec_tag=0x7634706d
width=716
height=400
coded_width=716
coded_height=400
closed_captions=0
film_grain=0
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=179:100
pix_fmt=yuv420p
level=1
color_range=unknown
color_space=unknown
color_transfer=unknown
color_primaries=unknown
chroma_location=left
field_order=unknown
refs=1
quarter_sample=false
divx_packed=false
id=0x1
r_frame_rate=15/1
avg_frame_rate=15/1
time_base=1/15360
start_pts=0
start_time=0.000000
duration_ts=40104960
duration=2611.000000
bit_rate=200938
max_bit_rate=N/A
bits_per_raw_sample=N/A
nb_frames=39165
nb_read_frames=N/A
nb_read_packets=N/A
extradata_size=47
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
DISPOSITION:captions=0
DISPOSITION:descriptions=0
DISPOSITION:metadata=0
DISPOSITION:dependent=0
DISPOSITION:still_image=0
TAG:language=und
TAG:handler_name=VideoHandler
TAG:vendor_id=[0][0][0][0]
TAG:encoder=Lavc59.54.100 mpeg4
[/STREAM]

    如以上输出内容所示,从中可以看到流的信息,具体属性及说明见表2-6。

gdigrab python利用ffmpeg进行实时图像处理_封装_07


gdigrab python利用ffmpeg进行实时图像处理_封装_08


gdigrab python利用ffmpeg进行实时图像处理_c++_09


    ffprobe使用前面的参数可以获得key-value格式的显示方式,但是阅读起来因习惯不同,可能有的人会认为方便,有的人认为不方便;如果要进行格式化的显示,这样就需要用到ffprobe -print_format或者ffprobe -of参数来进行相应的格式输出,而-print_format支持多种格式输出,包括XML、INI、JSON、CSV、FLAT等。下面列举几种常见的格式输出的例子。

    通过ffprobe -of xml -show_streams input.flv得到的XML输出格式如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<ffprobe>
Input #0, flv, from 'input.flv':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42avc1
    encoder         : Lavf57.83.100
  Duration: 00:22:25.26, start: 0.000000, bitrate: 673 kb/s
  Stream #0:0: Video: flv1, yuv420p, 848x480, 200 kb/s, 25 fps, 25 tbr, 1k tbn
  Stream #0:1: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
    <streams>
        <stream index="0" codec_name="flv1" codec_long_name="FLV / Sorenson Spark / Sorenson H.263 (Flash Video)" codec_type="video" codec_tag_string="[0][0][0][0]" codec_tag="0x0000" width="848" height="480" coded_width="848" coded_height="480" closed_captions="0" film_grain="0" has_b_frames="0" pix_fmt="yuv420p" level="-99" refs="1" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/1000" start_pts="0" start_time="0.000000" bit_rate="200000">
            <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0" timed_thumbnails="0" captions="0" descriptions="0" metadata="0" dependent="0" still_image="0"/>
        </stream>
        <stream index="1" codec_name="mp3" codec_long_name="MP3 (MPEG audio layer 3)" codec_type="audio" codec_tag_string="[0][0][0][0]" codec_tag="0x0000" sample_fmt="fltp" sample_rate="44100" channels="2" channel_layout="stereo" bits_per_sample="0" initial_padding="0" r_frame_rate="0/0" avg_frame_rate="0/0" time_base="1/1000" start_pts="55" start_time="0.055000" bit_rate="128000">
            <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0" timed_thumbnails="0" captions="0" descriptions="0" metadata="0" dependent="0" still_image="0"/>
        </stream>
    </streams>
</ffprobe>

    从输出内容可以看到输出的内容格式为INI格式,这种格式可以用于擅长解析INI格式的项目中。
通过ffprobe -of flat -show_streams input.flv输出FLAT格式:

streams.stream.0.index=0
streams.stream.0.codec_name="flv1"
streams.stream.0.codec_long_name="FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"
streams.stream.0.profile="unknown"
streams.stream.0.codec_type="video"
streams.stream.0.codec_tag_string="[0][0][0][0]"
streams.stream.0.codec_tag="0x0000"
streams.stream.0.width=848
streams.stream.0.height=480
streams.stream.0.coded_width=848
streams.stream.0.coded_height=480

    从输出的内容可以看到,输出的信息为FLAT格式的输出,从Packet的stream_index的值可以直接得知Packet属于哪个Stream,从而获得Stream对应的Packet的信息。
    通过ffprobe -of json -show_packets input.flv输出JSON格式:

{
  "codec_type": "audio",
    "stream_index": 1,
    "pts": 26595,
    "pts_time": "26.595000",
    "dts": 26595,
    "dts_time": "26.595000",
    "duration": 26,
    "duration_time": "0.026000",
    "size": "418",
    "pos": "2975184",
    "flags": "K_"
},
{
    "codec_type": "video",
    "stream_index": 0,
    "pts": 26600,
    "pts_time": "26.600000",
    "dts": 26600,
    "dts_time": "26.600000",
    "duration": 40,
    "duration_time": "0.040000",
    "size": "12406",
    "pos": "2975618",
    "flags": "__"
},

    从输出内容可以看到,内容信息还是Packet的信息,但是输出的形式为JSON的格式,这种格式的数据可以用在以JSON解析为主的业务中。
    通过ffprobe -of csv -show_packets input.flv输出CSV格式

packet,audio,1,65230,65.230000,65230,65.230000,26,0.026000,418,7016030,K_
packet,video,0,65240,65.240000,65240,65.240000,40,0.040000,221,7016464,__
packet,audio,1,65257,65.257000,65257,65.257000,26,0.026000,418,7016701,K_
packet,video,0,65280,65.280000,65280,65.280000,40,0.040000,326,7017135,__
packet,audio,1,65283,65.283000,65283,65.283000,26,0.026000,418,7017477,K_
packet,audio,1,65309,65.309000,65309,65.309000,26,0.026000,418,7017911,K_
packet,video,0,65320,65.320000,65320,65.320000,40,0.040000,221,7018345,__
packet,audio,1,65335,65.335000,65335,65.335000,26,0.026000,417,7018582,K_
packet,video,0,65360,65.360000,65360,65.360000,40,0.040000,367,7019015,__
packet,audio,1,65361,65.361000,65361,65.361000,26,0.026000,418,7019398,K_
packet,audio,1,65387,65.387000,65387,65.387000,26,0.026000,418,7019832,K_
packet,video,0,65400,65.400000,65400,65.400000,40,0.040000,217,7020266,__

    通过各种格式的输出,可以使用对应的绘图方式绘制出可视化图形。
    使用select_streams可以只查看音频(a)、视频(v)、字幕(s)的信息,例如配合show_frames查看视频的frames信息:

ffprobe -show_frames -select_streams v -of xml input.mp4
<frame media_type="video" stream_index="0" key_frame="0" pts="1262" pts_time="252.400000" pkt_dts="1262" pkt_dts_time="252.400000" best_effort_timestamp="1262" best_effort_timestamp_time="252.400000" pkt_duration="1" pkt_duration_time="0.200000" duration="1" duration_time="0.200000" pkt_pos="16002965" pkt_size="38283" width="1280" height="720" pix_fmt="yuv420p" sample_aspect_ratio="1:1" pict_type="P" coded_picture_number="1262" display_picture_number="0" interlaced_frame="0" top_field_first="0" repeat_pict="0" chroma_location="left"/>
       <frame media_type="video" stream_index="0" key_frame="0" pts="1263" pts_time="252.600000" pkt_dts="1263" pkt_dts_time="252.600000" best_effort_timestamp="1263" best_effort_timestamp_time="252.600000" pkt_duration="1" pkt_duration_time="0.200000" duration="1" duration_time="0.200000" pkt_pos="16041329" pkt_size="19873" width="1280" height="720" pix_fmt="yuv420p" sample_aspect_ratio="1:1" pict_type="P" coded_picture_number="1263" display_picture_number="0" interlaced_frame="0" top_field_first="0" repeat_pict="0" chroma_location="left"/>

    从以上的输出内容中可以看到,输出的frame信息全部为视频相关的信息。
    使用ffprobe还可以查看很多信息,读者可以通过本节介绍的help方法查看更多更详细的信息。

  2.3 ffplay常用命令

    在编译旧版本FFmpeg源代码时,如果系统中包含了SDL-1.2版本,就会默认将ffplay编译生成出来,如果不包含SDL-1.2或者版本不是SDL-1.2时,将无法生成ffplay文件,所以,如果想使用ffplay进行流媒体播放测试,则需要安装SDL-1.2。而在新版本的FFmpeg源代码中,需要SDL-2.0之后的版本才能有效生成ffplay。
    在FFmpeg中通常使用ffplay作为播放器,其实ffplay同样也可以作为很多音视频数据的图形化分析工具,通过ffplay可以看到视频图像的运动估计方向、音频数据的波形等,本节将会介绍更多的参数并举例说明。

  2.3.1 ffplay常用参数

    ffplay不仅仅是播放器,同时也是测试ffmpeg的codec引擎、format引擎,以及filter引擎的工具,并且还可以进行可视化的媒体参数分析,其可以通过ffplay --help进行查看:

Simple media player
usage: ffplay [options] input_file

Main options:
-L                  show license
-h topic            show help
-? topic            show help
-help topic         show help
--help topic        show help
-version            show version
-buildconf          show build configuration
-formats            show available formats
-muxers             show available muxers
-demuxers           show available demuxers
-devices            show available devices
-codecs             show available codecs
-decoders           show available decoders
-encoders           show available encoders
-bsfs               show available bit stream filters
-protocols          show available protocols
-filters            show available filters
-pix_fmts           show available pixel formats
-layouts            show standard channel layouts
-sample_fmts        show available audio sample formats
-dispositions       show available stream dispositions
..............................

    如上述帮助信息的输出所示,大多数都是前面已经介绍过的参数,这里就不再一一赘述,一些未介绍的参数说明见表2-8。

gdigrab python利用ffmpeg进行实时图像处理_封装_10


    常见参数可以手动进行尝试,下面列举几个示例。

    ·如果希望从视频的第30秒开始播放,播放10秒钟的文件,则可以使用如下命令:

ffplay -ss 30 -t 10 input.mp4

    如果希望视频播放时播放器的窗口显示标题为自定义标题,则可以使用如下命令:

ffplay -window_title "Hello World, This is a sample" output.mp4

    如果希望使用ffplay打开网络直播流,则可以使用如下命令:

ffplay -window_title "播放测试"  rtmp://...

  2.3.2 ffplay高级参数

    通过使用ffplay --help参数可以看到比较多的帮助信息,其中包含了高级参数介绍,下面就来详细介绍一下,具体见表。

gdigrab python利用ffmpeg进行实时图像处理_字段_11


gdigrab python利用ffmpeg进行实时图像处理_ffmpeg_12


    下面将这些参数与前面介绍过的一些参数进行组合,列举几个示例。

    例如从20秒播放一个视频,播放时长为10秒钟,播放完成后自动退出ffplay,播放器的窗口标题为“Hello World”,为了确认播放时长正确,可以通过系统命令time查看命令运行时长:

time ffplay -window_title "Hello World" -ss 20 -t 10 -autoexit output.mp4

    例如强制使用H.264解码器解码MPEG4的视频,将会报错:

ffplay -vcodec h264 output.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.mp4':    0B f=0/0
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf59.34.102
    description     : This File is Created by Easy RealMedia Tools@!
  Duration: 00:43:31.00, start: 0.000000, bitrate: 201 kb/s
  Stream #0:0[0x1](und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 716x400 [SAR 1:1 DAR 179:100], 200 kb/s, 15 fps, 15 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.54.100 mpeg4
[h264 @ 0000028fa9723a00] Invalid NAL unit 0, skipping.
    Last message repeated 4 times
[h264 @ 0000028fa9723a00] no frame!
[h264 @ 0000028fa97242c0] Invalid NAL unit 0, skipping.
[h264 @ 0000028fa97242c0] no frame!
[h264 @ 0000028faf28b480] Invalid NAL unit 0, skipping.

    从输出的信息可以看到,使用H.264的解码器解码MPEG4时会得到no frame的错误,视频也解析不出来。
    如果使用ffplay播放视频时希望加载字幕文件,则可以通过加载ASS或者SRT字幕文件来解决,下面列举一个加载SRT字幕的例子,首先编辑SRT字幕文件,内容如下:

00:00:01.000 --> 00:00:30.000
Test Subtitle by Steven Liu 
2
00:00:30.001 --> 00:00:60.000
Hello Test Subtitle
3
00:01:01.000 --> 00:01:10.000
Test Subtitle by Steven Liu 
4
00:01:11.000 --> 00:01:30.000
Test Subtitle by Steven Liu

    然后通过filter将字幕文件加载到播放数据中,使用命令如下:

ffplay -window_title "Test Movie" -vf "subtitles=input.srt" output.mp4

  2.3.3 ffplay的数据可视化分析应用

    使用ffplay除了可以播放视频流媒体文件之外,还可以作为可视化的视频流媒体分析工具,例如播放音频文件时,如果不确定文件的声音是否正常,则可以直接使用ffplay播放音频文件,播放的时候其将会把解码后的音频数据以音频波形的形式显示出来,命令如下:

ffplay -showmode 1 output.mp3

    例如,当播放视频时想要体验解码器是如何解码每个宏块的,可以使用如下命令:

ffplay -debug vis_mb_type -window_title "show vis_mb_type" -ss 20 -t 10 -autoexit output.mp4

    在输出的视频信息中,可以看到不同颜色的方块,下面就来说明一下这些颜色分别代表什么信息,具体见表(见彩插)。

gdigrab python利用ffmpeg进行实时图像处理_c++_13


    例如通过ffplay查看B帧预测与P帧预测信息,希望将信息在窗口中显示出来,可使用如下命令:

ffplay -vismv pf output.mp4

    ffplay播放视频显示运动估计信息示例

    vismv参数则是用来显示图像解码时的运动向量信息的,可以设置三种类型的运动向量信息显示,具体见表。

gdigrab python利用ffmpeg进行实时图像处理_字段_14


    这个vismv参数将会在未来被替换掉,未来更多的是使用codecview这个滤镜来进行设置,如图所示,也可以通过下面这条命令来完成:

ffplay -flags2 +export_mvs -ss 40 output.mp4 -vf codecview=mv=pf+bf+bb