From dfe213abc3ee36daf4dcf1f92a3805d5d0495eca Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Mon, 29 Oct 2018 14:59:22 +0800 Subject: [PATCH] =?UTF-8?q?rtsp=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=BB=B6=E6=97=B6=E8=8E=B7=E5=8F=96RtspMediaSouce?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtsp/RtspSession.cpp | 132 +++++++++++++++++++++++++++++++-------- src/Rtsp/RtspSession.h | 5 ++ 2 files changed, 111 insertions(+), 26 deletions(-) diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 9eda9d07..42174fba 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -141,6 +141,13 @@ void RtspSession::onManager() { shutdown(); return; } + + if(_delayTask){ + if(time(NULL) > _iTaskTimeLine){ + _delayTask(); + _delayTask = nullptr; + } + } } @@ -226,33 +233,42 @@ bool RtspSession::handleReq_Describe() { _mediaInfo.parse(_parser.FullUrl()); } - if (!findStream()) { - //未找到相应的MediaSource - send_StreamNotFound(); - return false; - } + weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this());\ + auto parserCopy = _parser; + findStream([weakSelf,parserCopy](bool success){ + auto strongSelf = weakSelf.lock(); + if(!strongSelf){ + return; + } + //恢复现场 + strongSelf->_parser = parserCopy; + if(!success){ + //未找到相应的MediaSource + strongSelf->send_StreamNotFound(); + strongSelf->shutdown(); + return; + } + //该请求中的认证信息 + auto authorization = strongSelf->_parser["Authorization"]; + onGetRealm invoker = [weakSelf,authorization](const string &realm){ + if(realm.empty()){ + //无需认证,回复sdp + onAuthSuccess(weakSelf); + return; + } + //该流需要认证 + onAuthUser(weakSelf,realm,authorization); + }; - weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); - //该请求中的认证信息 - auto authorization = _parser["Authorization"]; - onGetRealm invoker = [weakSelf,authorization](const string &realm){ - if(realm.empty()){ - //无需认证,回复sdp - onAuthSuccess(weakSelf); - return; - } - //该流需要认证 - onAuthUser(weakSelf,realm,authorization); - }; - - //广播是否需要认证事件 - if(!NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastOnGetRtspRealm, - _mediaInfo, - invoker, - *this)){ - //无人监听此事件,说明无需认证 - invoker(""); - } + //广播是否需要认证事件 + if(!NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastOnGetRtspRealm, + strongSelf->_mediaInfo, + invoker, + *strongSelf)){ + //无人监听此事件,说明无需认证 + invoker(""); + } + }); return true; } void RtspSession::onAuthSuccess(const weak_ptr &weakSelf) { @@ -901,6 +917,70 @@ inline void RtspSession::send_NotAcceptable() { } +void RtspSession::doDelay(int delaySec, const std::function &fun) { + if(_delayTask){ + _delayTask(); + } + _delayTask = fun; + _iTaskTimeLine = time(NULL) + delaySec; +} + +void RtspSession::cancelDelyaTask(){ + _delayTask = nullptr; +} + +void RtspSession::findStream(const function &cb) { + bool success = findStream(); + if (success) { + cb(true); + return; + } + + weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); + auto task_id = this; + auto media_info = _mediaInfo; + + auto onRegist = [task_id, weakSelf, media_info, cb](BroadcastMediaChangedArgs) { + if (bRegist && + schema == media_info._schema && + vhost == media_info._vhost && + app == media_info._app && + stream == media_info._streamid) { + //播发器请求的rtmp流终于注册上了 + auto strongSelf = weakSelf.lock(); + if (!strongSelf) { + return; + } + //切换到自己的线程再回复 + //如果触发 kBroadcastMediaChanged 事件的线程与本RtspSession绑定的线程相同, + //那么strongSelf->async操作可能是同步操作, + //通过指定参数may_sync为false确保 NoticeCenter::delListener操作延后执行, + //以便防止遍历事件监听对象map时做删除操作 + strongSelf->async([task_id, weakSelf, media_info, cb]() { + auto strongSelf = weakSelf.lock(); + if (!strongSelf) { + return; + } + DebugL << "收到rtsp注册事件,回复播放器:" << media_info._schema << "/" << media_info._vhost << "/" + << media_info._app << "/" << media_info._streamid; + cb(strongSelf->findStream()); + //取消延时任务,防止多次回复 + strongSelf->cancelDelyaTask(); + + //取消事件监听 + //在事件触发时不能在当前线程移除事件监听,否则会导致遍历map时做删除操作导致程序崩溃 + NoticeCenter::Instance().delListener(task_id, Broadcast::kBroadcastMediaChanged); + }, false); + } + }; + + NoticeCenter::Instance().addListener(task_id, Broadcast::kBroadcastMediaChanged, onRegist); + //5秒后执行失败回调 + doDelay(5, [cb]() { + cb(false); + }); +} + inline bool RtspSession::findStream() { RtspMediaSource::Ptr pMediaSrc = dynamic_pointer_cast( MediaSource::find(RTSP_SCHEMA,_mediaInfo._vhost, _mediaInfo._app,_mediaInfo._streamid) ); diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index 5bf1ff64..5b7b6848 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -104,6 +104,7 @@ private: void inline send_SessionNotFound(); //会话id错误 void inline send_NotAcceptable(); //rtsp同时播放数限制 inline bool findStream(); //根据rtsp url查找 MediaSource实例 + inline void findStream(const function &cb); //根据rtsp url查找 MediaSource实例 inline void initSender(const std::shared_ptr &pSession); //处理rtsp over http,quicktime使用的 inline void sendRtpPacket(const RtpPacket::Ptr &pkt); @@ -143,6 +144,8 @@ private: static void onAuthBasic(const weak_ptr &weakSelf,const string &realm,const string &strBase64); static void onAuthDigest(const weak_ptr &weakSelf,const string &realm,const string &strMd5); + void doDelay(int delaySec,const std::function &fun); + void cancelDelyaTask(); private: char *_pcBuf = nullptr; Ticker _ticker; @@ -199,6 +202,8 @@ private: static unordered_map > g_mapGetter; static unordered_map > g_mapPostter; + std::function _delayTask; + uint32_t _iTaskTimeLine = 0; }; } /* namespace mediakit */