5 FFmpeg从入门到精通-FFmpeg流媒体

1 FFmpeg从入门到精通-FFmpeg简介
2 FFmpeg从入门到精通-FFmpeg工具使用基础
3 FFmpeg从入门到精通-FFmpeg转封装
4 FFmpeg从入门到精通-FFmpeg转码
5 FFmpeg从入门到精通-FFmpeg流媒体
6 FFmpeg从入门到精通-FFmpeg滤镜使用
7 FFmpeg从入门到精通-FFmpeg中Linux设备操作
8 FFmpeg从入门到精通-FFmpeg接口libavformat的使用
9 FFmpeg从入门到精通-FFmpeg接口libavcodec的使用
10 FFmpeg从入门到精通-FFmpeg接口libavfilter的使用

文章目录

5.FFmpeg流媒体

  5.1 FFmpeg发布与录制RTMP流

    在流媒体中,RTMP直播是最为常见的一种实时直播,同时考虑将RTMP实时直播的流录制下来。

  5.1.1 RTMP参数说明

    下面就来介绍FFmpeg拉取RTMP直播流可以使用的主要参数,如表所示。
在这里插入图片描述

  5.1.2 RTMP参数举例

    开始之前需要先搭建Nginx+RTMP服务,接下来将根据例子进行设置项的作用分析。

   1.rtmp_app参数

    通过使用rtmp_app参数可以设置RTMP的推流发布点,录制命令行如下:

ffmpeg -rtmp_app live -i rtmp://192.168.100.12:1935 -c copy -f flv output.flv

    或者发布流命令行如下

ffmpeg -re -i input.mp4 -c copy -f flv -rtmp_app live rtmp://192.168.100.12:1935

    执行这条命令行时,FFmpeg将会给出错误提示,具体如下:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
    Metadata:
        major_brand     : isom
        minor_version   : 512
        compatible_brands: isomiso2avc1mp41
        encoder         : Lavf57.66.102
    Duration: 00:00:10.01, start: 0.000000, bitrate: 2309 kb/s
        Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x714 [SAR 1:1 DAR 640:357], 2183 kb/s, 25 fps, 25 tbr, 25k tbn, 50 tbc (default)
    Metadata:
        handler_name    : VideoHandler
        Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 120 kb/s (default)
    Metadata:
        handler_name    : SoundHandler
[rtmp @ 0x7fd0816016e0] Server error: identify stream failed.
rtmp://192.168.100.12: Unknown error occurred

    出现该错误是因为我们尚未设置stream项所致

   2.rtmp_playpath参数

    设置rtmp_app时可以看到提示了identify stream failed错误,可以通过使用rtmp_playpath参数来解决该错误,下面先列举一个推流的例子

ffmpeg -re -i input.mp4 -c copy -f flv -rtmp_app myapp -rtmp_playpath hls rtmp://192.168.100.12:1935

    执行完这条命令行之后,推流将会成功,因为其设置了rtmp_app与rtmp_playpath两个参数,分别发布点live与流名称class。执行后的输出结果如下:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:35.07, start: 0.000000, bitrate: 2661 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 2493 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 159 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Output #0, flv, to 'rtmp://192.168.100.12:1935':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.34.102
  Stream #0:0(und): Video: h264 (High) ([7][0][0][0] / 0x0007), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2493 kb/s, 30 fps, 30 tbr, 1k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Audio: aac (LC) ([10][0][0][0] / 0x000A), 48000 Hz, stereo, fltp, 159 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame=  202 fps= 30 q=-1.0 size=    2160kB time=00:00:06.63 bitrate=2667.2kbits/s speed=   1x

    输出信息为链接成功,表示推流(发布流)成功。
    流发布成功后,可以用同样的方式测试播放RTMP流:

ffmpeg -rtmp_app myapp -rtmp_playpath hls -i rtmp://192.168.100.12:1935 -c copy -f flv output.flv

    执行完这条命令之后,将会成功地从RTMP服务器中拉取直播流,保存为output.flv,因为设置了rtmp_app与rtmp_playpath参数,执行效果如下:

Input #0, flv, from 'rtmp://192.168.100.12:1935':
  Metadata:
    |RtmpSampleAccess: true
    Server          : NGINX RTMP (github.com/arut/nginx-rtmp-module)
    displayWidth    : 1920
    displayHeight   : 1080
    fps             : 30
    profile         :
    level           :
  Duration: 00:00:00.00, start: 0.067000, bitrate: N/A
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 2492 kb/s, 30 fps, 30 tbr, 1k tbn
  Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 159 kb/s
