addStreamProxy新增force,支持强制重试拉流

This commit is contained in:
xia-chu 2026-03-17 19:30:08 +08:00
parent a13063c5e4
commit 4e170e9281
6 changed files with 43 additions and 22 deletions

View File

@ -875,6 +875,12 @@
"description": "推流重试次数,不传此参数或传值<=0时则无限重试",
"disabled": true
},
{
"key": "force",
"value": null,
"description": "是否强制添加代理默认0设置为1时如果拉流失败也会不断重试",
"disabled": true
},
{
"key": "latency",
"value": null,

View File

@ -583,7 +583,7 @@ void getStatisticJson(const function<void(Value &val)> &cb) {
#endif
}
void addStreamProxy(const MediaTuple &tuple, const string &url, int retry_count,
void addStreamProxy(const MediaTuple &tuple, const string &url, int retry_count, bool force,
const ProtocolOption &option, int rtp_type, float timeout_sec, const mINI &args,
const function<void(const SockException &ex, const string &key)> &cb) {
auto key = tuple.shortUrl();
@ -615,11 +615,18 @@ void addStreamProxy(const MediaTuple &tuple, const string &url, int retry_count,
// 开始播放,如果播放失败或者播放中止,将会自动重试若干次,默认一直重试 [AUTO-TRANSLATED:ac8499e5]
// Start playing. If playback fails or is stopped, it will automatically retry several times, by default it will retry indefinitely
player->setPlayCallbackOnce([cb, key](const SockException &ex) {
if (ex) {
s_player_proxy.erase(key);
player->setPlayCallbackOnce([cb, key, force](const SockException &ex) {
if (force) {
// 强制添加成功
cb(SockException(), key);
} else {
// 非强制添加
if (ex) {
// 失败则移除记录
s_player_proxy.erase(key);
}
cb(ex, key);
}
cb(ex, key);
});
// 被主动关闭拉流 [AUTO-TRANSLATED:41a19476]
@ -1264,6 +1271,7 @@ void installWebApi() {
addStreamProxy(tuple,
allArgs["url"],
retry_count,
allArgs["force"],
option,
allArgs["rtp_type"],
allArgs["timeout_sec"],

View File

@ -248,7 +248,7 @@ uint16_t openRtpServer(uint16_t local_port, const mediakit::MediaTuple &tuple, i
Json::Value makeMediaSourceJson(mediakit::MediaSource &media);
ApiArgsType getAllArgs(const mediakit::Parser &parser);
void getStatisticJson(const std::function<void(Json::Value &val)> &cb);
void addStreamProxy(const mediakit::MediaTuple &tuple, const std::string &url, int retry_count,
void addStreamProxy(const mediakit::MediaTuple &tuple, const std::string &url, int retry_count, bool force,
const mediakit::ProtocolOption &option, int rtp_type, float timeout_sec, const toolkit::mINI &args,
const std::function<void(const toolkit::SockException &ex, const std::string &key)> &cb);

View File

@ -321,7 +321,7 @@ static void pullStreamFromOrigin(const vector<string> &urls, size_t index, size_
option.enable_hls = option.enable_hls || (args.schema == HLS_SCHEMA);
option.enable_mp4 = false;
addStreamProxy(args, url, retry_count, option, Rtsp::RTP_TCP, timeout_sec, mINI{}, [=](const SockException &ex, const string &key) mutable {
addStreamProxy(args, url, retry_count, false, option, Rtsp::RTP_TCP, timeout_sec, mINI{}, [=](const SockException &ex, const string &key) mutable {
if (!ex) {
return;
}

View File

@ -46,6 +46,10 @@ void TsPlayerImp::onPlayResult(const SockException &ex) {
}
void TsPlayerImp::onShutdown(const SockException &ex) {
if (!ex) {
// http-ts拉流如果为eof正常断开那么强制为异常状态
const_cast<SockException &>(ex).reset(Err_other, ex.what());
}
while (_demuxer) {
try {
// shared_from_this()可能抛异常 [AUTO-TRANSLATED:6af9bd3c]

View File

@ -32,7 +32,7 @@ PlayerProxy::PlayerProxy(
setOnClose(nullptr);
setOnConnect(nullptr);
setOnDisconnect(nullptr);
_reconnect_delay_min = reconnect_delay_min > 0 ? reconnect_delay_min : 2;
_reconnect_delay_max = reconnect_delay_max > 0 ? reconnect_delay_max : 60;
_reconnect_delay_step = reconnect_delay_step > 0 ? reconnect_delay_step : 3;
@ -51,15 +51,14 @@ void PlayerProxy::setOnClose(function<void(const SockException &ex)> cb) {
}
void PlayerProxy::setOnDisconnect(std::function<void()> cb) {
_on_disconnect = cb ? std::move(cb) : [] () {};
_on_disconnect = cb ? std::move(cb) : []() {};
}
void PlayerProxy::setOnConnect(std::function<void(const TranslationInfo&)> cb) {
_on_connect = cb ? std::move(cb) : [](const TranslationInfo&) {};
void PlayerProxy::setOnConnect(std::function<void(const TranslationInfo &)> cb) {
_on_connect = cb ? std::move(cb) : [](const TranslationInfo &) {};
}
void PlayerProxy::setTranslationInfo()
{
void PlayerProxy::setTranslationInfo() {
_transtalion_info.byte_speed = _media_src ? _media_src->getBytesSpeed() : -1;
_transtalion_info.start_time_stamp = _media_src ? _media_src->getCreateStamp() : 0;
_transtalion_info.stream_info.clear();
@ -72,22 +71,21 @@ void PlayerProxy::setTranslationInfo()
back.codec_type = track->getTrackType();
back.codec_name = track->getCodecName();
switch (back.codec_type) {
case TrackAudio : {
case TrackAudio: {
auto audio_track = dynamic_pointer_cast<AudioTrack>(track);
back.audio_sample_rate = audio_track->getAudioSampleRate();
back.audio_channel = audio_track->getAudioChannel();
back.audio_sample_bit = audio_track->getAudioSampleBit();
break;
}
case TrackVideo : {
case TrackVideo: {
auto video_track = dynamic_pointer_cast<VideoTrack>(track);
back.video_width = video_track->getVideoWidth();
back.video_height = video_track->getVideoHeight();
back.video_fps = video_track->getVideoFps();
break;
}
default:
break;
default: break;
}
}
}
@ -120,7 +118,8 @@ void PlayerProxy::play(const string &strUrlTmp) {
if (!err) {
// 取消定时器,避免hls拉流索引文件因为网络波动失败重连成功后出现循环重试的情况 [AUTO-TRANSLATED:91e5f0c8]
// Cancel the timer to avoid the situation where the hls stream index file fails to reconnect due to network fluctuations and then retries in a loop after successful reconnection
// Cancel the timer to avoid the situation where the hls stream index file fails to reconnect due to network fluctuations and then retries in a loop
// after successful reconnection
strongSelf->_timer.reset();
strongSelf->_live_ticker.resetTime();
strongSelf->_live_status = 0;
@ -129,7 +128,7 @@ void PlayerProxy::play(const string &strUrlTmp) {
*piFailedCnt = 0; // 连续播放失败次数清0
strongSelf->onPlaySuccess();
strongSelf->setTranslationInfo();
strongSelf->_on_connect(strongSelf->_transtalion_info);
strongSelf->_on_connect(strongSelf->_transtalion_info);
InfoL << "play " << strUrlTmp << " success";
} else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) {
@ -151,6 +150,10 @@ void PlayerProxy::play(const string &strUrlTmp) {
if (err) {
NOTICE_EMIT(BroadcastPlayerProxyFailedArgs, Broadcast::kBroadcastPlayerProxyFailed, *strongSelf, err);
}
if (strongSelf->_on_play) {
strongSelf->_on_play(err);
strongSelf->_on_play = nullptr;
}
// 注销直接拉流代理产生的流:#532 [AUTO-TRANSLATED:c6343a3b]
// Unregister the stream generated by the direct stream proxy: #532
@ -291,7 +294,7 @@ float PlayerProxy::getLossRate(MediaSource &sender, TrackType type) {
return getPacketLossRate(type);
}
toolkit::EventPoller::Ptr PlayerProxy::getOwnerPoller(MediaSource &sender) {
toolkit::EventPoller::Ptr PlayerProxy::getOwnerPoller(MediaSource &sender) {
return getPoller();
}
@ -314,10 +317,10 @@ void PlayerProxy::onPlaySuccess() {
// rtmp拉流代理 [AUTO-TRANSLATED:21173335]
// Rtmp stream proxy
if (reset_when_replay || !_muxer) {
auto old = _option.enable_rtmp;
auto old = _option.enable_rtmp;
_option.enable_rtmp = false;
_muxer = std::make_shared<MultiMediaSourceMuxer>(_tuple, getDuration(), _option);
_option.enable_rtmp = old;
_option.enable_rtmp = old;
}
} else {
// 其他拉流代理 [AUTO-TRANSLATED:e5f2e45d]