Skip to content

Commit

Permalink
feat: Using kBeatIntervalMS option for rtsp heartbeat interval time a…
Browse files Browse the repository at this point in the history
…nd add kRtspBeatType for setting rtsp heartbeat type
  • Loading branch information
xia-chu committed May 11, 2024
1 parent 1c89950 commit bbdbd6a
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/Common/config.cpp
Expand Up @@ -361,6 +361,7 @@ static onceToken token([]() {
namespace Client {
const string kNetAdapter = "net_adapter";
const string kRtpType = "rtp_type";
const string kRtspBeatType = "rtsp_beat_type";
const string kRtspUser = "rtsp_user";
const string kRtspPwd = "rtsp_pwd";
const string kRtspPwdIsMD5 = "rtsp_pwd_md5";
Expand Down
3 changes: 3 additions & 0 deletions src/Common/config.h
Expand Up @@ -417,6 +417,9 @@ extern const std::string kNetAdapter;
// 设置rtp传输类型,可选项有0(tcp,默认)、1(udp)、2(组播)
// 设置方法:player[PlayerBase::kRtpType] = 0/1/2;
extern const std::string kRtpType;
// rtsp播放器发送信令心跳还是rtcp心跳,可选项有0(同时发)、1(rtcp心跳)、2(信令心跳)
// 设置方法:player[PlayerBase::kRtspBeatType] = 0/1/2;
extern const std::string kRtspBeatType;
// rtsp认证用户名
extern const std::string kRtspUser;
// rtsp认证用用户密码,可以是明文也可以是md5,md5密码生成方式 md5(username:realm:password)
Expand Down
25 changes: 15 additions & 10 deletions src/Rtsp/RtspPlayer.cpp
Expand Up @@ -28,6 +28,7 @@ using namespace std;
namespace mediakit {

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)
: TcpClient(poller) {}
Expand Down Expand Up @@ -85,6 +86,8 @@ void RtspPlayer::play(const string &strUrl) {

_play_url = url._url;
_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;

weak_ptr<RtspPlayer> weakSelf = static_pointer_cast<RtspPlayer>(shared_from_this());
Expand Down Expand Up @@ -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);

auto &ticker = _rtcp_send_ticker[track_idx];
if (ticker.elapsedTime() < 3 * 1000) {
// 时间未到
if (ticker.elapsedTime() < _beat_interval_ms) {
// 心跳时间未到
return;
}

// 有些rtsp服务器需要rtcp保活,有些需要发送信令保活; rtcp与rtsp信令轮流心跳,该特性用于兼容issue:#642
auto &rtcp_flag = _send_rtcp[track_idx];
ticker.resetTime();

// 每3秒发送一次心跳,rtcp与rtsp信令轮流心跳,该特性用于兼容issue:642
// 有些rtsp服务器需要rtcp保活,有些需要发送信令保活
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 (track_idx == 0) {
// 两个track无需同时触发发送信令保活
sendKeepAlive();
}
ticker.resetTime();
// 下次发送rtcp保活
rtcp_flag = true;
return;
}

Expand All @@ -680,9 +688,6 @@ void RtspPlayer::onBeforeRtpSorted(const RtpPacket::Ptr &rtp, int track_idx) {
rtcp_sdes->chunks.ssrc = htonl(ssrc);
send_rtcp(this, track_idx, std::move(rtcp));
send_rtcp(this, track_idx, RtcpHeader::toBuffer(rtcp_sdes));
ticker.resetTime();
// 下次发送信令保活
rtcp_flag = false;
}

void RtspPlayer::onPlayResult_l(const SockException &ex, bool handshake_done) {
Expand Down
5 changes: 5 additions & 0 deletions src/Rtsp/RtspPlayer.h
Expand Up @@ -114,6 +114,11 @@ class RtspPlayer : public PlayerBase, public toolkit::TcpClient, public RtspSpli
//轮流发送rtcp与GET_PARAMETER保活
bool _send_rtcp[2] = {true, true};

// 心跳类型
uint32_t _beat_type = 0;
// 心跳保护间隔
uint32_t _beat_interval_ms = 0;

std::string _play_url;
std::vector<SdpTrack::Ptr> _sdp_track;
std::function<void(const Parser&)> _on_response;
Expand Down

0 comments on commit bbdbd6a

Please sign in to comment.