File 'output.flv' already exists. Overwrite? [y/N] y
Output #0, flv, to 'output.flv':
  Metadata:
    |RtmpSampleAccess: true
    Server          : NGINX RTMP (github.com/arut/nginx-rtmp-module)
    displayWidth    : 1920
    displayHeight   : 1080
    fps             : 30
    profile         :
    level           :
    encoder         : Lavf59.34.102
  Stream #0:0: Video: h264 (High) ([7][0][0][0] / 0x0007), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2492 kb/s, 30 fps, 30 tbr, 1k tbn
  Stream #0:1: Audio: aac (LC) ([10][0][0][0] / 0x000A), 48000 Hz, stereo, fltp, 159 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame=  246 fps= 10 q=-1.0 size=    2816kB time=00:00:27.56 bitrate= 836.9kbits/s speed=1.16x

    之所以能够成功地推流与拉流,是因为设置rtmp_app与rtmp_playpath起到了作用。如果认为设置rtmp_app与rtmp_playpath太麻烦,那么可以省略这两个参数,直接将参数设置在RTMP的连接中即可:

ffmpeg -i input.mp4 -c copy -f flv rtmp://192.168.100.12:1935/myapp/hls

    发布流可以通过这种方式直接进行发布,其中myapp为发布点,hls为流名称,推流成功,并且推流的信息与使用rtmp_app和rtmp_playpath组合起来的效果相同,可以通过抓包工具分析出来。

ffmpeg -i rtmp://192.168.100.12:1935/myapp/hls -c copy -f flv output.flv

    与推流的链接相同,将发布点与流名称同时放在URL中进行拉流录制,至此,rtmp_app与rtmp_playpath参数介绍完毕。

   3.rtmp_pageurl、rtmp_swfurl、rtmp_tcurl参数

    在RTMP的Connect命令中包含了很多Object,这些Object中有一个pageUrl,例如通过页面的Flashplayer进行播放,RTMP的Connect命令中包含的pageUrl如。在使用FFmpeg发起播放时,不会在Connect命令中携带pageUrl字段,如图所示。
在这里插入图片描述
    FFmpeg可以使用rtmp_pageurl来设置这个字段,以做标识,这个标识与HTTP请求中的referer防盗链基本可以认为是起相同作用的,在RTMP服务器中可以根据这个信息进行referer防盗链操作。使用FFmpeg的rtmp_pageurl参数可以设置pageUrl,例如设置一个192.168.100.10:1935:

ffmpeg -rtmp_pageurl "192.168.100.10:1935" -i rtmp://192.168.100.10:1935/myapp/hls

    执行完这条命令行之后,使用抓包工具抓包可以看到Connect命令中包含了pageUrl一项,值为myapp,这个值可通过ffmpeg -rtmp_pageurl设置生效。

  5.2 FFmpeg录制RTSP流

    提到直播流媒体,RTSP曾经是最常见的直播方式。如今在安防领域中其依然常见,互联网中虽然已经大多数转向RTMP、HTTP+FLV、HLS、DASH等方式,但依然还是有很多场景在使用RTSP,所以这里先来介绍一下RTSP。众所周知,实时直播的优点为实时性,如果直播过后再想回溯之前发生的实时情况时,则需要录制与存储的技术来做支撑,FFmpeg可以满足这个技术,下面就来介绍一下FFmpeg的RTSP支持的参数。

  5.2.1 RTSP参数说明

    在使用FFmpeg处理RTSP之前,首先需要了解RTSP都有哪些参数,执行ffmpeg -h demuxer=RTSP命令行将会输出RTSP相关的协议读取操作参数。
在这里插入图片描述
    从表中所列的参数可以看出,RTSP传输协议可以有多种方式,不仅可以通过UDP,还可以通过TCP、HTTP隧道等,下面就来根据上述参数进行举例说明。

  5.2.2 RTSP参数使用举例

    使用RTSP拉流时,时常会遇到因为采用UDP方式而导致拉流丢包出现异常,所以在实时性与可靠性适中时,可以考虑采用TCP的方式进行拉流。

   1.TCP方式录制RTSP直播流

    FFmpeg默认使用的RTSP拉流的方式为UDP传输方式,为了避免丢包导致的花屏、绿屏、灰屏、马赛克等问题,还可以考虑将UDP传输方式改为TCP传输方式:

ffmpeg -rtsp_transport tcp -i rtsp://admin:[email protected]:554/h264/ch33/sub/av_stream -ar 22050 -c:v libx264 -f mp4 output.mp4
Input #0, rtsp, from 'rtsp://admin:[email protected]:554/h264/ch33/sub/av_stream':
  Metadata:
    title           : Media Presentation
  Duration: N/A, start: 0.000000, bitrate: N/A
  Stream #0:0: Video: h264 (Main), yuvj420p(pc, bt709, progressive), 704x576, 25 fps, 25 tbr, 90k tbn
  Stream #0:1: Audio: pcm_alaw, 8000 Hz, mono, s16, 64 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (pcm_alaw (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 00000236e7d0a700] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 00000236e7d0a700] profile High, level 3.0, 4:2:0, 8-bit
