FFmpeg的推流器的作用就是将本地的视频数据推送至流媒体服务器。本文记录的推流器,可以将本地的 MOV / AVI / MKV / MP4 / FLV 等格式的媒体文件,通过流媒体协议(例如RTMP,HTTP,UDP,TCP,RTP等等)以直播流的形式推送出去。由于流媒体协议种类繁多,不一一记录。在这里记录将本地文件以RTMP直播流的形式推送至RTMP流媒体服务器(例如 Flash Media Server,Red5,Wowza等等)的方法。
在这个推流器的基础上可以进行多种方式的修改,实现各式各样的推流器。例如:
* 将输入文件改为网络流URL,可以实现转流器。
* 将输入的文件改为回调函数(内存读取)的形式,可以推送内存中的视频数据。
* 将输入文件改为系统设备(通过libavdevice),同时加上编码的功能,可以实现实时推流器(现场直播)。
PS:本程序并不包含视频转码的功能。
简介
RTMP推流器(Streamer)的在流媒体系统中的作用可以用下图表示。首先将视频数据以RTMP的形式发送到流媒体服务器端(Server,比如FMS,Red5,Wowza等),然后客户端(一般为Flash Player)通过访问流媒体服务器就可以收看实时流了。
需要要注意的地方
封装格式
RTMP采用的封装格式是FLV。因此在指定输出流媒体的时候需要指定其封装格式为“flv”。同理,其他流媒体协议也需要指定其封装格式。例如采用UDP推送流媒体的时候,可以指定其封装格式为“mpegts”。延时
发送流媒体的数据的时候需要延时。不然的话,FFmpeg处理数据速度很快,瞬间就能把所有的数据发送出去,流媒体服务器是接受不了的。因此需要按照视频实际的帧率发送数据。本文记录的推流器在视频帧与帧之间采用了av_usleep()函数休眠的方式来延迟发送。这样就可以按照视频的帧率发送数据了,参考代码如下。PTS/DTS问题
没有封装格式的裸流(例如H.264裸流)是不包含PTS、DTS这些参数的。在发送这种数据的时候,需要自己计算并写入AVPacket的PTS,DTS,duration等参数。这里还没有深入研究,简单写了一点代码,如下所示。程序流程图
程序的流程图如下图所示。可以看出和《 最简单的基于FFMPEG的封装格式转换器(无编解码) 》中的封装格式转换器比较类似。它们之间比较明显的区别在于:1. Streamer输出为URL
2. Streamer包含了延时部分