Commit 67d5ca02 by xiongguangjie

rtsp push replace pre pusher

parent ca7efd59
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "Util/base64.h" #include "Util/base64.h"
#include "RtpMultiCaster.h" #include "RtpMultiCaster.h"
#include "Rtcp/RtcpContext.h" #include "Rtcp/RtcpContext.h"
#include "Network/Server.h"
using namespace std; using namespace std;
using namespace toolkit; using namespace toolkit;
...@@ -218,7 +219,36 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { ...@@ -218,7 +219,36 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
throw SockException(Err_shutdown, StrPrinter << err << ":" << full_url); throw SockException(Err_shutdown, StrPrinter << err << ":" << full_url);
} }
auto onRes = [this, parser, full_url](const string &err, const ProtocolOption &option) { auto onResPushSrc = [this, parser, full_url](ProtocolOption option) {
SdpParser sdpParser(parser.Content());
_sessionid = makeRandStr(12);
_sdp_track = sdpParser.getAvailableTrack();
if (_sdp_track.empty()) {
// sdp无效
static constexpr auto err = "sdp中无有效track";
sendRtspResponse("403 Forbidden", { "Content-Type", "text/plain" }, err);
shutdown(SockException(Err_shutdown, StrPrinter << err << ":" << full_url));
return;
}
_rtcp_context.clear();
for (auto &track : _sdp_track) {
_rtcp_context.emplace_back(std::make_shared<RtcpContextForRecv>());
}
if (!_push_src) {
_push_src = std::make_shared<RtspMediaSourceImp>(_media_info._vhost, _media_info._app, _media_info._streamid);
// 获取所有权
_push_src_ownership = _push_src->getOwnership();
_push_src->setProtocolOption(option);
_push_src->setSdp(parser.Content());
}
_push_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
_continue_push_ms = option.continue_push_ms;
sendRtspResponse("200 OK");
};
auto onRes = [this, parser, full_url,onResPushSrc](const string &err, const ProtocolOption &option) {
if (!err.empty()) { if (!err.empty()) {
sendRtspResponse("401 Unauthorized", { "Content-Type", "text/plain" }, err); sendRtspResponse("401 Unauthorized", { "Content-Type", "text/plain" }, err);
shutdown(SockException(Err_shutdown, StrPrinter << "401 Unauthorized:" << err)); shutdown(SockException(Err_shutdown, StrPrinter << "401 Unauthorized:" << err));
...@@ -228,57 +258,54 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { ...@@ -228,57 +258,54 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
assert(!_push_src); assert(!_push_src);
auto src = MediaSource::find(RTSP_SCHEMA, _media_info._vhost, _media_info._app, _media_info._streamid); auto src = MediaSource::find(RTSP_SCHEMA, _media_info._vhost, _media_info._app, _media_info._streamid);
auto push_failed = (bool)src; auto push_failed = (bool)src;
RtspMediaSource::Ptr rtsp_src;
RtspMediaSourceImp::Ptr rtsp_src_imp;
while (src) { while (src) {
//尝试断连后继续推流 //尝试断连后继续推流
auto rtsp_src = dynamic_pointer_cast<RtspMediaSourceImp>(src); rtsp_src_imp = dynamic_pointer_cast<RtspMediaSourceImp>(src);
if (!rtsp_src) { rtsp_src = dynamic_pointer_cast<RtspMediaSource>(src);
if (!rtsp_src_imp) {
//源不是rtsp推流产生的 //源不是rtsp推流产生的
break; break;
} }
auto ownership = rtsp_src->getOwnership(); auto ownership = rtsp_src_imp->getOwnership();
if (!ownership) { if (!ownership) {
//获取推流源所有权失败 //获取推流源所有权失败
break; break;
} }
_push_src = std::move(rtsp_src); _push_src = std::move(rtsp_src_imp);
_push_src_ownership = std::move(ownership); _push_src_ownership = std::move(ownership);
push_failed = false; push_failed = false;
break; break;
} }
if (push_failed) { if (push_failed && rtsp_src) {
sendRtspResponse("406 Not Acceptable", { "Content-Type", "text/plain" }, "Already publishing."); auto sock = rtsp_src->getOriginSock();
string err = StrPrinter << "ANNOUNCE: Already publishing:" << _media_info.shortUrl() << endl; if(sock){
throw SockException(Err_shutdown, err); auto session = SessionMap::Instance().get(sock->getIdentifier());
} auto rtsp_session = dynamic_pointer_cast<RtspSession>(session);
if(session && rtsp_session){
SdpParser sdpParser(parser.Content()); rtsp_src_imp = rtsp_session->getPushSrc();
_sessionid = makeRandStr(12); session->getPoller()->async_first([this,rtsp_src,option,rtsp_src_imp,onResPushSrc,session](){
_sdp_track = sdpParser.getAvailableTrack(); session->shutdown(SockException(Err_shutdown, "other pusher kick session"));
if (_sdp_track.empty()) { _push_src_ownership = rtsp_src_imp->getOwnership();
// sdp无效 _push_src = std::move(rtsp_src_imp);
static constexpr auto err = "sdp中无有效track";
sendRtspResponse("403 Forbidden", { "Content-Type", "text/plain" }, err); this->getPoller()->async_first([option,onResPushSrc](){
shutdown(SockException(Err_shutdown, StrPrinter << err << ":" << full_url)); onResPushSrc(option);
});
});
return; return;
} }
_rtcp_context.clear();
for (auto &track : _sdp_track) {
_rtcp_context.emplace_back(std::make_shared<RtcpContextForRecv>());
} }
if (!_push_src) { sendRtspResponse("406 Not Acceptable", { "Content-Type", "text/plain" }, "not reach this");
_push_src = std::make_shared<RtspMediaSourceImp>(_media_info._vhost, _media_info._app, _media_info._streamid); string err = StrPrinter << "ANNOUNCE: not reach this:" << _media_info.shortUrl() << endl;
//获取所有权 throw SockException(Err_shutdown, err);
_push_src_ownership = _push_src->getOwnership();
_push_src->setProtocolOption(option);
_push_src->setSdp(parser.Content());
} }
_push_src->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this())); onResPushSrc(option);
_continue_push_ms = option.continue_push_ms;
sendRtspResponse("200 OK");
}; };
weak_ptr<RtspSession> weak_self = dynamic_pointer_cast<RtspSession>(shared_from_this()); weak_ptr<RtspSession> weak_self = dynamic_pointer_cast<RtspSession>(shared_from_this());
...@@ -1249,5 +1276,9 @@ void RtspSession::setSocketFlags(){ ...@@ -1249,5 +1276,9 @@ void RtspSession::setSocketFlags(){
} }
} }
RtspMediaSourceImp::Ptr RtspSession::getPushSrc(){
return _push_src;
}
} }
/* namespace mediakit */ /* namespace mediakit */
...@@ -40,6 +40,8 @@ public: ...@@ -40,6 +40,8 @@ public:
void onError(const toolkit::SockException &err) override; void onError(const toolkit::SockException &err) override;
void onManager() override; void onManager() override;
RtspMediaSourceImp::Ptr getPushSrc();
protected: protected:
/////RtspSplitter override///// /////RtspSplitter override/////
//收到完整的rtsp包回调,包括sdp等content数据 //收到完整的rtsp包回调,包括sdp等content数据
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论