[libx264 @ 00000236e7d0a700] 264 - core 164 r3101 b093bbe - H.264/MPEG-4 AVC codec - Copyleft 2003-2022 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=9 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'output.mp4':
  Metadata:
    title           : Media Presentation
    encoder         : Lavf59.34.102
  Stream #0:0: Video: h264 (avc1 / 0x31637661), yuvj420p(pc, bt709, progressive), 704x576, q=2-31, 25 fps, 12800 tbn
    Metadata:
      encoder         : Lavc59.54.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
  Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 22050 Hz, mono, fltp, 69 kb/s
    Metadata:
      encoder         : Lavc59.54.100 aac
frame=   35 fps= 13 q=28.0 size=       0kB time=00:00:03.66 bitrate=   0.1kbits/s speed= 1.4x

    从输出的内容可以看出,FFmpeg已经从,将海康相机RTSP流,并且将其录制到本地存储为output.mp4。
    RTSP录制流建连接时,可以通过抓网络传输的包看到交互内容,内容如下:

Request: OPTIONS rtsp://192.168.100.17:554/h264/ch33/sub/av_stream RTSP/1.0\r\n
CSeq: 1\r\n
User-Agent: Lavf59.34.102\r\n
Response: RTSP/1.0 200 OK\r\n
CSeq: 1\r\n
Public: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER\r\n

    以上内容为RTSP标准中查询RTSP服务器所支持的方法所包含的内容。从输出的列表中可以看到该RTSP支持:DESCRIBE、SETUP、TEARDOWN、PLAY、PAUSE、OPTIONS、GET_PARAMETER、SET_PARAMETER;查询完成之后,继续进入下一步。

Request: DESCRIBE rtsp://192.168.100.17:554/h264/ch33/sub/av_stream RTSP/1.0\r\n
Accept: application/sdp\r\n
CSeq: 2\r\n
User-Agent: Lavf59.34.102\r\n

Response: RTSP/1.0 200 OK\r\n
 CSeq: 3\r\n
 Content-type: application/sdp
 Content-Base: rtsp://192.168.100.17:554/h264/ch33/sub/av_stream/\r\n
 Content-length: 758
Session Description Protocol
    Session Description Protocol Version (v): 0
    Owner/Creator, Session Id (o): - 1679930691333247 1679930691333247 IN IP4 192.168.100.17
    Session Name (s): Media Presentation
    E-mail Address (e): NONE
    Bandwidth Information (b): AS:5100
    Time Description, active time (t): 0 0
    Session Attribute (a): control:rtsp://192.168.100.17:554/h264/ch33/sub/av_stream/
    Media Description, name and address (m): video 0 RTP/AVP 96
    Connection Information (c): IN IP4 0.0.0.0
    Bandwidth Information (b): AS:5000

    根据协议中的内容可以看到,FFmpeg与服务器之间又发起了DESCRIBE操作,RTSP服务器返回了流数据的描述,数据为视频数据,编码为H.264格式,通过RTP进行传输;接下来进入下一步:

Request: SETUP rtsp://192.168.100.17:554/h264/ch33/sub/av_stream/trackID=1 RTSP/1.0\r\n
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
CSeq: 4\r\n
User-Agent: Lavf59.34.102\r\n

Response: RTSP/1.0 200 OK\r\n
CSeq: 4\r\n
Session: 1518403376;timeout=60
Transport: RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=05eaf54b;mode="play"

    从输出的协议内容中可以看到,这一步为设置SETUP操作,建立会话,以后的交互都将通过该会话Session进行标识,得到Session之后再继续进入下一步。

   Request: PLAY rtsp://192.168.100.17:554/h264/ch33/sub/av_stream/ RTSP/1.0\r\n
   Range: npt=0.000-\r\n
   CSeq: 6\r\n
   User-Agent: Lavf59.34.102\r\n
   Session: 1518403376

    从SETUP得到Session之后,带着这个Session发起PLAY操作,得到RTSP服务器的OK状态之后,即可进入接收视频数据的操作,也就是播放操作或录制操作等,如果希望退出播放,或者停止录制,则可以通过TEARDOWN来操作。

Request: TEARDOWN rtsp://192.168.100.17:554/h264/ch33/sub/av_stream/ RTSP/1.0\r\n
CSeq: 7\r\n
User-Agent: Lavf59.34.102\r\n
Session: 1518403376

    从上述协议内容中可以看到,接收数据的时候发起了TEARDOWN,服务器关闭了Session,整个会话结束

   2.User-Agent设置参数

    为了在访问的时候区分是不是自己访问的流,可以通过设置User-Agent进行区别,设置一个比较有特点的User-Agent做标识即可,下面就来举例说明如何设置User-Agent进行访问。

