feat: Using kBeatIntervalMS option for rtsp heartbeat interval time and add kRtspBeatType for setting rtsp heartbeat type

This commit is contained in:
xia-chu 2024-05-11 14:38:33 +08:00
parent 1c89950ebe
commit bbdbd6a3e0
4 changed files with 25 additions and 11 deletions

View File

@ -361,6 +361,7 @@ static onceToken token([]() {
namespace Client { namespace Client {
const string kNetAdapter = "net_adapter"; const string kNetAdapter = "net_adapter";
const string kRtpType = "rtp_type"; const string kRtpType = "rtp_type";
const string kRtspBeatType = "rtsp_beat_type";
const string kRtspUser = "rtsp_user"; const string kRtspUser = "rtsp_user";
const string kRtspPwd = "rtsp_pwd"; const string kRtspPwd = "rtsp_pwd";
const string kRtspPwdIsMD5 = "rtsp_pwd_md5"; const string kRtspPwdIsMD5 = "rtsp_pwd_md5";

View File

@ -417,6 +417,9 @@ extern const std::string kNetAdapter;
// 设置rtp传输类型可选项有0(tcp默认)、1(udp)、2(组播) // 设置rtp传输类型可选项有0(tcp默认)、1(udp)、2(组播)
// 设置方法:player[PlayerBase::kRtpType] = 0/1/2; // 设置方法:player[PlayerBase::kRtpType] = 0/1/2;
extern const std::string kRtpType; extern const std::string kRtpType;
// rtsp播放器发送信令心跳还是rtcp心跳可选项有0(同时发)、1(rtcp心跳)、2(信令心跳)
// 设置方法:player[PlayerBase::kRtspBeatType] = 0/1/2;
extern const std::string kRtspBeatType;
// rtsp认证用户名 // rtsp认证用户名
extern const std::string kRtspUser; extern const std::string kRtspUser;
// rtsp认证用用户密码可以是明文也可以是md5,md5密码生成方式 md5(username:realm:password) // rtsp认证用用户密码可以是明文也可以是md5,md5密码生成方式 md5(username:realm:password)

View File

@ -28,6 +28,7 @@ using namespace std;
namespace mediakit { namespace mediakit {
enum PlayType { type_play = 0, type_pause, type_seek, type_speed }; enum PlayType { type_play = 0, type_pause, type_seek, type_speed };
enum class BeatType : uint32_t { both = 0, rtcp, cmd };
RtspPlayer::RtspPlayer(const EventPoller::Ptr &poller) RtspPlayer::RtspPlayer(const EventPoller::Ptr &poller)
: TcpClient(poller) {} : TcpClient(poller) {}
@ -85,6 +86,8 @@ void RtspPlayer::play(const string &strUrl) {
_play_url = url._url; _play_url = url._url;
_rtp_type = (Rtsp::eRtpType)(int)(*this)[Client::kRtpType]; _rtp_type = (Rtsp::eRtpType)(int)(*this)[Client::kRtpType];
_beat_type = (*this)[Client::kRtspBeatType].as<int>();
_beat_interval_ms = (*this)[Client::kBeatIntervalMS].as<int>();
DebugL << url._url << " " << (url._user.size() ? url._user : "null") << " " << (url._passwd.size() ? url._passwd : "null") << " " << _rtp_type; DebugL << url._url << " " << (url._user.size() ? url._user : "null") << " " << (url._passwd.size() ? url._passwd : "null") << " " << _rtp_type;
weak_ptr<RtspPlayer> weakSelf = static_pointer_cast<RtspPlayer>(shared_from_this()); weak_ptr<RtspPlayer> weakSelf = static_pointer_cast<RtspPlayer>(shared_from_this());
@ -642,23 +645,28 @@ void RtspPlayer::onBeforeRtpSorted(const RtpPacket::Ptr &rtp, int track_idx) {
rtcp_ctx->onRtp(rtp->getSeq(), rtp->getStamp(), rtp->ntp_stamp, rtp->sample_rate, rtp->size() - RtpPacket::kRtpTcpHeaderSize); rtcp_ctx->onRtp(rtp->getSeq(), rtp->getStamp(), rtp->ntp_stamp, rtp->sample_rate, rtp->size() - RtpPacket::kRtpTcpHeaderSize);
auto &ticker = _rtcp_send_ticker[track_idx]; auto &ticker = _rtcp_send_ticker[track_idx];
if (ticker.elapsedTime() < 3 * 1000) { if (ticker.elapsedTime() < _beat_interval_ms) {
// 时间未到 // 心跳时间未到
return; return;
} }
auto &rtcp_flag = _send_rtcp[track_idx];
// 每3秒发送一次心跳rtcp与rtsp信令轮流心跳该特性用于兼容issue:642 // 有些rtsp服务器需要rtcp保活有些需要发送信令保活; rtcp与rtsp信令轮流心跳该特性用于兼容issue:#642
// 有些rtsp服务器需要rtcp保活有些需要发送信令保活 auto &rtcp_flag = _send_rtcp[track_idx];
ticker.resetTime();
switch ((BeatType)_beat_type) {
case BeatType::cmd: rtcp_flag = false; break;
case BeatType::rtcp: rtcp_flag = true; break;
case BeatType::both:
default: rtcp_flag = !rtcp_flag; break;
}
// 发送信令保活 // 发送信令保活
if (!rtcp_flag) { if (!rtcp_flag) {
if (track_idx == 0) { if (track_idx == 0) {
// 两个track无需同时触发发送信令保活
sendKeepAlive(); sendKeepAlive();
} }
ticker.resetTime();
// 下次发送rtcp保活
rtcp_flag = true;
return; return;
} }
@ -680,9 +688,6 @@ void RtspPlayer::onBeforeRtpSorted(const RtpPacket::Ptr &rtp, int track_idx) {
rtcp_sdes->chunks.ssrc = htonl(ssrc); rtcp_sdes->chunks.ssrc = htonl(ssrc);
send_rtcp(this, track_idx, std::move(rtcp)); send_rtcp(this, track_idx, std::move(rtcp));
send_rtcp(this, track_idx, RtcpHeader::toBuffer(rtcp_sdes)); send_rtcp(this, track_idx, RtcpHeader::toBuffer(rtcp_sdes));
ticker.resetTime();
// 下次发送信令保活
rtcp_flag = false;
} }
void RtspPlayer::onPlayResult_l(const SockException &ex, bool handshake_done) { void RtspPlayer::onPlayResult_l(const SockException &ex, bool handshake_done) {

View File

@ -114,6 +114,11 @@ private:
//轮流发送rtcp与GET_PARAMETER保活 //轮流发送rtcp与GET_PARAMETER保活
bool _send_rtcp[2] = {true, true}; bool _send_rtcp[2] = {true, true};
// 心跳类型
uint32_t _beat_type = 0;
// 心跳保护间隔
uint32_t _beat_interval_ms = 0;
std::string _play_url; std::string _play_url;
std::vector<SdpTrack::Ptr> _sdp_track; std::vector<SdpTrack::Ptr> _sdp_track;
std::function<void(const Parser&)> _on_response; std::function<void(const Parser&)> _on_response;