初步提交2.0版本,支持虚拟主机

This commit is contained in:
xiongziliang
2018-02-02 18:06:08 +08:00
parent 1262c4c51d
commit bd72a69d33
44 changed files with 354 additions and 730 deletions

View File

@@ -84,10 +84,10 @@ RtpBroadCaster::~RtpBroadCaster() {
m_pReader->setDetachCB(nullptr);
DebugL;
}
RtpBroadCaster::RtpBroadCaster(const string &strLocalIp,const string &strApp,const string &strStream) {
auto src = RtspMediaSource::find(strApp, strStream);
RtpBroadCaster::RtpBroadCaster(const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream) {
auto src = dynamic_pointer_cast<RtspMediaSource>(MediaSource::find(RTSP_SCHEMA,strVhost,strApp, strStream));
if(!src){
auto strErr = StrPrinter << "未找到媒体源:" << strApp << " " << strStream << endl;
auto strErr = StrPrinter << "未找到媒体源:" << strVhost << " " << strApp << " " << strStream << endl;
throw std::runtime_error(strErr);
}
m_multiAddr = MultiCastAddressMaker::Instance().obtain();
@@ -130,6 +130,7 @@ RtpBroadCaster::RtpBroadCaster(const string &strLocalIp,const string &strApp,con
DebugL << MultiCastAddressMaker::toString(*m_multiAddr) << " "
<< m_apUdpSock[0]->get_local_port() << " "
<< m_apUdpSock[1]->get_local_port() << " "
<< strVhost << " "
<< strApp << " " << strStream;
}
uint16_t RtpBroadCaster::getPort(int iTrackId){
@@ -139,11 +140,11 @@ uint16_t RtpBroadCaster::getPort(int iTrackId){
string RtpBroadCaster::getIP(){
return inet_ntoa(m_aPeerUdpAddr[0].sin_addr);
}
RtpBroadCaster::Ptr RtpBroadCaster::make(const string &strLocalIp,const string &strApp,const string &strStream){
RtpBroadCaster::Ptr RtpBroadCaster::make(const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream){
try{
auto ret = Ptr(new RtpBroadCaster(strLocalIp,strApp,strStream));
auto ret = Ptr(new RtpBroadCaster(strLocalIp,strVhost,strApp,strStream));
lock_guard<recursive_mutex> lck(g_mtx);
string strKey = StrPrinter << strLocalIp << " " << strApp << " " << strStream << endl;
string strKey = StrPrinter << strLocalIp << " " << strVhost << " " << strApp << " " << strStream << endl;
weak_ptr<RtpBroadCaster> weakPtr = ret;
g_mapBroadCaster.emplace(strKey,weakPtr);
return ret;
@@ -153,17 +154,17 @@ RtpBroadCaster::Ptr RtpBroadCaster::make(const string &strLocalIp,const string &
}
}
RtpBroadCaster::Ptr RtpBroadCaster::get(const string &strLocalIp,const string& strApp, const string& strStream) {
string strKey = StrPrinter << strLocalIp << " " << strApp << " " << strStream << endl;
RtpBroadCaster::Ptr RtpBroadCaster::get(const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream) {
string strKey = StrPrinter << strLocalIp << " " << strVhost << " " << strApp << " " << strStream << endl;
lock_guard<recursive_mutex> lck(g_mtx);
auto it = g_mapBroadCaster.find(strKey);
if (it == g_mapBroadCaster.end()) {
return make(strLocalIp,strApp, strStream);
return make(strLocalIp,strVhost,strApp, strStream);
}
auto ret = it->second.lock();
if (!ret) {
g_mapBroadCaster.erase(it);
return make(strLocalIp,strApp, strStream);
return make(strLocalIp,strVhost,strApp, strStream);
}
return ret;
}

View File

@@ -74,14 +74,14 @@ public:
typedef std::shared_ptr<RtpBroadCaster> Ptr;
typedef function<void()> onDetach;
virtual ~RtpBroadCaster();
static Ptr get(const string &strLocalIp,const string &strApp,const string &strStream);
static Ptr get(const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream);
void setDetachCB(void *listener,const onDetach &cb);
uint16_t getPort(int iTrackId);
string getIP();
private:
static recursive_mutex g_mtx;
static unordered_map<string , weak_ptr<RtpBroadCaster> > g_mapBroadCaster;
static Ptr make(const string &strLocalIp,const string &strApp,const string &strStream);
static Ptr make(const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream);
std::shared_ptr<uint32_t> m_multiAddr;
recursive_mutex m_mtx;
@@ -90,7 +90,7 @@ private:
Socket::Ptr m_apUdpSock[2];
struct sockaddr_in m_aPeerUdpAddr[2];
RtpBroadCaster(const string &strLocalIp,const string &strApp,const string &strStream);
RtpBroadCaster(const string &strLocalIp,const string &strVhost,const string &strApp,const string &strStream);
};

View File

@@ -163,36 +163,18 @@ public:
this->m_strContent = content;
}
const StrCaseMap& getValues() const {
StrCaseMap& getValues() const {
return m_mapValues;
}
const StrCaseMap& getUrlArgs() const {
StrCaseMap& getUrlArgs() const {
return m_mapUrlArgs;
}
//注意:当字符串为空时,也会返回一个空字符串
static vector<string> split(const string& s, const char *delim) {
size_t last = 0;
size_t index = s.find_first_of(delim, last);
vector<string> ret;
while (index != string::npos) {
ret.push_back(s.substr(last, index - last));
last = index + 1;
index = s.find_first_of(delim, last);
}
if (index - last > 0) {
ret.push_back(s.substr(last, index - last));
}
return ret;
}
static StrCaseMap parseArgs(const string &str,const char *pair_delim = "&", const char *key_delim = "="){
StrCaseMap ret;
auto arg_vec = split(str, pair_delim);
for (string &key_val : arg_vec) {
if (!key_val.size()) {
continue;
}
auto key_val_vec = split(key_val, key_delim);
if (key_val_vec.size() >= 2) {
ret[key_val_vec[0]] = key_val_vec[1];
@@ -207,8 +189,8 @@ private:
string m_strTail;
string m_strContent;
string m_strNull;
StrCaseMap m_mapValues;
StrCaseMap m_mapUrlArgs;
mutable StrCaseMap m_mapValues;
mutable StrCaseMap m_mapUrlArgs;
};
typedef struct {

View File

@@ -32,30 +32,5 @@ using namespace ZL::MediaFile;
namespace ZL {
namespace Rtsp {
recursive_mutex RtspMediaSource::g_mtxMediaSrc;
unordered_map<string, unordered_map<string, weak_ptr<RtspMediaSource> > > RtspMediaSource::g_mapMediaSrc;
RtspMediaSource::Ptr RtspMediaSource::find(const string &strApp, const string &strId,bool bMake) {
//查找某一媒体源,找到后返回
lock_guard<recursive_mutex> lock(g_mtxMediaSrc);
auto itApp = g_mapMediaSrc.find(strApp);
if (itApp == g_mapMediaSrc.end()) {
return bMake ? MediaReader::onMakeRtsp(strApp, strId) : nullptr;
}
auto itId = itApp->second.find(strId);
if (itId == itApp->second.end()) {
return bMake ? MediaReader::onMakeRtsp(strApp, strId) : nullptr;
}
auto ret = itId->second.lock();
if(ret){
return ret;
}
itApp->second.erase(itId);
if (itApp->second.size() == 0) {
g_mapMediaSrc.erase(itApp);
}
return bMake ? MediaReader::onMakeRtsp(strApp, strId) : nullptr;
}
} /* namespace Rtsp */
} /* namespace ZL */

View File

@@ -35,6 +35,8 @@
#include "Rtsp.h"
#include "Common/config.h"
#include "Common/MediaSender.h"
#include "Common/MediaSource.h"
#include "Util/logger.h"
#include "Util/RingBuffer.h"
#include "Util/TimeTicker.h"
@@ -45,80 +47,33 @@
using namespace std;
using namespace ZL::Util;
using namespace ZL::Thread;
using namespace ZL::Media;
namespace ZL {
namespace Rtsp {
class RtspMediaSource: public enable_shared_from_this<RtspMediaSource> {
class RtspMediaSource: public MediaSource {
public:
typedef ResourcePool<RtpPacket, 64> PoolType;
typedef std::shared_ptr<RtspMediaSource> Ptr;
typedef RingBuffer<RtpPacket::Ptr> RingType;
RtspMediaSource(const string &strApp, const string &strId) :
m_strApp(strApp),
m_strId(strId),
RtspMediaSource(const string &strVhost,const string &strApp, const string &strId) :
MediaSource(RTSP_SCHEMA,strVhost,strApp,strId),
m_pRing(new RingBuffer<RtpPacket::Ptr>()),
m_thPool(MediaSender::sendThread()) {
}
virtual ~RtspMediaSource() {
unregist();
}
virtual ~RtspMediaSource() {}
const RingType::Ptr &getRing() const {
//获取媒体源的rtp环形缓冲
return m_pRing;
}
const string& getSdp() const {
//获取该源的媒体描述信息
return m_strSdp;
}
virtual void regist() {
//注册该源注册后rtsp服务器才能找到该源
lock_guard<recursive_mutex> lock(g_mtxMediaSrc);
if (!g_mapMediaSrc[m_strApp].erase(m_strId)) {
InfoL << "Rtsp src:" << m_strApp << " " << m_strId;
}
g_mapMediaSrc[m_strApp].emplace(m_strId, shared_from_this());
NoticeCenter::Instance().emitEvent(Config::Broadcast::kBroadcastRtspSrcRegisted,m_strApp.data(),m_strId.data());
}
virtual void unregist() {
//反注册该源
lock_guard<recursive_mutex> lock(g_mtxMediaSrc);
auto it = g_mapMediaSrc.find(m_strApp);
if (it == g_mapMediaSrc.end()) {
return;
}
if (it->second.erase(m_strId)) {
if(it->second.size() == 0){
g_mapMediaSrc.erase(it);
}
InfoL << "Rtsp src:" << m_strApp << " " << m_strId;
}
}
static set<string> getMediaSet() {
set<string> ret;
lock_guard<recursive_mutex> lock(g_mtxMediaSrc);
for (auto &pr0 : g_mapMediaSrc) {
for (auto &pr1 : pr0.second) {
if(pr1.second.lock()){
ret.emplace(pr0.first + "/" + pr1.first);
}
}
}
return ret;
}
static Ptr find(const string &_app, const string &_id,bool bMake = true) ;
const string& getApp() const {
//获取该源的id
return m_strApp;
}
const string& getId() const {
return m_strId;
}
virtual uint32_t getSsrc(int trackId) {
return m_mapTracks[trackId].ssrc;
}
@@ -131,7 +86,7 @@ public:
virtual void onGetSDP(const string& sdp) {
//派生类设置该媒体源媒体描述信息
this->m_strSdp = sdp;
m_strSdp = sdp;
}
virtual void onGetRTP(const RtpPacket::Ptr &rtppt, bool keyPos) {
auto &trackRef = m_mapTracks[rtppt->interleaved / 2];
@@ -144,36 +99,11 @@ public:
_outRing->write(rtppt,keyPos);
});
}
bool seekTo(uint32_t ui32Stamp) {
if (!m_onSeek) {
return false;
}
return m_onSeek(ui32Stamp);
}
virtual void setOnSeek(const function<bool(uint32_t)> &cb){
m_onSeek = cb;
}
uint32_t getStamp() {
if (!m_onStamp) {
return 0;
}
return m_onStamp();
}
virtual void setOnStamp(const function<uint32_t()> &cb) {
m_onStamp = cb;
}
protected:
function<bool(uint32_t)> m_onSeek;
function<uint32_t()> m_onStamp;
unordered_map<int, RtspTrack> m_mapTracks;
private:
string m_strSdp; //媒体描述信息
string m_strApp; //媒体app
string m_strId; //媒体id
RingType::Ptr m_pRing; //rtp环形缓冲
string m_strSdp; //媒体描述信息
RingType::Ptr m_pRing; //rtp环形缓冲
ThreadPool &m_thPool;
static unordered_map<string, unordered_map<string, weak_ptr<RtspMediaSource> > > g_mapMediaSrc; //静态的媒体源表
static recursive_mutex g_mtxMediaSrc; ///访问静态的媒体源表的互斥锁
};
} /* namespace Rtsp */

View File

@@ -427,19 +427,6 @@ void RtspPlayer::pause(bool bPause) {
sendPause(bPause,getProgressTime());
}
//注意:当字符串为空时,也会返回一个空字符串
static void split(const string& s, const char *delim, vector<string> &ret) {
size_t last = 0;
size_t index = s.find_first_of(delim, last);
while (index != string::npos) {
ret.push_back(s.substr(last, index - last));
last = index + 1;
index = s.find_first_of(delim, last);
}
if (index - last > 0) {
ret.push_back(s.substr(last, index - last));
}
}
void RtspPlayer::HandleResPAUSE(const Parser& parser, bool bPause) {
if (parser.Url() != "200") {
WarnL <<(bPause ? "Pause" : "Play") << " failed:" << parser.Url() << " " << parser.Tail() << endl;
@@ -461,18 +448,15 @@ void RtspPlayer::HandleResPAUSE(const Parser& parser, bool bPause) {
auto strRtpInfo = parser["RTP-Info"];
if (strRtpInfo.size()) {
strRtpInfo.append(",");
vector<string> vec;
split(strRtpInfo, ",", vec);
vector<string> vec = split(strRtpInfo, ",");
for(auto &strTrack : vec){
if (strTrack.size()) {
strTrack.append(";");
auto strTrackId = FindField(strTrack.data(), m_aTrackInfo[0].trackStyle.data(), ";");
auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";");
auto iIdx = getTrackIndex(atoi(strTrackId.data()));
m_adFistStamp[iIdx] = atoll(strRtpTime.data());
m_adNowStamp[iIdx] = m_adFistStamp[iIdx];
DebugL << "rtptime:" << strTrackId <<" " << strRtpTime;
}
strTrack.append(";");
auto strTrackId = FindField(strTrack.data(), m_aTrackInfo[0].trackStyle.data(), ";");
auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";");
auto iIdx = getTrackIndex(atoi(strTrackId.data()));
m_adFistStamp[iIdx] = atoll(strRtpTime.data());
m_adNowStamp[iIdx] = m_adFistStamp[iIdx];
DebugL << "rtptime:" << strTrackId <<" " << strRtpTime;
}
}
_onPlayResult(SockException(Err_success, "rtsp play success"));

View File

@@ -55,7 +55,6 @@ unordered_map<void *, std::shared_ptr<RtspSession> > RtspSession::g_mapPostter;
recursive_mutex RtspSession::g_mtxGetter; //对quicktime上锁保护
recursive_mutex RtspSession::g_mtxPostter; //对quicktime上锁保护
unordered_map<string, RtspSession::rtspCMDHandle> RtspSession::g_mapCmd;
string RtspSession::g_serverName;
RtspSession::RtspSession(const std::shared_ptr<ThreadPool> &pTh, const Socket::Ptr &pSock) :
TcpLimitedSession(pTh, pSock), m_pSender(pSock) {
static onceToken token( []() {
@@ -69,7 +68,6 @@ RtspSession::RtspSession(const std::shared_ptr<ThreadPool> &pTh, const Socket::P
g_mapCmd.emplace("POST",&RtspSession::handleReq_Post);
g_mapCmd.emplace("SET_PARAMETER",&RtspSession::handleReq_SET_PARAMETER);
g_mapCmd.emplace("GET_PARAMETER",&RtspSession::handleReq_SET_PARAMETER);
g_serverName = mINI::Instance()[Config::Rtsp::kServerName];
}, []() {});
#ifndef __x86_64__
@@ -184,7 +182,7 @@ bool RtspSession::handleReq_Options() {
"%s"
"Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY,"
" PAUSE, SET_PARAMETER, GET_PARAMETER\r\n\r\n",
m_iCseq, g_serverName.data(),
m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data());
send(m_pcBuf, n);
@@ -192,7 +190,15 @@ bool RtspSession::handleReq_Options() {
}
bool RtspSession::handleReq_Describe() {
m_strUrl = m_parser.Url();
{
//解析url获取媒体名称
m_strUrl = m_parser.Url();
m_mediaInfo.parse(m_strUrl);
if(!m_parser.getUrlArgs()[VHOST_KEY].empty()){
m_mediaInfo.m_vhost = m_parser.getUrlArgs()[VHOST_KEY];
}
}
if (!findStream()) {
//未找到相应的MediaSource
send_StreamNotFound();
@@ -213,7 +219,10 @@ bool RtspSession::handleReq_Describe() {
};
//广播是否需要认证事件
if(!NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastOnGetRtspRealm,m_strApp.data(),m_strStream.data(),invoker)){
if(!NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastOnGetRtspRealm,
m_mediaInfo.m_app.data(),
m_mediaInfo.m_streamid.data(),
invoker)){
//无人监听此事件,说明无需认证
invoker("");
}
@@ -242,7 +251,7 @@ void RtspSession::onAuthSuccess(const weak_ptr<RtspSession> &weakSelf) {
"Content-Base: %s/\r\n"
"Content-Type: application/sdp\r\n"
"Content-Length: %d\r\n\r\n%s",
strongSelf->m_iCseq, strongSelf->g_serverName.data(),
strongSelf->m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), strongSelf->m_strUrl.data(),
(int) strongSelf->m_strSdp.length(), strongSelf->m_strSdp.data());
@@ -274,7 +283,7 @@ void RtspSession::onAuthFailed(const weak_ptr<RtspSession> &weakSelf,const strin
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"WWW-Authenticate:Digest realm=\"%s\",nonce=\"%s\"\r\n\r\n",
strongSelf->m_iCseq, strongSelf->g_serverName.data(),
strongSelf->m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), realm.data(), strongSelf->m_strNonce.data());
}else {
@@ -285,7 +294,7 @@ void RtspSession::onAuthFailed(const weak_ptr<RtspSession> &weakSelf,const strin
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"WWW-Authenticate:Basic realm=\"%s\"\r\n\r\n",
strongSelf->m_iCseq, strongSelf->g_serverName.data(),
strongSelf->m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), realm.data());
}
@@ -297,7 +306,7 @@ void RtspSession::onAuthBasic(const weak_ptr<RtspSession> &weakSelf,const string
//base64认证
char user_pwd_buf[512];
av_base64_decode((uint8_t *)user_pwd_buf,strBase64.data(),strBase64.size());
auto user_pwd_vec = Parser::split(user_pwd_buf,":");
auto user_pwd_vec = split(user_pwd_buf,":");
if(user_pwd_vec.size() < 2){
//认证信息格式不合法回复401 Unauthorized
onAuthFailed(weakSelf,realm);
@@ -324,23 +333,7 @@ void RtspSession::onAuthBasic(const weak_ptr<RtspSession> &weakSelf,const string
invoker(false,pwd);
}
}
static string trim(string str){
while(!str.empty()){
if(str.front()==' ' || str.front()=='"'){
str.erase(0,1);
continue;
}
break;
}
while(!str.empty()){
if(str.back()==' ' || str.back()=='"'){
str.pop_back();
continue;
}
break;
}
return str;
}
void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const string &realm,const string &strMd5){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
@@ -351,7 +344,7 @@ void RtspSession::onAuthDigest(const weak_ptr<RtspSession> &weakSelf,const strin
auto mapTmp = Parser::parseArgs(strMd5,",","=");
decltype(mapTmp) map;
for(auto &pr : mapTmp){
map[trim(pr.first)] = trim(pr.second);
map[trim(string(pr.first)," \"")] = trim(pr.second," \"");
}
//check realm
if(realm != map["realm"]){
@@ -448,7 +441,7 @@ inline void RtspSession::send_StreamNotFound() {
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"Connection: Close\r\n\r\n",
m_iCseq, g_serverName.data(),
m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data());
send(m_pcBuf, n);
@@ -459,7 +452,7 @@ inline void RtspSession::send_UnsupportedTransport() {
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"Connection: Close\r\n\r\n",
m_iCseq, g_serverName.data(),
m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data());
send(m_pcBuf, n);
@@ -471,7 +464,7 @@ inline void RtspSession::send_SessionNotFound() {
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"Connection: Close\r\n\r\n",
m_iCseq, g_serverName.data(),
m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data());
send(m_pcBuf, n);
@@ -539,7 +532,7 @@ bool RtspSession::handleReq_Setup() {
"Session: %s\r\n"
"x-Transport-Options: late-tolerance=1.400000\r\n"
"x-Dynamic-Rate: 1\r\n\r\n",
m_iCseq, g_serverName.data(),
m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), trackid * 2,
trackid * 2 + 1,
@@ -584,7 +577,7 @@ bool RtspSession::handleReq_Setup() {
"Transport: RTP/AVP/UDP;unicast;"
"client_port=%s;server_port=%d-%d;ssrc=%s;mode=play\r\n"
"Session: %s\r\n\r\n",
m_iCseq, g_serverName.data(),
m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), strClientPort.data(),
pSockRtp->get_local_port(), pSockRtcp->get_local_port(),
@@ -595,7 +588,7 @@ bool RtspSession::handleReq_Setup() {
break;
case PlayerBase::RTP_MULTICAST: {
if(!m_pBrdcaster){
m_pBrdcaster = RtpBroadCaster::get(getLocalIp(), m_strApp, m_strStream);
m_pBrdcaster = RtpBroadCaster::get(getLocalIp(),m_mediaInfo.m_vhost, m_mediaInfo.m_app, m_mediaInfo.m_streamid);
if (!m_pBrdcaster) {
send_NotAcceptable();
return false;
@@ -627,7 +620,7 @@ bool RtspSession::handleReq_Setup() {
"Transport: RTP/AVP;multicast;destination=%s;"
"source=%s;port=%d-%d;ttl=%d;ssrc=%s\r\n"
"Session: %s\r\n\r\n",
m_iCseq, g_serverName.data(),
m_iCseq, SERVER_NAME,
RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), m_pBrdcaster->getIP().data(),
getLocalIp().data(), iSrvPort, pSockRtcp->get_local_port(),
@@ -705,7 +698,7 @@ bool RtspSession::handleReq_Play() {
"%s"
"Session: %s\r\n"
"Range: npt=%.2f-\r\n"
"RTP-Info: ", m_iCseq, g_serverName.data(), RTSP_VERSION, RTSP_BUILDTIME,
"RTP-Info: ", m_iCseq, SERVER_NAME, RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), m_strSession.data(),iStamp/1000.0);
for (unsigned int i = 0; i < m_uiTrackCnt; i++) {
@@ -722,7 +715,11 @@ bool RtspSession::handleReq_Play() {
(m_pcBuf)[iLen] = '\0';
iLen += sprintf(m_pcBuf + iLen, "\r\n\r\n");
send(m_pcBuf, iLen);
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastRtspSessionPlay, m_strApp.data(),m_strStream.data());
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed,
RTSP_SCHEMA,
m_mediaInfo.m_vhost.data(),
m_mediaInfo.m_app.data(),
m_mediaInfo.m_streamid.data());
return true;
}
@@ -735,7 +732,7 @@ bool RtspSession::handleReq_Pause() {
"CSeq: %d\r\n"
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"Session: %s\r\n\r\n", m_iCseq, g_serverName.data(), RTSP_VERSION, RTSP_BUILDTIME,
"Session: %s\r\n\r\n", m_iCseq, SERVER_NAME, RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), m_strSession.data());
send(m_pcBuf, n);
if(m_pRtpReader){
@@ -750,7 +747,7 @@ bool RtspSession::handleReq_Teardown() {
"CSeq: %d\r\n"
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"Session: %s\r\n\r\n", m_iCseq, g_serverName.data(), RTSP_VERSION, RTSP_BUILDTIME,
"Session: %s\r\n\r\n", m_iCseq, SERVER_NAME, RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), m_strSession.data());
send(m_pcBuf, n);
@@ -801,7 +798,7 @@ bool RtspSession::handleReq_SET_PARAMETER() {
"CSeq: %d\r\n"
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"Session: %s\r\n\r\n", m_iCseq, g_serverName.data(), RTSP_VERSION, RTSP_BUILDTIME,
"Session: %s\r\n\r\n", m_iCseq, SERVER_NAME, RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data(), m_strSession.data());
send(m_pcBuf, n);
return true;
@@ -812,21 +809,17 @@ inline void RtspSession::send_NotAcceptable() {
"CSeq: %d\r\n"
"Server: %s-%0.2f(build in %s)\r\n"
"%s"
"Connection: Close\r\n\r\n", m_iCseq, g_serverName.data(), RTSP_VERSION, RTSP_BUILDTIME,
"Connection: Close\r\n\r\n", m_iCseq, SERVER_NAME, RTSP_VERSION, RTSP_BUILDTIME,
dateHeader().data());
send(m_pcBuf, n);
}
void RtspSession::splitRtspUrl(const string &url,string &app,string &stream){
string strHost = FindField(url.data(), "://", "/");
app = FindField(url.data(), (strHost + "/").data(), "/");
stream = FindField(url.data(), (strHost + "/" + app + "/").data(), NULL);
}
inline bool RtspSession::findStream() {
splitRtspUrl(m_strUrl,m_strApp,m_strStream);
RtspMediaSource::Ptr pMediaSrc = RtspMediaSource::find(m_strApp,m_strStream);
RtspMediaSource::Ptr pMediaSrc =
dynamic_pointer_cast<RtspMediaSource>( MediaSource::find(RTSP_SCHEMA,m_mediaInfo.m_vhost, m_mediaInfo.m_app,m_mediaInfo.m_streamid) );
if (!pMediaSrc) {
WarnL << "No such stream:" << m_strApp << " " << m_strStream;
WarnL << "No such stream:" << m_mediaInfo.m_vhost << " " << m_mediaInfo.m_app << " " << m_mediaInfo.m_streamid;
return false;
}
m_strSdp = pMediaSrc->getSdp();

View File

@@ -109,7 +109,6 @@ private:
void inline send_UnsupportedTransport(); //不支持的传输模式
void inline send_SessionNotFound(); //会话id错误
void inline send_NotAcceptable(); //rtsp同时播放数限制
void splitRtspUrl(const string &url,string &app,string &stream);
inline bool findStream(); //根据rtsp url查找 MediaSource实例
inline void initSender(const std::shared_ptr<RtspSession> &pSession); //处理rtsp over httpquicktime使用的
@@ -148,8 +147,7 @@ private:
string m_strSdp;
string m_strSession;
bool m_bFirstPlay = true;
string m_strApp;
string m_strStream;
MediaInfo m_mediaInfo;
std::weak_ptr<RtspMediaSource> m_pMediaSrc;
static unordered_map<string, rtspCMDHandle> g_mapCmd;
@@ -191,7 +189,6 @@ private:
static recursive_mutex g_mtxPostter; //对quicktime上锁保护
static unordered_map<string, weak_ptr<RtspSession> > g_mapGetter;
static unordered_map<void *, std::shared_ptr<RtspSession> > g_mapPostter;
static string g_serverName;
};

View File

@@ -37,28 +37,27 @@ using namespace ZL::Network;
namespace ZL {
namespace Rtsp {
#ifdef ENABLE_RTSP2RTMP
RtspToRtmpMediaSource::RtspToRtmpMediaSource(const string &_app,const string &_id,bool bEnableFile) :
RtspMediaSource(_app,_id),m_bEnableFile(bEnableFile) {
RtspToRtmpMediaSource::RtspToRtmpMediaSource(const string &vhost,const string &app,const string &id,bool bEnableFile) :
RtspMediaSource(vhost,app,id),m_bEnableFile(bEnableFile) {
}
RtspToRtmpMediaSource::~RtspToRtmpMediaSource() {
}
void RtspToRtmpMediaSource::regist() {
RtspMediaSource::regist();
bool RtspToRtmpMediaSource::regist() {
if (m_pRtmpSrc) {
m_pRtmpSrc->regist();
}
return MediaSource::regist();
}
void RtspToRtmpMediaSource::unregist() {
RtspMediaSource::unregist();
bool RtspToRtmpMediaSource::unregist() {
if (m_pRtmpSrc) {
m_pRtmpSrc->unregist();
}
return MediaSource::unregist();
}
void RtspToRtmpMediaSource::makeVideoConfigPkt() {
@@ -196,9 +195,8 @@ void RtspToRtmpMediaSource::makeAudioConfigPkt() {
}
void RtspToRtmpMediaSource::makeMetaData() {
m_pRtmpSrc.reset(new RtmpMediaSource(getApp(),getId()));
m_pRtmpSrc->setOnSeek(m_onSeek);
m_pRtmpSrc->setOnStamp(m_onStamp);
m_pRtmpSrc.reset(new RtmpMediaSource(getVhost(),getApp(),getId()));
m_pRtmpSrc->setListener(m_listener);
AMFValue metaData(AMF_OBJECT);
metaData.set("duration", m_pParser->getDuration());
metaData.set("fileSize", 0);
@@ -222,6 +220,5 @@ void RtspToRtmpMediaSource::makeMetaData() {
m_pRtmpSrc->onGetMetaData(metaData);
}
#endif //ENABLE_RTSP2RTMP
} /* namespace Rtsp */
} /* namespace ZL */

View File

@@ -38,18 +38,17 @@ using namespace ZL::MediaFile;
namespace ZL {
namespace Rtsp {
#ifdef ENABLE_RTSP2RTMP
class RtspToRtmpMediaSource: public RtspMediaSource {
public:
typedef std::shared_ptr<RtspToRtmpMediaSource> Ptr;
RtspToRtmpMediaSource(const string &_app,const string &_id,bool bEnableFile = true);
RtspToRtmpMediaSource(const string &vhost,const string &app,const string &id,bool bEnableFile = true);
virtual ~RtspToRtmpMediaSource();
virtual void onGetSDP(const string& strSdp) override{
try {
m_pParser.reset(new RtpParser(strSdp));
if(m_bEnableFile){
m_pRecorder.reset(new MediaRecorder(getApp(),getId(),m_pParser));
m_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),m_pParser));
}
m_pParser->setOnAudioCB( std::bind(&RtspToRtmpMediaSource::onGetAdts, this, placeholders::_1));
m_pParser->setOnVideoCB( std::bind(&RtspToRtmpMediaSource::onGetH264, this, placeholders::_1));
@@ -65,23 +64,13 @@ public:
}
RtspMediaSource::onGetRTP(pRtppkt, bKeyPos);
}
virtual void regist() override ;
virtual void unregist() override;
virtual bool regist() override ;
virtual bool unregist() override;
int readerCount(){
return getRing()->readerCount() + (m_pRtmpSrc ? m_pRtmpSrc->getRing()->readerCount() : 0);
}
void setOnSeek(const function<bool(uint32_t)> &cb) override{
RtspMediaSource::setOnSeek(cb);
if(m_pRtmpSrc){
m_pRtmpSrc->setOnSeek(cb);
}
}
void setOnStamp(const function<uint32_t()> &cb) override{
RtspMediaSource::setOnStamp(cb);
if (m_pRtmpSrc) {
m_pRtmpSrc->setOnStamp(cb);
}
}
void updateTimeStamp(uint32_t uiStamp) {
for (auto &pr : m_mapTracks) {
switch (pr.second.type) {
@@ -111,9 +100,6 @@ private:
void makeMetaData();
};
#else
typedef RtspMediaSource RtspToRtmpMediaSource;
#endif //ENABLE_RTSP2RTMP
} /* namespace Rtsp */
} /* namespace ZL */