ffmpeg -user-agent "ChinaFFmpeg-Player" -i rtsp://admin:[email protected]:554/h264/ch33/sub/av_stream -ar 22050 -c:v libx264 -f mp4 -y output.mp4

    执行这条命令行之后,即设置了User-Agent,进行抓包后分析过程时可以看到包中的User-Agent已经设置生效。

  5.3 FFmpeg录制HTTP流

    在流媒体服务当中,HTTP服务最为常见,尤其是点播。当然,直播也支持HTTP服务,例如使用HTTP传输FLV直播流、使用HTTP传输TS直播流,或者使用HTTP传输M3U8以及TS文件等。

  5.3.1 HTTP参数说明

    在FFmpeg中支持HTTP进行流媒体的传输,无论是直播还是点播,均可以采用HTTP,而FFmpeg既可以作为播放器,也可以作为服务器进行使用,使用时针对HTTP,FFmpeg有很多参数都可以使用,下面就来看一下FFmpeg中的HTTP都可以支持哪些参数,具体见表。
在这里插入图片描述
关于FFmpeg的HTTP参数均已在表中列举出,例如设置HTTP请求时的HTTP头、设置User-Agent信息等;上述参数均是FFmpeg作为播放器或服务器的常用参数。

  5.3.2 HTTP参数使用举例

    从表所示的参数列表中可以看到,FFmpeg的HTTP既可以作为客户端使用,又可以作为服务器端使用,FFmpeg作为客户端使用的场景更多,所以本节专门针对客户端使用进行举例。

   1.seekable参数举例

    在使用FFmpeg打开直播或者点播文件时,可以通过seek操作进行播放进度移动、定位等操作:

ffmpeg -ss 300 -seekable 0 -i http://192.168.100.10/test.ts -c copy output.mp4

    命令执行时,若seekable设置为0,则FFmpeg的参数ss指定seek的时间位置。因为seekable参数是0,所以会一直处于阻塞状态。而下面这条命令则会出现另外一种情况:

ffmpeg -ss 30 -seekable 1 -i http://bbs.chinaffmpeg.com/test.ts -c copy -y output.mp4

    若seekable设置为1,则命令行执行后输出如下:

Input #0, mpegts, from 'http://120.24.33.118/input.ts':
  Duration: 00:00:08.38, start: 9.756522, bitrate: 2615 kb/s
  Program 1
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
  Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720, 30 fps, 30 tbr, 90k tbn
  Stream #0:1[0x101](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 4 kb/s
Output #0, mp4, to 'output.mp4':
  Metadata:
    encoder         : Lavf59.34.102
  Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1280x720, q=2-31, 30 fps, 30 tbr, 90k tbn
  Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 4 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame=  250 fps= 17 q=-1.0 Lsize=    2596kB time=00:00:08.28 bitrate=2565.6kbits/s speed=0.561x
video:2582kB audio:5kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.355639%

    因为seekable设置为1,因此FFmpeg可以对HTTP服务进行seek操作,自然不会再有任何异常。

   2.headers参数举例

    在使用FFmpeg拉取HTTP数据时,很多时候会遇到需要自己设置HTTP的header的情况,例如使用HTTP传输时在header中设置referer字段等操作,下面就来列举一个设置Referer参数的例子:

ffmpeg -headers "referer: http://192.168.100.10/index.html" -i http://192.168.100.10/input.ts -c copy -f flv -y output.flv

    执行完这条命令行之后,即可以在HTTP传输时在header中增加referer字段,使用Wireshark抓包可以看到详细信息:

    GET /input.ts HTTP/1.1\r\n
    User-Agent: Lavf/59.34.102\r\n
    Accept: */*\r\n
    Range: bytes=0-\r\n
    Connection: close\r\n
    Host: 120.24.33.118\r\n
    Icy-MetaData: 1\r\n
    \r\n
    [Full request URI: http://192.168.100.10/input.ts]
    [HTTP request 1/1]

    如上述抓包信息所示,在HTTP的header中增加了referer字段,referer的值为http://192.168.100.10/index.html。可见HTTP的headers信息已经设置成功。

   3.user_agent参数设置

    在使用FFmpeg进行HTTP连接时,所使用的User-Agent也有自己的特殊标识,FFmpeg连接HTTP时采用的默认User-Agent如下所示:

GET /live/class.flv HTTP/1.1
User-Agent: Lavf/57.71.100
Accept: */*
Range: bytes=0-
Connection: close
Host: play.chinaffmpeg.com
Icy-MetaData: 1

    从协议包中可以看到,FFmpeg使用的默认User-Agent为Lavf。在使用FFmpeg连接HTTP时,为了区分FFmpeg是自己的,可以通过参数user_agent进行设置:

ffmpeg -user_agent "LiuQi's Player" -i http://192.168.100.10/1.flv

    命令行执行后,User-Agent即被设置为LiuQi’s Player,下面看一下执行后的效果:

