转自:https://blog.youkuaiyun.com/xiejiashu/article/details/34434669
最近很多人问,如何将内网的摄像机流媒体数据发布到公网,如果用公网与局域网间的端口映射方式太过麻烦,一个摄像机要做一组映射,而且不是每一个局域网都是有固定ip地址,即使外网主机配置好了每一个摄像机的映射地址,也有可能会因为宽带公网ip地址变动而导致配置无效。
再换一个应用场景,当我们的所有IP摄像机都部署在一个没有有线网络的环境里面,所有的流媒体数据都要通过3G/4G网络发布出去。那么就必须有这么一个服务单元,能够通过先拉后推的方式,将内网的流媒体数据,推送并发布到外网的流媒体服务器上去:
在实现先拉后推式转发之前,我们先熟悉下live555的运转模式,live555主要运转的是一个source与sink的循环,sink想要数据,就调用source的getNextFrame,source获取到数据后,再调用afterGettingFrame回调,返回给sink数据,sink处理完后,再调用source的getNextFrame,如此循环。那么我们这里要实现从摄像机获取数据,那么我们的source就是一个RTPSource,我们又需要将数据以RTP的方式发送给流媒体服务器,那么我们的sink就是一个RTPSink,我们需要打通的就是一个RTPSource到一个RTPSink的过程。
ok,live555已经帮我们实现了大部分的功能,我们只需要将已有的部分组合起来就行了,这里我们主要用到的就是live555的ProxyServerMediaSession类和DarwinInjector类,我们用ProxyServerMediaSession从摄像机获取流媒体,再用DarwinInjector推送到Darwin Streaming Server,主要实现流程在下面代码注释中:
-
/*
-
功能描述: 一个简单的RTSP/RTP对接功能,从RTSP源通过基本的RTSPClient流程,获取到RTP流媒体数据
-
再通过标准RTSP推送过程(ANNOUNCE/SETUP/PLAY),将获取到RTP数据推送给Darwin流媒体
-
分发服务器。
-
此Demo只演示了单个源的转换、推送功能!
-
-
Author: sunpany@qq.com
-
时间: 2014/06/25
-
*/
-
-
#include "liveMedia.hh"
-
#include "BasicUsageEnvironment.hh"
-
#include "RTSPCommon.hh"
-
-
char* server =
"www.easydss.com";
//RTSP流媒体转发服务器地址,<请修改为自己搭建的流媒体服务器地址>
-
int port =
8554;
//RTSP流媒体转发服务器端口,<请修改为自己搭建的流媒体服务器端口>
-
char* streamName =
"live.sdp";
//流名称,推送到Darwin的流名称必须以.sdp结尾
-
char* src =
"rtsp://218.204.223.237:554/live/1/66251FC11353191F/e7ooqwcfbqjoo80j.sdp";
//源端URL
-
-
UsageEnvironment* env =
NULL;
//live555 global environment
-
TaskScheduler* scheduler =
NULL;
-
char eventLoopWatchVariable =
0;
-
-
DarwinInjector* injector =
NULL;
//DarwinInjector
-
FramedSource* vSource =
NULL;
//Video Source
-
FramedSource* aSource =
NULL;
//Audio Source
-
-
RTPSink* vSink =
NULL;
//Video Sink
-
RTPSink* aSink =
NULL;
//Audio Sink
-
-
Groupsock* rtpGroupsockVideo =
NULL;
//Video Socket
-
Groupsock* rtpGroupsockAudio =
NULL;
//Audio Socket