mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 12:11:36 +08:00
rtsp推流拉流转发时修整sdp
rtsp推流修整时间戳
This commit is contained in:
parent
bf7363714d
commit
fb1d7dd5a6
1
.gitignore
vendored
1
.gitignore
vendored
@ -34,3 +34,4 @@
|
|||||||
/cmake-build-debug/
|
/cmake-build-debug/
|
||||||
/.idea/
|
/.idea/
|
||||||
/c_wrapper/.idea/
|
/c_wrapper/.idea/
|
||||||
|
/release/mac/Debug/
|
@ -161,13 +161,16 @@ namespace Rtsp {
|
|||||||
const string kAuthBasic = RTSP_FIELD"authBasic";
|
const string kAuthBasic = RTSP_FIELD"authBasic";
|
||||||
const string kHandshakeSecond = RTSP_FIELD"handshakeSecond";
|
const string kHandshakeSecond = RTSP_FIELD"handshakeSecond";
|
||||||
const string kKeepAliveSecond = RTSP_FIELD"keepAliveSecond";
|
const string kKeepAliveSecond = RTSP_FIELD"keepAliveSecond";
|
||||||
const string kDirectProxy = RTSP_FIELD"directProxy";;
|
const string kDirectProxy = RTSP_FIELD"directProxy";
|
||||||
|
const string kModifyStamp = RTSP_FIELD"modifyStamp";
|
||||||
|
|
||||||
onceToken token([](){
|
onceToken token([](){
|
||||||
//默认Md5方式认证
|
//默认Md5方式认证
|
||||||
mINI::Instance()[kAuthBasic] = 0;
|
mINI::Instance()[kAuthBasic] = 0;
|
||||||
mINI::Instance()[kHandshakeSecond] = 15;
|
mINI::Instance()[kHandshakeSecond] = 15;
|
||||||
mINI::Instance()[kKeepAliveSecond] = 15;
|
mINI::Instance()[kKeepAliveSecond] = 15;
|
||||||
mINI::Instance()[kDirectProxy] = 1;
|
mINI::Instance()[kDirectProxy] = 1;
|
||||||
|
mINI::Instance()[kModifyStamp] = true;
|
||||||
},nullptr);
|
},nullptr);
|
||||||
|
|
||||||
} //namespace Rtsp
|
} //namespace Rtsp
|
||||||
|
@ -209,6 +209,8 @@ extern const string kKeepAliveSecond;
|
|||||||
//假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理
|
//假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理
|
||||||
//默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的
|
//默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的
|
||||||
extern const string kDirectProxy;
|
extern const string kDirectProxy;
|
||||||
|
//rtsp推流是否修改时间戳
|
||||||
|
extern const string kModifyStamp;
|
||||||
} //namespace Rtsp
|
} //namespace Rtsp
|
||||||
|
|
||||||
////////////RTMP服务器配置///////////
|
////////////RTMP服务器配置///////////
|
||||||
|
@ -38,10 +38,6 @@ RtspDemuxer::RtspDemuxer(const string& sdp) {
|
|||||||
loadSdp(SdpParser(sdp));
|
loadSdp(SdpParser(sdp));
|
||||||
}
|
}
|
||||||
|
|
||||||
RtspDemuxer::RtspDemuxer(const SdpParser &attr) {
|
|
||||||
loadSdp(attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RtspDemuxer::loadSdp(const SdpParser &attr) {
|
void RtspDemuxer::loadSdp(const SdpParser &attr) {
|
||||||
auto tracks = attr.getAvailableTrack();
|
auto tracks = attr.getAvailableTrack();
|
||||||
for (auto &track : tracks){
|
for (auto &track : tracks){
|
||||||
|
@ -41,7 +41,6 @@ class RtspDemuxer : public Demuxer{
|
|||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<RtspDemuxer> Ptr;
|
typedef std::shared_ptr<RtspDemuxer> Ptr;
|
||||||
RtspDemuxer(const string &sdp);
|
RtspDemuxer(const string &sdp);
|
||||||
RtspDemuxer(const SdpParser &parser);
|
|
||||||
virtual ~RtspDemuxer(){};
|
virtual ~RtspDemuxer(){};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -219,14 +219,14 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
|
|||||||
_strContentBase.pop_back();
|
_strContentBase.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SdpParser sdpParser(parser.Content());
|
||||||
//解析sdp
|
//解析sdp
|
||||||
_sdpParser.load(parser.Content());
|
_aTrackInfo = sdpParser.getAvailableTrack();
|
||||||
_aTrackInfo = _sdpParser.getAvailableTrack();
|
|
||||||
|
|
||||||
if (_aTrackInfo.empty()) {
|
if (_aTrackInfo.empty()) {
|
||||||
throw std::runtime_error("无有效的Sdp Track");
|
throw std::runtime_error("无有效的Sdp Track");
|
||||||
}
|
}
|
||||||
if (!onCheckSDP(parser.Content(), _sdpParser)) {
|
if (!onCheckSDP(sdpParser.toString())) {
|
||||||
throw std::runtime_error("onCheckSDP faied");
|
throw std::runtime_error("onCheckSDP faied");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
float getPacketLossRate(TrackType type) const override;
|
float getPacketLossRate(TrackType type) const override;
|
||||||
protected:
|
protected:
|
||||||
//派生类回调函数
|
//派生类回调函数
|
||||||
virtual bool onCheckSDP(const string &strSdp, const SdpParser &parser) = 0;
|
virtual bool onCheckSDP(const string &strSdp) = 0;
|
||||||
virtual void onRecvRTP(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track) = 0;
|
virtual void onRecvRTP(const RtpPacket::Ptr &pRtppt, const SdpTrack::Ptr &track) = 0;
|
||||||
uint32_t getProgressMilliSecond() const;
|
uint32_t getProgressMilliSecond() const;
|
||||||
void seekToMilliSecond(uint32_t ms);
|
void seekToMilliSecond(uint32_t ms);
|
||||||
@ -124,7 +124,6 @@ private:
|
|||||||
void createUdpSockIfNecessary(int track_idx);
|
void createUdpSockIfNecessary(int track_idx);
|
||||||
private:
|
private:
|
||||||
string _strUrl;
|
string _strUrl;
|
||||||
SdpParser _sdpParser;
|
|
||||||
vector<SdpTrack::Ptr> _aTrackInfo;
|
vector<SdpTrack::Ptr> _aTrackInfo;
|
||||||
function<void(const Parser&)> _onHandshake;
|
function<void(const Parser&)> _onHandshake;
|
||||||
Socket::Ptr _apRtpSock[2]; //RTP端口,trackid idx 为数组下标
|
Socket::Ptr _apRtpSock[2]; //RTP端口,trackid idx 为数组下标
|
||||||
|
@ -61,12 +61,12 @@ public:
|
|||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
//派生类回调函数
|
//派生类回调函数
|
||||||
bool onCheckSDP(const string &sdp, const SdpParser &parser) override {
|
bool onCheckSDP(const string &sdp) override {
|
||||||
_pRtspMediaSrc = dynamic_pointer_cast<RtspMediaSource>(_pMediaSrc);
|
_pRtspMediaSrc = dynamic_pointer_cast<RtspMediaSource>(_pMediaSrc);
|
||||||
if(_pRtspMediaSrc){
|
if(_pRtspMediaSrc){
|
||||||
_pRtspMediaSrc->onGetSDP(parser.toString());
|
_pRtspMediaSrc->onGetSDP(sdp);
|
||||||
}
|
}
|
||||||
_parser.reset(new RtspDemuxer(parser));
|
_parser.reset(new RtspDemuxer(sdp));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void onRecvRTP(const RtpPacket::Ptr &rtp, const SdpTrack::Ptr &track) override {
|
void onRecvRTP(const RtpPacket::Ptr &rtp, const SdpTrack::Ptr &track) override {
|
||||||
|
@ -242,13 +242,13 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
|
|||||||
throw SockException(Err_shutdown,err);
|
throw SockException(Err_shutdown,err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SdpParser sdpParser(parser.Content());
|
||||||
_strSession = makeRandStr(12);
|
_strSession = makeRandStr(12);
|
||||||
_strSdp = parser.Content();
|
_aTrackInfo = sdpParser.getAvailableTrack();
|
||||||
_aTrackInfo = SdpParser(_strSdp).getAvailableTrack();
|
|
||||||
|
|
||||||
_pushSrc = std::make_shared<RtspToRtmpMediaSource>(_mediaInfo._vhost,_mediaInfo._app,_mediaInfo._streamid);
|
_pushSrc = std::make_shared<RtspToRtmpMediaSource>(_mediaInfo._vhost,_mediaInfo._app,_mediaInfo._streamid);
|
||||||
_pushSrc->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
|
_pushSrc->setListener(dynamic_pointer_cast<MediaSourceEvent>(shared_from_this()));
|
||||||
_pushSrc->onGetSDP(_strSdp);
|
_pushSrc->onGetSDP(sdpParser.toString());
|
||||||
sendRtspResponse("200 OK");
|
sendRtspResponse("200 OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,9 +362,7 @@ void RtspSession::onAuthSuccess() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//找到了响应的rtsp流
|
//找到了响应的rtsp流
|
||||||
strongSelf->_strSdp = rtsp_src->getSdp();
|
strongSelf->_aTrackInfo = SdpParser(rtsp_src->getSdp()).getAvailableTrack();
|
||||||
SdpParser sdpParser(strongSelf->_strSdp);
|
|
||||||
strongSelf->_aTrackInfo = sdpParser.getAvailableTrack();
|
|
||||||
if (strongSelf->_aTrackInfo.empty()) {
|
if (strongSelf->_aTrackInfo.empty()) {
|
||||||
//该流无效
|
//该流无效
|
||||||
strongSelf->send_StreamNotFound();
|
strongSelf->send_StreamNotFound();
|
||||||
@ -383,7 +381,7 @@ void RtspSession::onAuthSuccess() {
|
|||||||
{"Content-Base",strongSelf->_strContentBase + "/",
|
{"Content-Base",strongSelf->_strContentBase + "/",
|
||||||
"x-Accept-Retransmit","our-retransmit",
|
"x-Accept-Retransmit","our-retransmit",
|
||||||
"x-Accept-Dynamic-Rate","1"
|
"x-Accept-Dynamic-Rate","1"
|
||||||
},strongSelf->_strSdp);
|
},rtsp_src->getSdp());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
void RtspSession::onAuthFailed(const string &realm,const string &why,bool close) {
|
void RtspSession::onAuthFailed(const string &realm,const string &why,bool close) {
|
||||||
@ -918,7 +916,12 @@ inline void RtspSession::send_NotAcceptable() {
|
|||||||
|
|
||||||
|
|
||||||
void RtspSession::onRtpSorted(const RtpPacket::Ptr &rtppt, int trackidx) {
|
void RtspSession::onRtpSorted(const RtpPacket::Ptr &rtppt, int trackidx) {
|
||||||
|
GET_CONFIG(bool,modify_stamp,Rtsp::kModifyStamp);
|
||||||
|
if(modify_stamp){
|
||||||
|
int64_t dts_out;
|
||||||
|
_stamp[trackidx].revise(0, 0, dts_out, dts_out);
|
||||||
|
rtppt->timeStamp = dts_out;
|
||||||
|
}
|
||||||
_pushSrc->onWrite(rtppt, false);
|
_pushSrc->onWrite(rtppt, false);
|
||||||
}
|
}
|
||||||
inline void RtspSession::onRcvPeerUdpData(int intervaled, const Buffer::Ptr &pBuf, const struct sockaddr& addr) {
|
inline void RtspSession::onRcvPeerUdpData(int intervaled, const Buffer::Ptr &pBuf, const struct sockaddr& addr) {
|
||||||
|
@ -190,8 +190,6 @@ private:
|
|||||||
int _iCseq = 0;
|
int _iCseq = 0;
|
||||||
//ContentBase
|
//ContentBase
|
||||||
string _strContentBase;
|
string _strContentBase;
|
||||||
//推流端发送的sdp或播放端请求的sdp
|
|
||||||
string _strSdp;
|
|
||||||
//Session号
|
//Session号
|
||||||
string _strSession;
|
string _strSession;
|
||||||
//是否第一次播放,第一次播放需要鉴权,第二次播放属于暂停恢复
|
//是否第一次播放,第一次播放需要鉴权,第二次播放属于暂停恢复
|
||||||
@ -235,6 +233,8 @@ private:
|
|||||||
RtcpCounter _aRtcpCnt[2];
|
RtcpCounter _aRtcpCnt[2];
|
||||||
//rtcp发送时间,trackid idx 为数组下标
|
//rtcp发送时间,trackid idx 为数组下标
|
||||||
Ticker _aRtcpTicker[2];
|
Ticker _aRtcpTicker[2];
|
||||||
|
//时间戳修整器
|
||||||
|
Stamp _stamp[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user