ffmpeg -user_agent "LiuQi's Player" -i http://192.168.100.10/1.flv

    从上述协议包中可以看到,执行效果与预期相同User-Agent设置成功。

  5.3.3 HTTP拉流录制

    粗略地了解了HTTP参数之后,接下来即可对HTTP服务器中的流媒体流进行录制,其不仅可以录制,还可以进行转封装,例如从HTTP传输的FLV直播流录制为HLS(M3U8)、MP4、FLV等,只要录制的封装格式支持流媒体中包含的音视频编码,就可以进行拉流录制。

  5.3.4 拉取HTTP中的流录制FLV

    1)拉取FLV直播流录制为FLV:

ffmpeg -i http://121.23.34.118/123.flv -c copy -f flv output.flv

    2)拉取TS直播流录制为FLV:

ffmpeg -i http://121.23.34.118/live.ts -c copy -f flv output.flv

    3)拉取HLS直播流录制为FLV:

ffmpeg -i http://121.23.34.118/live.m3u8 -c copy -f flv output.flv

    通过以上三个例子可以看到,转封装录制的输出相同,输入略有差别,但均为HTTP传输协议的直播流。

  5.4 FFmpeg录制和发布UDP/TCP流

    FFmpeg支持流媒体时不仅仅支持RTMP、HTTP这类高层协议,同样也支持UDP、TCP这类底层协议,而且还可以支持UDP、TCP流媒体的录制与发布,下面就来参考一下TCP与UDP支持的相关参数。

  5.4.1 TCP与UDP参数说明

    FFmpeg对于TCP与UDP操作也支持很多参数进行组合,可以通过ffmpeg–help full查看FFmpeg支持的UDP与TCP的参数,分别见表。
在这里插入图片描述
在这里插入图片描述

  5.4.2 TCP参数使用举例

    使用FFmpeg既可以进行TCP的监听,也可以使用FFmpeg进行TCP的链接请求,使用TCP监听与请求可以是对称方式,下面举几个例子。

   1.TCP监听接收流

    表中介绍了TCP端口监听模式,使用方式如下:

ffmpeg -listen 1 -f flv -i tcp://127.0.0.1:1234/live/stream -c copy -f flv output.flv

    执行完命令行之后,FFmpeg会进入端口监听模式,等待客户端连接到本地的1234端口。

   2.TCP请求发布流

    上文介绍了TCP端口监听模式接收流,这里介绍一下FFmpeg请求TCP并发布流,使用方式如下:

ffmpeg -re -i input.mp4 -c copy -f flv tcp://127.0.0.1:1234/live/stream

    前文介绍过TCP监听端口为1234,这里请求的端口即为1234,并且指定输出的格式为FLV格式,因为TCP监听接收流时指定了接收FLV格式的流,下面就来看一下这条命令行执行之后的输出:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:35.07, start: 0.000000, bitrate: 2661 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 2493 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 159 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Output #0, flv, to 'tcp://127.0.0.1:1234/live/stream':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.34.102
  Stream #0:0(und): Video: h264 (High) ([7][0][0][0] / 0x0007), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2493 kb/s, 30 fps, 30 tbr, 1k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Audio: aac (LC) ([10][0][0][0] / 0x000A), 48000 Hz, stereo, fltp, 159 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[flv @ 000002998004ffc0] Failed to update header with correct duration.7.8kbits/s speed=   1x

    输出成功,推流成功,推流格式为FLV,推流地址为tcp://127.0.0.1:1234/live/stream。
    当这里发布流成功后,在端口监听一端同样也会有数据的输出,因为在前面介绍端口监听时,输入为FLV格式,输出为output.flv的FLV格式,所以可以在监听一端看到输出信息:

Input #0, flv, from 'tcp://127.0.0.1:1234/live/stream':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.34.102
  Duration: 00:00:00.00, start: 0.067000, bitrate: N/A
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 2493 kb/s, 30 fps, 30 tbr, 1k tbn
  Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 159 kb/s
Output #0, flv, to 'output.flv':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.34.102
  Stream #0:0: Video: h264 (High) ([7][0][0][0] / 0x0007), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 2493 kb/s, 30 fps, 30 tbr, 1k tbn
  Stream #0:1: Audio: aac (LC) ([10][0][0][0] / 0x000A), 48000 Hz, stereo, fltp, 159 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 1052 fps= 31 q=-1.0 Lsize=   11404kB time=00:00:34.98 bitrate=2670.2kbits/s speed=1.04x

    当监听TCP时指定格式与TCP客户端连接所发布的格式相同时均正常,如果TCP监听的输入格式与TCP客户端连接时所发布的格式不同时,将会出现解析格式异常,例如将请求发布流时的格式改为MPEGTS格式,监听端将无法正常解析格式而处于“无动于衷”的状态。

   3.监听端口超时listen_timeout

    监听端口时,默认处于持续监听状态,通过使用listen_timeout可以设置指定时间长度监听超时,例如设置5秒钟超时时间,到达超时时间则退出监听:

time ffmpeg -listen_timeout 5000 -listen 1 -f flv -i tcp://127.0.0.1:1234/live/stream -c copy -f flv output.flv

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

