这个流媒体的理解我认为就是我们看到的音视频文件,然后通过互联网来进行传递的一种处理音视频流媒体的压缩,录制,编辑等操作。FFmpeg比较强大可以实现这些功能。

FFmpeg发布与录制RTMP流

首先简单了解一下RTMP:
它是直播中最为常见的一种实时直播流,详细的介绍与描述我找了一篇文章看了一下查看
因为直播的RTMP是出现了就没有的,我们可以通过FFmpeg把它录制下来,就是说只要有一个RTMP地址就可以录制下来,这个还是很方便的。

RTMP参数介绍

  • rtmp_app:RTMP流发布点
  • rtmp_buffer:客户端buffer大小(单位:毫米),默认为3秒
  • rtmp_conn:在RTMP的Connect命令中增加自定义AMF数据
  • rtmp_flashver:设置模拟的flashplugin的版本号
  • rtmp_live:指定RTMP流媒体播放类型(any:直播或点播随意 live:直播 recorded:点播)
  • rtmp_pageurl:播放时所在Web页面URL
  • rtmp_playpath:RTMP流播放Stream地址
  • rtmp_subscribe:直播流名称,默认为rtmp_playpath的值
  • rtmp_swfhash:解压swf文件后的SHA256的hash值
  • rtmp_swfsize:swf文件解压后的大小
  • rtmp_swfurl:RTMP的Connect命令中设置的swfURL播放器RRL
  • rtmp_swfverify:设置swf认证时swf文件的URL地址
  • rtmp_tcurl:RTMP的Connect命令中设置的tcURL目标发布点地址
  • rtmp_listen:开启RTMP服务时所监听的端口
  • listen:与rtmp_listen相同
  • timeout:监听rtmp端口时设置的超时时间

rtmp_app

通过rtmp_app设置推流发布点,录制直播视频示例:

ffmpeg -rtmp_app live -i rtmp://live.hkstv.hk.lxdns.com/live/hks -c copy -f flv output.flv

发布流示例:

ffmpeg -re -i input.mp4 -c copy -f flv -rtmp_app live rtmp://publish.chinaffmpeg.com

这个会出现一个错误:
Server error: identify stream failed.这就要设置下面介绍的参数了
这里要一个流媒体的服务器我们就可以把本地的mp4文件推上去,之前有一篇搭建流媒体服务器的可以做到。查看

rtmp_playpath

添加这个参数来推流:

ffmpeg -re -i input.mp4 -c copy -f flv -rtmp_app live -rtmp_playpath class rtmp://publish.chinaffmpeg.com

上面这个rtmp的流地址是我看到书上面的一个地址,我们同样可以在本地搭建流媒体服务器的方式来换成自己的。
执行以后成功了。
现在保持我们推的直播流

ffmpeg -rtmp_app live -rtmp_playpath class -i rtmp://publish.chinaffmpeg.com -c copy -f flv output.flv

推流和拉流我们配置了两个参数rtmp_app和rtmp_playpath有一种简便方式不用写这两个参数,之间在rtmp地址中设置好
推流:

ffmpeg -i input.mp4 -c copy -f flv rtmp://publish.chinaffmpeg.com/live/class

拉流:

ffmpeg -i rtmp://publish.chinaffmpeg.com/live/class -c copy -f flv output.flv

FFmpeg录制RTSP流

通过命令ffmpeg -h demuxer=RTSP查看RTSP协议相关的配置参数。

TCP方式录制RTSP流

ffmpeg -rtsp_transport tcp -i rtsp://xxx -c copy -f mp4 output.mp4

FFmpeg录制HTTP流

HTTP流的流媒体服务器也是很常见的。我们看如何拉取这种流

ffmpeg -ss 30 -seekable 0 -i http://xxx -c copy output.mp4

命令执行后seekable设置为0,则FFmpeg的参数ss指定seek的时间位置。并且会一直处于阻塞状态。如果设置seekable为1则可以通过FFmpeg对HTTP服务进行seek操作,不会有异常情况

FFmpeg录制和发布UDP/TCP流

FFmpeg不止支持RTMP,HTTP这类高层协议,偏底层一点的TCP,UDP协议都支持。

TCP使用

  • TCP监听接受流
ffmpeg -listen 1 -f flv -i tcp://xxx -c copy -f flv output.flv
  • TCP请求发布流
ffmpeg -re -i input.mp4 -c copy -f flv tcp://xxx
  • 监听端口超时listen_timeout

超过监听5秒退出

ffmpeg -listen_timeout 5000 -listen 1 -f flv -i tcp://xxx -c copy -f flv output.flv
  • TCP拉流超时参数
ffmpeg -timeout 20000000 -i tcp://xxx -c copy -f flv output.flv
  • TCP传输buffer大小设置send_buffer_size/recv_buffer_size
    buffer设置越小,传输就会越频繁,网络开销就会越大
ffmpeg -re -i input.mp4 -c copy -send_buffer_size 265 -f flv tcp://xxx
  • 绑定本地UDP端口localport
    使用FFmpeg的UDP传输数据时,默认会由系统分配本地端口,使用localport参数时可以设置监听本地端口
ffmpeg -re -i input.mp4 -c copy -localport 23456 -f flv udp://xxx

FFmpeg推多路流

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

管道方式输出多路流

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

上述音频编码为acc,视频编码为libx264,输出格式为FLV,然后输出之后通过管道传给另一条ffmpeg命令对codec的copy可以实现一次编码多次输出

ffmpeg -i input.mp4 -vcodec libx264 -acodec acc -f flv - | ffmpeg -f flv -i - -c copy -f flv rtmp://xxx -c copy -f flv rtmp://xxx

执行完在RTMP服务器包含两路直播流。

tee封装格式输出多路流

ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -map 0 -f tee "[f=flv] rtmp://xxx | [f=flv] rtmp://xxx

命令执行以后编码一次输出tee封装格式,格式中包含两个FLV格式的RTMP流。

tee协议输出多路流

FFmpeg 3.1.3之后支持tee协议输出多路流。

ffmpeg -re -i input.mp4 -vcodec libx264 -acodec aac -f flv "tee:rtmp://xxx|rtmp://xxx"

这个命令好像比上面的都简单一些。

FFmpeg生成HDS流

通过命令ffmpeg -h muxer=hds可以查看HDS的参数

window_size参数控制文件列表大小

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

extra_window_size参数控制文件个数

window_size控制文件列表大小,extra_window_size可以控制残留文件个数

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

FFmpeg生成DASH流

列表类型直播除了HLS和HDS之外,还有一种比较流行的列表方式是DASH方式直播。通过命令行ffmpeg -h muxer=dash查看dash的一些参数
使用示例:

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个切片。生成的音频切片有9个视频切片有9个,其中包含2个初始化信息切片,1个索引文件。

通过参数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

执行完成生成一个索引文件,一个音频文件,一个视频文件。