mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 14:45:55 +08:00
解决sdp解析失败的问题
This commit is contained in:
parent
770651467e
commit
03507e5bfc
@ -50,65 +50,57 @@ string FindField(const char* buf, const char* start, const char *end ,int bufSiz
|
|||||||
return string(msg_start, msg_end);
|
return string(msg_start, msg_end);
|
||||||
}
|
}
|
||||||
int parserSDP(const string& sdp, RtspTrack Track[2]) {
|
int parserSDP(const string& sdp, RtspTrack Track[2]) {
|
||||||
string track_str;
|
|
||||||
if (sdp.find("trackID=") != string::npos) {
|
|
||||||
track_str = "trackID=";
|
|
||||||
}else if (sdp.find("track") != string::npos) {
|
|
||||||
track_str = "track";
|
|
||||||
}else if (sdp.find("streamid=") != string::npos) {
|
|
||||||
track_str = "streamid=";
|
|
||||||
}else if (sdp.find("stream") != string::npos) {
|
|
||||||
track_str = "stream";
|
|
||||||
}
|
|
||||||
int track_cnt = 0;
|
int track_cnt = 0;
|
||||||
string::size_type pos_head = sdp.find("m=");
|
string::size_type pos_head = 0;
|
||||||
string::size_type pos_end = 0;
|
while ((pos_head = sdp.find("m=",pos_head)) != string::npos ) {
|
||||||
string IDStr;
|
auto pos_end = sdp.find("m=", pos_head + 2);
|
||||||
int TrackID;
|
|
||||||
string mid;
|
|
||||||
while (true) {
|
|
||||||
IDStr = FindField(sdp.c_str() + pos_head, track_str.c_str(), "\r\n");
|
|
||||||
if (IDStr == "") {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(strcasecmp(IDStr.data(),"video") == 0){
|
|
||||||
TrackID = 0;
|
|
||||||
}else if(strcasecmp(IDStr.data(),"audio") == 0){
|
|
||||||
TrackID = 1;
|
|
||||||
}else{
|
|
||||||
TrackID = atoi(IDStr.c_str());
|
|
||||||
}
|
|
||||||
pos_end = sdp.find("m=", pos_head + 2);
|
|
||||||
if (pos_end == string::npos) {
|
if (pos_end == string::npos) {
|
||||||
pos_end = sdp.size();
|
pos_end = sdp.size();
|
||||||
}
|
}
|
||||||
mid = sdp.substr(pos_head, pos_end - pos_head);
|
auto sdp_mid = sdp.substr(pos_head, pos_end - pos_head);
|
||||||
Track[track_cnt].trackSdp = mid;
|
Track[track_cnt].trackSdp = sdp_mid;
|
||||||
Track[track_cnt].trackStyle = track_str;
|
|
||||||
Track[track_cnt].inited = false;
|
Track[track_cnt].inited = false;
|
||||||
Track[track_cnt].trackId = TrackID;
|
Track[track_cnt].PT = atoi(FindField(sdp_mid.c_str(), "a=rtpmap:", " ").c_str());
|
||||||
Track[track_cnt].trackIdStr = IDStr;
|
auto control = string("/") + trim(FindField(sdp_mid.c_str(), "a=control:", "\n"));
|
||||||
Track[track_cnt].PT = atoi(FindField(mid.c_str(), "rtpmap:", " ").c_str());
|
Track[track_cnt].controlSuffix = control.substr(1 + control.find_last_of('/'));
|
||||||
if (mid.find("m=video") != string::npos) {
|
|
||||||
|
if (sdp_mid.find("m=video") != string::npos) {
|
||||||
//视频通道
|
//视频通道
|
||||||
Track[track_cnt].type = TrackVideo;
|
Track[track_cnt].type = TrackVideo;
|
||||||
} else if (mid.find("m=audio") != string::npos) {
|
Track[track_cnt].trackId = 0;
|
||||||
|
} else if (sdp_mid.find("m=audio") != string::npos) {
|
||||||
//音频通道
|
//音频通道
|
||||||
Track[track_cnt].type = TrackAudio;
|
Track[track_cnt].type = TrackAudio;
|
||||||
} else {
|
Track[track_cnt].trackId = 1;
|
||||||
|
} else {
|
||||||
//不识别的track
|
//不识别的track
|
||||||
return 0;
|
return track_cnt;
|
||||||
}
|
}
|
||||||
pos_head = pos_end;
|
pos_head = pos_end;
|
||||||
if (track_cnt++ > 2) {
|
track_cnt++;
|
||||||
//最大支持2个通道
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return track_cnt;
|
return track_cnt;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//static onceToken s_token([](){
|
||||||
|
// string str = "v=0\n"
|
||||||
|
// "o=- 1001 1 IN IP4 192.168.0.22\n"
|
||||||
|
// "s=VCP IPC Realtime stream\n"
|
||||||
|
// "m=video 0 RTP/AVP 105\n"
|
||||||
|
// "c=IN IP4 192.168.0.22\n"
|
||||||
|
// "a=control:rtsp://192.168.0.22/media/video1/video\n"
|
||||||
|
// "a=rtpmap:105 H264/90000\n"
|
||||||
|
// "a=fmtp:105 profile-level-id=64001f; packetization-mode=1; sprop-parameter-sets=Z2QAH6wrUCgC3QgAAB9AAAYahCAA,aO4xsg==\n"
|
||||||
|
// "a=recvonly\n"
|
||||||
|
// "m=application 0 RTP/AVP 107\n"
|
||||||
|
// "c=IN IP4 192.168.0.22\n"
|
||||||
|
// "a=control:rtsp://192.168.0.22/media/video1/metadata\n"
|
||||||
|
// "a=rtpmap:107 vnd.onvif.metadata/90000\n"
|
||||||
|
// "a=fmtp:107 DecoderTag=h3c-v3 RTCP=0\n"
|
||||||
|
// "a=recvonly";
|
||||||
|
// RtspTrack track[2];
|
||||||
|
// parserSDP(str,track);
|
||||||
|
// track[0].inited=true;
|
||||||
|
//});
|
||||||
bool MakeNalu(char in, NALU &nal) {
|
bool MakeNalu(char in, NALU &nal) {
|
||||||
nal.forbidden_zero_bit = in >> 7;
|
nal.forbidden_zero_bit = in >> 7;
|
||||||
if (nal.forbidden_zero_bit) {
|
if (nal.forbidden_zero_bit) {
|
||||||
|
@ -44,11 +44,10 @@ class RtspTrack{
|
|||||||
public:
|
public:
|
||||||
uint8_t PT;
|
uint8_t PT;
|
||||||
uint8_t trackId;
|
uint8_t trackId;
|
||||||
string trackIdStr;
|
|
||||||
uint8_t interleaved;
|
uint8_t interleaved;
|
||||||
TrackType type = (TrackType) -1;
|
TrackType type = (TrackType) -1;
|
||||||
string trackSdp;
|
string trackSdp;
|
||||||
string trackStyle;
|
string controlSuffix;
|
||||||
bool inited;
|
bool inited;
|
||||||
uint32_t ssrc = 0;
|
uint32_t ssrc = 0;
|
||||||
uint16_t seq;
|
uint16_t seq;
|
||||||
|
@ -261,21 +261,21 @@ inline void RtspPlayer::sendSetup(unsigned int trackIndex) {
|
|||||||
auto &track = m_aTrackInfo[trackIndex];
|
auto &track = m_aTrackInfo[trackIndex];
|
||||||
switch (m_eType) {
|
switch (m_eType) {
|
||||||
case RTP_TCP: {
|
case RTP_TCP: {
|
||||||
iLen = sprintf(acRtspbuf, "SETUP %s/%s%s RTSP/1.0\r\n"
|
iLen = sprintf(acRtspbuf, "SETUP %s/%s RTSP/1.0\r\n"
|
||||||
"CSeq: %d\r\n"
|
"CSeq: %d\r\n"
|
||||||
"Transport: RTP/AVP/TCP;unicast;interleaved=%d-%d\r\n"
|
"Transport: RTP/AVP/TCP;unicast;interleaved=%d-%d\r\n"
|
||||||
"Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(),
|
"Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(),
|
||||||
track.trackStyle.c_str(), track.trackIdStr.data(), m_uiCseq++,
|
track.controlSuffix.c_str(), m_uiCseq++,
|
||||||
track.trackId * 2, track.trackId * 2 + 1,
|
track.trackId * 2, track.trackId * 2 + 1,
|
||||||
m_strAuthorization.c_str());
|
m_strAuthorization.c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RTP_MULTICAST: {
|
case RTP_MULTICAST: {
|
||||||
iLen = sprintf(acRtspbuf, "SETUP %s/%s%s RTSP/1.0\r\n"
|
iLen = sprintf(acRtspbuf, "SETUP %s/%s RTSP/1.0\r\n"
|
||||||
"CSeq: %d\r\n"
|
"CSeq: %d\r\n"
|
||||||
"Transport: RTP/AVP;multicast\r\n"
|
"Transport: RTP/AVP;multicast\r\n"
|
||||||
"Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(),
|
"Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(),
|
||||||
track.trackStyle.c_str(), track.trackIdStr.data(), m_uiCseq++,
|
track.controlSuffix.c_str(), m_uiCseq++,
|
||||||
m_strAuthorization.c_str());
|
m_strAuthorization.c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -286,11 +286,11 @@ inline void RtspPlayer::sendSetup(unsigned int trackIndex) {
|
|||||||
throw std::runtime_error("open udp sock err");
|
throw std::runtime_error("open udp sock err");
|
||||||
}
|
}
|
||||||
int port = m_apUdpSock[trackIndex]->get_local_port();
|
int port = m_apUdpSock[trackIndex]->get_local_port();
|
||||||
iLen = sprintf(acRtspbuf, "SETUP %s/%s%s RTSP/1.0\r\n"
|
iLen = sprintf(acRtspbuf, "SETUP %s/%s RTSP/1.0\r\n"
|
||||||
"CSeq: %d\r\n"
|
"CSeq: %d\r\n"
|
||||||
"Transport: RTP/AVP;unicast;client_port=%d-%d\r\n"
|
"Transport: RTP/AVP;unicast;client_port=%d-%d\r\n"
|
||||||
"Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(),
|
"Authorization: Basic %s\r\n\r\n", m_strContentBase.c_str(),
|
||||||
track.trackStyle.c_str(), track.trackIdStr.data(), m_uiCseq++, port,
|
track.controlSuffix.c_str(), m_uiCseq++, port,
|
||||||
port + 1, m_strAuthorization.c_str());
|
port + 1, m_strAuthorization.c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -456,12 +456,12 @@ void RtspPlayer::HandleResPAUSE(const Parser& parser, bool bPause) {
|
|||||||
vector<string> vec = split(strRtpInfo, ",");
|
vector<string> vec = split(strRtpInfo, ",");
|
||||||
for(auto &strTrack : vec){
|
for(auto &strTrack : vec){
|
||||||
strTrack.append(";");
|
strTrack.append(";");
|
||||||
auto strTrackId = FindField(strTrack.data(), m_aTrackInfo[0].trackStyle.data(), ";");
|
auto strControlSuffix = strTrack.substr(1 + strTrack.find_last_of('/'),strTrack.find(';') - strTrack.find_last_of('/') - 1);
|
||||||
auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";");
|
auto strRtpTime = FindField(strTrack.data(), "rtptime=", ";");
|
||||||
auto iIdx = getTrackIndex(atoi(strTrackId.data()));
|
auto iIdx = getTrackIndex(strControlSuffix);
|
||||||
m_adFistStamp[iIdx] = atoll(strRtpTime.data());
|
m_adFistStamp[iIdx] = atoll(strRtpTime.data());
|
||||||
m_adNowStamp[iIdx] = m_adFistStamp[iIdx];
|
m_adNowStamp[iIdx] = m_adFistStamp[iIdx];
|
||||||
DebugL << "rtptime:" << strTrackId <<" " << strRtpTime;
|
DebugL << "rtptime:" << strControlSuffix <<" " << strRtpTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_onPlayResult(SockException(Err_success, "rtsp play success"));
|
_onPlayResult(SockException(Err_success, "rtsp play success"));
|
||||||
|
@ -127,14 +127,22 @@ private:
|
|||||||
inline bool HandleOneRtp(int iTrackidx, unsigned char *ucData, unsigned int uiLen);
|
inline bool HandleOneRtp(int iTrackidx, unsigned char *ucData, unsigned int uiLen);
|
||||||
bool sendOptions();
|
bool sendOptions();
|
||||||
inline void _onRecvRTP(const RtpPacket::Ptr &pRtppt, int iTrackidx);
|
inline void _onRecvRTP(const RtpPacket::Ptr &pRtppt, int iTrackidx);
|
||||||
inline int getTrackIndex(int iTrackId) const{
|
inline int getTrackIndex(const string &controlSuffix) const{
|
||||||
for (unsigned int i = 0; i < m_uiTrackCnt; i++) {
|
for (unsigned int i = 0; i < m_uiTrackCnt; i++) {
|
||||||
if (m_aTrackInfo[i].trackId == iTrackId) {
|
if (m_aTrackInfo[i].controlSuffix == controlSuffix) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
inline int getTrackIndex(int iTrackId) const{
|
||||||
|
for (unsigned int i = 0; i < m_uiTrackCnt; i++) {
|
||||||
|
if (m_aTrackInfo[i].trackId == iTrackId) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
string m_strUrl;
|
string m_strUrl;
|
||||||
unsigned int m_uiTrackCnt = 0;
|
unsigned int m_uiTrackCnt = 0;
|
||||||
|
@ -481,11 +481,8 @@ inline void RtspSession::send_SessionNotFound() {
|
|||||||
}
|
}
|
||||||
bool RtspSession::handleReq_Setup() {
|
bool RtspSession::handleReq_Setup() {
|
||||||
//处理setup命令,该函数可能进入多次
|
//处理setup命令,该函数可能进入多次
|
||||||
//track id
|
auto controlSuffix = m_parser.Url().substr(1 + m_parser.Url().find_last_of('/'));
|
||||||
int trackid = atoi( FindField( m_parser.Url().data(),
|
int trackIdx = getTrackIndexByControlSuffix(controlSuffix);
|
||||||
m_aTrackInfo[0].trackStyle.data(),
|
|
||||||
NULL).data());
|
|
||||||
int trackIdx = getTrackIndexByTrackId(trackid);
|
|
||||||
if (trackIdx == -1) {
|
if (trackIdx == -1) {
|
||||||
//未找到相应track
|
//未找到相应track
|
||||||
return false;
|
return false;
|
||||||
@ -541,8 +538,8 @@ bool RtspSession::handleReq_Setup() {
|
|||||||
"x-Dynamic-Rate: 1\r\n\r\n",
|
"x-Dynamic-Rate: 1\r\n\r\n",
|
||||||
m_iCseq, SERVER_NAME,
|
m_iCseq, SERVER_NAME,
|
||||||
RTSP_VERSION, RTSP_BUILDTIME,
|
RTSP_VERSION, RTSP_BUILDTIME,
|
||||||
dateHeader().data(), trackid * 2,
|
dateHeader().data(), trackRef.trackId * 2,
|
||||||
trackid * 2 + 1,
|
trackRef.trackId * 2 + 1,
|
||||||
printSSRC(trackRef.ssrc).data(),
|
printSSRC(trackRef.ssrc).data(),
|
||||||
m_strSession.data());
|
m_strSession.data());
|
||||||
send(m_pcBuf, iLen);
|
send(m_pcBuf, iLen);
|
||||||
@ -609,7 +606,7 @@ bool RtspSession::handleReq_Setup() {
|
|||||||
strongSelf->safeShutdown();
|
strongSelf->safeShutdown();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
int iSrvPort = m_pBrdcaster->getPort(trackid);
|
int iSrvPort = m_pBrdcaster->getPort(trackRef.trackId);
|
||||||
//我们用trackIdx区分rtp和rtcp包
|
//我们用trackIdx区分rtp和rtcp包
|
||||||
auto pSockRtcp = UDPServer::Instance().getSock(get_local_ip().data(),2*trackIdx + 1,iSrvPort + 1);
|
auto pSockRtcp = UDPServer::Instance().getSock(get_local_ip().data(),2*trackIdx + 1,iSrvPort + 1);
|
||||||
if (!pSockRtcp) {
|
if (!pSockRtcp) {
|
||||||
@ -734,9 +731,8 @@ bool RtspSession::handleReq_Play() {
|
|||||||
shutdown();
|
shutdown();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iLen += sprintf(m_pcBuf + iLen, "url=%s/%s%s;seq=%d;rtptime=%u,",
|
iLen += sprintf(m_pcBuf + iLen, "url=%s/%s;seq=%d;rtptime=%u,",
|
||||||
m_strUrl.data(), track.trackStyle.data(),
|
m_strUrl.data(), track.controlSuffix.data(), track.seq,track.timeStamp);
|
||||||
track.trackIdStr.data(), track.seq,track.timeStamp);
|
|
||||||
}
|
}
|
||||||
iLen -= 1;
|
iLen -= 1;
|
||||||
(m_pcBuf)[iLen] = '\0';
|
(m_pcBuf)[iLen] = '\0';
|
||||||
|
@ -134,6 +134,15 @@ private:
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
inline int getTrackIndexByControlSuffix(const string &controlSuffix) {
|
||||||
|
for (unsigned int i = 0; i < m_uiTrackCnt; i++) {
|
||||||
|
if (controlSuffix == m_aTrackInfo[i].controlSuffix) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
inline void onRcvPeerUdpData(int iTrackIdx, const Buffer::Ptr &pBuf, const struct sockaddr &addr);
|
inline void onRcvPeerUdpData(int iTrackIdx, const Buffer::Ptr &pBuf, const struct sockaddr &addr);
|
||||||
inline void startListenPeerUdpData();
|
inline void startListenPeerUdpData();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user