real	0m5.110s
user	0m0.001s
sys	0m0.003s

    从输出的内容中可以看到,超时时间为5秒,5秒钟若未收到任何请求则自动退出监听。

   4.TCP拉流超时参数timeout

    使用TCP拉取直播流时,常常会遇到TCP服务器端没有数据却不主动断开连接的情况,导致客户端持续处于连接状态不断开,通过设置timeout参数可以解决这个问题。例如拉取一个TCP服务器中的流数据,若超过20秒没有数据则退出,实现方式如下:

time ./ffmpeg -timeout 20000000 -i tcp://127.0.0.1:1935/live/stream -c copy -f flv output.flv

    这条命令行设置超时时间为20秒,连接TCP拉取端口1935的数据,如果超过20秒没有收到数据则自动退出,命令行执行后的效果如下:

real	0m20.139s
user	0m0.004s
sys	0m0.004s

    从以上输出的内容中可以看到,命令行执行耗时时长为20秒,设置超时时间生效

   5.TCP传输buffer大小设置send_buffer_size/recv_buffer_size

    在TCP参数列表中可以看到send_buffer_size与recv_buffer_size参数,这两个参数的作用是设置TCP传输时buffer的大小,buffer设置得越小,传输就会越频繁,网络开销就会越大

ffmpeg -re -i input.mp4 -c copy -send_buffer_size 265 -f flv tcp://127.0.0.1:1234/live/stream

    执行完这条命令行之后输出速度将会变慢,因为数据发送的buffer大小变成了265,数据发送的频率变大,并且次数变多,网络的开销也变大,所以输出速度会变慢,命令行执行后相关的输出信息如下:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.34.102
  Duration: 00:01:10.47, start: 0.000000, bitrate: 2507 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1280x720, 2496 kb/s, 30 fps, 30 tbr, 16k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 2 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Output #0, flv, to 'tcp://127.0.0.1:1234/live/stream':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Stream #0:0(und): Video: h264 (High) ([7][0][0][0] / 0x0007), yuv420p(progressive), 1280x720, q=2-31, 2496 kb/s, 30 fps, 30 tbr, 1k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Audio: aac (LC) ([10][0][0][0] / 0x000A), 44100 Hz, stereo, fltp, 2 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[flv @ 0x35f5dc0] Failed to update header with correct duration.ate=2511.3kbits/s speed=   1x   

    从FFmpeg执行过程的内容中可以看到速度降低了,不仅仅是输出速度降低了,输出帧率也降低了。Data的大小为265字节,参数send_buffer_size设置成功。

   6.绑定本地UDP端口localport

    使用FFmpeg的UDP传输数据时,默认会由系统分配本地端口,使用localport参数时可以设置监听本地端口

ffmpeg -re -i input.mp4 -c copy -localport 23456 -f flv udp://192.168.100.179:1234/live/stream

    命令行执行后可以看到相关输出如下:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.34.102
  Duration: 00:01:10.47, start: 0.000000, bitrate: 2507 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1280x720, 2496 kb/s, 30 fps, 30 tbr, 16k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 2 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Output #0, flv, to 'udp://127.0.0.1:1234/live/stream':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Stream #0:0(und): Video: h264 (High) ([7][0][0][0] / 0x0007), yuv420p(progressive), 1280x720, q=2-31, 2496 kb/s, 30 fps, 30 tbr, 1k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1(und): Audio: aac (LC) ([10][0][0][0] / 0x000A), 44100 Hz, stereo, fltp, 2 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[flv @ 0x2b3fdc0] Failed to update header with correct duration.ate=2511.6kbits/s speed=   1x

    输出的时候可以使用netstat查看,也可以使用Wireshark抓取UDP包进行确认,UDP的Source Port已经成功设置为23456,可见localport参数设置生效。

  5.4.3 TCP/UDP使用小结

    FFmpeg的TCP与UDP传输常见于TCP或者UDP的网络裸传输场景。

  5.5 FFmpeg推多路流

    早期FFmpeg在转码后输出直播流时并不支持编码一次之后同时输出多路直播流,需要使用管道方式进行输出,而在新版本的FFmpeg中已经支持tee文件封装及协议输出,可以使用tee进行多路流输出,本节将主要讲解管道方式输出多路流tee协议输出方式输出多路流

  5.5.1 管道方式输出多路流

    使用FFmpeg进行编码与转封装,编码消耗的资源比较多,转封装则相对较少,很多时候只需要转一次编码并且输出多个封装,早期FFmpeg本身并不支持这么做,尤其是一次转码多次输出RTMP流等操作,而是通过使用系统管道的方式进行操作,方式如下:

ffmpeg -i input -acodec aac -vcodec libx264 -f flv - | ffmpeg -f mpegts -i - -c copy output1 -c copy output2 -c copy output3

    从命令行格式中可以看到,音频编码为AAC,视频编码为libx264,输出格式为FLV,然后输出之后通过管道传给另一条ffmpeg命令,另一条ffmpeg命令直接执行对codec的copy即可实现一次编码多路输出:

