修复海康rtsp点播拉流seek相关bug(#2501 #2511)

This commit is contained in:
xiongguangjie 2023-05-31 09:59:41 +08:00 committed by GitHub
parent 0232caf068
commit 11a39c68c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -8,34 +8,29 @@
* may be found in the AUTHORS file in the root of the source tree. * may be found in the AUTHORS file in the root of the source tree.
*/ */
#include <set>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include "Common/config.h"
#include "RtspPlayer.h" #include "RtspPlayer.h"
#include "Util/MD5.h" #include "Common/config.h"
#include "Util/base64.h"
#include "Rtcp/Rtcp.h" #include "Rtcp/Rtcp.h"
#include "Rtcp/RtcpContext.h" #include "Rtcp/RtcpContext.h"
#include "RtspMediaSource.h"
#include "RtspDemuxer.h" #include "RtspDemuxer.h"
#include "RtspMediaSource.h"
#include "RtspPlayerImp.h" #include "RtspPlayerImp.h"
#include "Util/MD5.h"
#include "Util/base64.h"
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <set>
using namespace toolkit; using namespace toolkit;
using namespace std; using namespace std;
namespace mediakit { namespace mediakit {
enum PlayType { enum PlayType { type_play = 0, type_pause, type_seek, type_speed };
type_play = 0,
type_pause,
type_seek,
type_speed
};
RtspPlayer::RtspPlayer(const EventPoller::Ptr &poller) : TcpClient(poller){ RtspPlayer::RtspPlayer(const EventPoller::Ptr &poller)
} : TcpClient(poller) {}
RtspPlayer::~RtspPlayer(void) { RtspPlayer::~RtspPlayer(void) {
DebugL << endl; DebugL << endl;
@ -94,14 +89,17 @@ void RtspPlayer::play(const string &strUrl){
weak_ptr<RtspPlayer> weakSelf = static_pointer_cast<RtspPlayer>(shared_from_this()); weak_ptr<RtspPlayer> weakSelf = static_pointer_cast<RtspPlayer>(shared_from_this());
float playTimeOutSec = (*this)[Client::kTimeoutMS].as<int>() / 1000.0f; float playTimeOutSec = (*this)[Client::kTimeoutMS].as<int>() / 1000.0f;
_play_check_timer.reset(new Timer(playTimeOutSec, [weakSelf]() { _play_check_timer.reset(new Timer(
playTimeOutSec,
[weakSelf]() {
auto strongSelf = weakSelf.lock(); auto strongSelf = weakSelf.lock();
if (!strongSelf) { if (!strongSelf) {
return false; return false;
} }
strongSelf->onPlayResult_l(SockException(Err_timeout, "play rtsp timeout"), false); strongSelf->onPlayResult_l(SockException(Err_timeout, "play rtsp timeout"), false);
return false; return false;
}, getPoller())); },
getPoller()));
if (!(*this)[Client::kNetAdapter].empty()) { if (!(*this)[Client::kNetAdapter].empty()) {
setNetAdapter((*this)[Client::kNetAdapter]); setNetAdapter((*this)[Client::kNetAdapter]);
@ -251,23 +249,20 @@ void RtspPlayer::sendSetup(unsigned int track_idx) {
auto control_url = track->getControlUrl(_content_base); auto control_url = track->getControlUrl(_content_base);
switch (_rtp_type) { switch (_rtp_type) {
case Rtsp::RTP_TCP: { case Rtsp::RTP_TCP: {
sendRtspRequest("SETUP", control_url, {"Transport", StrPrinter << "RTP/AVP/TCP;unicast;interleaved=" << track->_type * 2 << "-" << track->_type * 2 + 1}); sendRtspRequest(
} "SETUP", control_url, { "Transport", StrPrinter << "RTP/AVP/TCP;unicast;interleaved=" << track->_type * 2 << "-" << track->_type * 2 + 1 });
break; } break;
case Rtsp::RTP_MULTICAST: { case Rtsp::RTP_MULTICAST: {
sendRtspRequest("SETUP", control_url, { "Transport", "RTP/AVP;multicast" }); sendRtspRequest("SETUP", control_url, { "Transport", "RTP/AVP;multicast" });
} } break;
break;
case Rtsp::RTP_UDP: { case Rtsp::RTP_UDP: {
createUdpSockIfNecessary(track_idx); createUdpSockIfNecessary(track_idx);
sendRtspRequest("SETUP", control_url, {"Transport", sendRtspRequest(
StrPrinter << "RTP/AVP;unicast;client_port=" "SETUP", control_url,
<< _rtp_sock[track_idx]->get_local_port() << "-" { "Transport",
<< _rtcp_sock[track_idx]->get_local_port()}); StrPrinter << "RTP/AVP;unicast;client_port=" << _rtp_sock[track_idx]->get_local_port() << "-" << _rtcp_sock[track_idx]->get_local_port() });
} } break;
break; default: break;
default:
break;
} }
} }
@ -359,8 +354,8 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int track_idx) {
WarnL << "收到其他地址的rtp数据:" << SockUtil::inet_ntoa(addr); WarnL << "收到其他地址的rtp数据:" << SockUtil::inet_ntoa(addr);
return; return;
} }
strongSelf->handleOneRtp(track_idx, strongSelf->_sdp_track[track_idx]->_type, strongSelf->handleOneRtp(
strongSelf->_sdp_track[track_idx]->_samplerate, (uint8_t *) buf->data(), buf->size()); track_idx, strongSelf->_sdp_track[track_idx]->_type, strongSelf->_sdp_track[track_idx]->_samplerate, (uint8_t *)buf->data(), buf->size());
}); });
if (pRtcpSockRef) { if (pRtcpSockRef) {
@ -428,12 +423,10 @@ void RtspPlayer::sendPause(int type , uint32_t seekMS){
_on_response = std::bind(&RtspPlayer::handleResPAUSE, this, placeholders::_1, type); _on_response = std::bind(&RtspPlayer::handleResPAUSE, this, placeholders::_1, type);
// 开启或暂停rtsp // 开启或暂停rtsp
switch (type) { switch (type) {
case type_pause: case type_pause: sendRtspRequest("PAUSE", _content_base); break;
sendRtspRequest("PAUSE", _content_base);
break;
case type_play: case type_play:
sendRtspRequest("PLAY", _content_base); // sendRtspRequest("PLAY", _content_base);
break; // break;
case type_seek: case type_seek:
sendRtspRequest("PLAY", _content_base, { "Range", StrPrinter << "npt=" << setiosflags(ios::fixed) << setprecision(2) << seekMS / 1000.0 << "-" }); sendRtspRequest("PLAY", _content_base, { "Range", StrPrinter << "npt=" << setiosflags(ios::fixed) << setprecision(2) << seekMS / 1000.0 << "-" });
break; break;
@ -455,16 +448,12 @@ void RtspPlayer::speed(float speed) {
void RtspPlayer::handleResPAUSE(const Parser &parser, int type) { void RtspPlayer::handleResPAUSE(const Parser &parser, int type) {
if (parser.Url() != "200") { if (parser.Url() != "200") {
switch (type) { switch (type) {
case type_pause: case type_pause: WarnL << "Pause failed:" << parser.Url() << " " << parser.Tail() << endl; break;
WarnL << "Pause failed:" << parser.Url() << " " << parser.Tail() << endl;
break;
case type_play: case type_play:
WarnL << "Play failed:" << parser.Url() << " " << parser.Tail() << endl; WarnL << "Play failed:" << parser.Url() << " " << parser.Tail() << endl;
onPlayResult_l(SockException(Err_shutdown, StrPrinter << "rtsp play failed:" << parser.Url() << " " << parser.Tail()), !_play_check_timer); onPlayResult_l(SockException(Err_shutdown, StrPrinter << "rtsp play failed:" << parser.Url() << " " << parser.Tail()), !_play_check_timer);
break; break;
case type_seek: case type_seek: WarnL << "Seek failed:" << parser.Url() << " " << parser.Tail() << endl; break;
WarnL << "Seek failed:" << parser.Url() << " " << parser.Tail() << endl;
break;
} }
return; return;
} }
@ -513,7 +502,9 @@ void RtspPlayer::onRtpPacket(const char *data, size_t len) {
if (trackIdx == -1) { if (trackIdx == -1) {
return; return;
} }
handleOneRtp(trackIdx, _sdp_track[trackIdx]->_type, _sdp_track[trackIdx]->_samplerate, (uint8_t *)data + RtpPacket::kRtpTcpHeaderSize, len - RtpPacket::kRtpTcpHeaderSize); handleOneRtp(
trackIdx, _sdp_track[trackIdx]->_type, _sdp_track[trackIdx]->_samplerate, (uint8_t *)data + RtpPacket::kRtpTcpHeaderSize,
len - RtpPacket::kRtpTcpHeaderSize);
} else { } else {
trackIdx = getTrackIndexByInterleaved(interleaved - 1); trackIdx = getTrackIndexByInterleaved(interleaved - 1);
if (trackIdx == -1) { if (trackIdx == -1) {
@ -624,7 +615,12 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
} }
_StrPrinter printer; _StrPrinter printer;
if (cmd == "PLAY") {
printer << cmd << " " << _play_url << " RTSP/1.0\r\n";
} else {
printer << cmd << " " << url << " RTSP/1.0\r\n"; printer << cmd << " " << url << " RTSP/1.0\r\n";
}
for (auto &pr : header) { for (auto &pr : header) {
printer << pr.first << ": " << pr.second << "\r\n"; printer << pr.first << ": " << pr.second << "\r\n";
} }
@ -752,8 +748,7 @@ int RtspPlayer::getTrackIndexByTrackType(TrackType track_type) const {
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
// RtspPlayerImp // RtspPlayerImp
float RtspPlayerImp::getDuration() const float RtspPlayerImp::getDuration() const {
{
return _demuxer ? _demuxer->getDuration() : 0; return _demuxer ? _demuxer->getDuration() : 0;
} }
@ -770,13 +765,11 @@ void RtspPlayerImp::addTrackCompleted() {
} }
} }
std::vector<Track::Ptr> RtspPlayerImp::getTracks(bool ready /*= true*/) const std::vector<Track::Ptr> RtspPlayerImp::getTracks(bool ready /*= true*/) const {
{
return _demuxer ? _demuxer->getTracks(ready) : Super::getTracks(ready); return _demuxer ? _demuxer->getTracks(ready) : Super::getTracks(ready);
} }
bool RtspPlayerImp::onCheckSDP(const std::string &sdp) bool RtspPlayerImp::onCheckSDP(const std::string &sdp) {
{
_rtsp_media_src = std::dynamic_pointer_cast<RtspMediaSource>(_media_src); _rtsp_media_src = std::dynamic_pointer_cast<RtspMediaSource>(_media_src);
if (_rtsp_media_src) { if (_rtsp_media_src) {
_rtsp_media_src->setSdp(sdp); _rtsp_media_src->setSdp(sdp);