ffmpeg -i input.mp4 -vcodec libx264 -acodec aac -f flv - | ffmpeg -f flv -i - -c copy -f flv rtmp://127.0.0.1:1935/myapp/stream1 -c copy -f flv rtmp://127.0.0.1:1935/myapp/stream2

    执行完这条命令之后,将会在RTMP服务器127.0.0.1中包含两路直播流,一路为stream1,另外一路为stream2,两路直播流的信息相同,下面用FFmpeg验证一下:

ffmpeg -i rtmp://127.0.0.1:1935/myapp/stream1  -i rtmp://127.0.0.1:1935/myapp/stream2

    如上述输出内容所示,两路直播流信息几乎一样,因为在编码推流时采用的是一次编码,多次输出支持所得到的流。

  5.5.2 tee封装格式输出多路流

    FFmpeg输出时支持tee封装格式输出,使用-f tee方式制定输出格式即可,下面就来看一下tee封装格式一次编码多路输出的方式:

ffmpeg -i input.flv -acodec aac -vcodec h264 -f tee -map 0:v -map 0:a "tee1.mp4|tee2.flv"
# 1. 单路输入,输出一路mp4本地,一路TS over UDP (其中TS over UDP需要指定格式)
ffmpeg -re -i input.mp4 -acodec aac -vcodec h264 -f tee -map 0:v -map 0:a "tee1.mp4|[f=mpegts]udp://121.24.33.118:1514"
# 2. 使用ffmpeg进行编码,实现单路输入,四路输出(一路rtmp,一路ts,一路mp4,一路aac)。
ffmpeg -re -i input.mp4 -acodec aac -vcodec h264 -flags +global_header -strict experimental -f tee -map 0:v -map 0:a "[f=flv]rtmp://121.24.33.118:1935/myapp/hls|[bsfs/v=dump_extra]out.ts|[movflags=+faststart]out.mp4|[select=a]out.aac"
ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -map 0 -flags +global_header -strict experimental -f tee "[f=flv]rtmp://121.24.33.118:1935/myapp/stream1 | [f=flv]rtmp://121.24.33.118:1935/myapp/stream2"

    执行完命令行之后,ffmpeg编码一次,输出tee封装格式,格式中包含两个FLV格式的RTMP流,一路为stream1,另一路为stream2。执行后的输出信息如下:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:35.07, start: 0.000000, bitrate: 2661 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 2493 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 159 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
Output #0, tee, to '[f=flv]rtmp://121.24.33.118:1935/myapp/stream1 | [f=flv]rtmp://121.24.33.118:1935/myapp/stream2':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.34.102
  Stream #0:0(und): Video: h264, yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 30 fps, 30 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.54.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
  Stream #0:1(und): Audio: aac (LC), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.54.100 aac
frame= 1052 fps= 30 q=-1.0 Lsize=N/A time=00:00:34.98 bitrate=N/A speed=0.981x

    从上述输出内容中可以看到,使用tee封装格式推多路RTMP流成功,接下来可以验证服务器端是否存在两路相同的直播RTMP流:

ffmpeg -i rtmp://121.24.33.118:1935/myapp/stream1  -i rtmp://121.24.33.118:1935/myapp/stream2

    经过验证,确认使用tee推流成功,现在流媒体服务器中存在两路相同的直播流。

  5.5.3 tee协议输出多路流

    FFmpeg在3.1.3版本之后支持tee协议输出多路流,使用方式比前文介绍的FFmpeg配合管道与tee封装格式更简单,下面详细举例说明:

ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -f flv "tee:rtmp://publish.chinaffmpeg.com/live/stream1|rtmp://publish.chinaffmpeg.com/live/stream2"

    执行命令行之后,FFmpeg执行了一次编码,然后输出为tee协议格式,tee中包含了两个子链接,协议全部为RTMP,输出两路RTMP流,一路为stream1,另一路为stream2

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.27.100
  Duration: 00:00:35.07, start: 0.000000, bitrate: 2661 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 2493 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 159 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
Output #0, flv, to 'tee:rtmp://120.24.33.118:1935/myapp/stream1|rtmp://120.24.33.118:1935/myapp/hls':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.34.102
  Stream #0:0(und): Video: h264 ([7][0][0][0] / 0x0007), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 30 fps, 1k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.54.100 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
  Stream #0:1(und): Audio: aac (LC) ([10][0][0][0] / 0x000A), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc59.54.100 aac
[flv @ 000001d3122202c0] Failed to update header with correct duration.9.6kbits/s speed=0.998x

    如上述输出内容所示,推流成功,两路直播流相同与否,可以通过验证FFmpeg配合管道的方式或验证tee封装支持的方式进行检测,结果将会是相同的。

  5.6 FFmpeg生成HDS流

    FFmpeg支持文件列表方式的切片直播、点播流,除了HLS之外,还支持HDS流切片格式,使用FFmpeg可以生成HDS切片。

  5.6.1 HDS参数说明

    使用ffmpeg -h muxer=hds可以得到HDS的参数列表,下面就来看一下HDS相关的操作参数都有哪些。
在这里插入图片描述
    如表所示,FFmpeg中做HDS格式封装主要包含四个参数,分别为HDS切片信息窗口大小、HDS切片信息窗口之外保留的切片文件个数、最小切片时间、在HDS封装结束时删除所有文件。下面就来对这些参数进行举例说明。

  5.6.2 HDS使用举例

    由于FFmpeg生成HDS文件与HLS类似,既可以生成点播文件列表,也可以生成直播文件列表;既可以保留历史文件,也可以刷新历史文件窗口大小,以上这些操作均可以通过参数进行控制。

   1.window_size参数控制文件列表大小

    设置HDS为直播模式时,需要实时更新列表,可以通过window_size参数控制文件列表窗口大小,例如HDS文件列表中只保存4个文件,通过设置window_size即可实现,下面举例说明:

ffmpeg -i input -c copy -f hds -window_size 4 output

    执行完以上命令行之后,会生成output目录,目录下面包含三种文件,具体如下。
    ·index.f4m:索引文件,主要为F4M参考标准中mainfest相关、Metadata信息等
    ·stream0.abst:文件流相关描述信息
    ·stream0Seg1-Frag:相似规则文件切片,文件切片中均为mdat信息
    生成output目录信息如下:


    使用window_size控制列表大小生效,默认不控制生成列表的大小。

   ;2.extra_window_size参数控制文件个数

    在控制window_size之后,HLS切片的情况与之类似,列表之外的文件会有一些残留,通过使用extra_window_size可以控制残留文件个数:
    将extra_window_size设置为1,则会在window_size之外多留一个历史文件,下面就来执行命令行测试一下:

ffmpeg -re -i input.mp4 -c copy -f hds -window_size 4 -extra_window_size 1 output

    命令行执行之后,将会在output目录生成HDS文件,这要比window_size规定的窗口大小之外多出来1个文件,下面就来看一下效果:
在这里插入图片描述

   3.其他参数

    remove_at_exit参数在FFmpeg退出时会删除所有生成的文件,如果min_frag_duration参数的值设置得比较小并且设置在使用codec copy时不会有效果,则需要在重新编码时将GOP间隔设置得比min_frag_duration时间短即可。

  5.7 FFmpeg生成DASH流

    列表类型直播除了HLS与HDS之外,还有一种比较流行的列表方式是DASH方式直播,下面就来介绍一下FFmpeg的DASH参数。

  5.7.1 DASH参数说明

    使用ffmpeg -h muxer=dash可以得到DASH的参数列表,下面就来看一下DASH都有哪些相关操作的参数,具体见表。
在这里插入图片描述
    从表中可以看出,对于DASH的封装操作FFmpeg所支持的参数稍微多一些,例如除了与HDS相似的参数之外,还可以支持单文件模式是否使用timeline模式设置切片名等操作,下面就来举例说明对DASH封装操作的常见参数。

  5.7.2 DASH参数使用举例

   1.window_size与extra_window_size参数举例

    与HDS设置类似,DASH参数设置同样可以支持window_size与extra_window_size参数设置列表中的切片个数与列表外切片的保留个数,设置方式如下:

ffmpeg -re -i input.mp4 -c:v copy -acodec copy -f dash -window_size 4 -extra_window_size 5 index.mpd

    执行完命令行之后会生成文件索引列表index.mpd,文件列表长度为4个切片长度,切片之外会保留5个切片,在DASH直播格式中,音视频是分开切片的,也就是说视频是一路切片,音频是一路切片,即音频切片文件会有9个,视频切片文件会有9个,其中包含了2个初始化信息切片,1个索引文件,可以参考如下信息:

   2.single_file参数举例

    FFmpeg支持生成DASH时将切片列表中的文件写入到一个文件,使用single_file参数即可,参考命令行如下:

ffmpeg -re -i input.mp4 -c:v copy -acodec copy -f dash -window_size 4 -extra_window_size 5 -single_file 1 index.mpd

    执行命令行之后,目录中将会生成3个文件:1个索引文件、1个音频文件、1个视频文件,可参考的信息如下:
在这里插入图片描述

  5.8 小结

    FFmpeg对流媒体的支持非常广泛,本章重点介绍RTMP、RTSP、TCP、UDP、HLS、HDS、DASH相关的支持情况,主要以推流、生成为主,以及对FFmpeg支持的HTTP传输参数做简略的分析,阅读完本章之后,将会对流媒体协议有一个基本的了解,并能够使用工具进行常规的媒体信息分析。

猜你喜欢

转载自blog.csdn.net/migu123/article/details/129313756