mirror of
https://gitee.com/xia-chu/ZLMediaKit.git
synced 2026-05-17 23:37:49 +08:00
addStreamProxy新增force,支持强制重试拉流
This commit is contained in:
parent
a13063c5e4
commit
4e170e9281
@ -875,6 +875,12 @@
|
|||||||
"description": "推流重试次数,不传此参数或传值<=0时,则无限重试",
|
"description": "推流重试次数,不传此参数或传值<=0时,则无限重试",
|
||||||
"disabled": true
|
"disabled": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "force",
|
||||||
|
"value": null,
|
||||||
|
"description": "是否强制添加代理,默认0,设置为1时如果拉流失败也会不断重试",
|
||||||
|
"disabled": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "latency",
|
"key": "latency",
|
||||||
"value": null,
|
"value": null,
|
||||||
|
|||||||
@ -583,7 +583,7 @@ void getStatisticJson(const function<void(Value &val)> &cb) {
|
|||||||
#endif
|
#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 ProtocolOption &option, int rtp_type, float timeout_sec, const mINI &args,
|
||||||
const function<void(const SockException &ex, const string &key)> &cb) {
|
const function<void(const SockException &ex, const string &key)> &cb) {
|
||||||
auto key = tuple.shortUrl();
|
auto key = tuple.shortUrl();
|
||||||
@ -615,11 +615,18 @@ void addStreamProxy(const MediaTuple &tuple, const string &url, int retry_count,
|
|||||||
|
|
||||||
// 开始播放,如果播放失败或者播放中止,将会自动重试若干次,默认一直重试 [AUTO-TRANSLATED:ac8499e5]
|
// 开始播放,如果播放失败或者播放中止,将会自动重试若干次,默认一直重试 [AUTO-TRANSLATED:ac8499e5]
|
||||||
// Start playing. If playback fails or is stopped, it will automatically retry several times, by default it will retry indefinitely
|
// 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) {
|
player->setPlayCallbackOnce([cb, key, force](const SockException &ex) {
|
||||||
if (ex) {
|
if (force) {
|
||||||
s_player_proxy.erase(key);
|
// 强制添加成功
|
||||||
|
cb(SockException(), key);
|
||||||
|
} else {
|
||||||
|
// 非强制添加
|
||||||
|
if (ex) {
|
||||||
|
// 失败则移除记录
|
||||||
|
s_player_proxy.erase(key);
|
||||||
|
}
|
||||||
|
cb(ex, key);
|
||||||
}
|
}
|
||||||
cb(ex, key);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 被主动关闭拉流 [AUTO-TRANSLATED:41a19476]
|
// 被主动关闭拉流 [AUTO-TRANSLATED:41a19476]
|
||||||
@ -1264,6 +1271,7 @@ void installWebApi() {
|
|||||||
addStreamProxy(tuple,
|
addStreamProxy(tuple,
|
||||||
allArgs["url"],
|
allArgs["url"],
|
||||||
retry_count,
|
retry_count,
|
||||||
|
allArgs["force"],
|
||||||
option,
|
option,
|
||||||
allArgs["rtp_type"],
|
allArgs["rtp_type"],
|
||||||
allArgs["timeout_sec"],
|
allArgs["timeout_sec"],
|
||||||
|
|||||||
@ -248,7 +248,7 @@ uint16_t openRtpServer(uint16_t local_port, const mediakit::MediaTuple &tuple, i
|
|||||||
Json::Value makeMediaSourceJson(mediakit::MediaSource &media);
|
Json::Value makeMediaSourceJson(mediakit::MediaSource &media);
|
||||||
ApiArgsType getAllArgs(const mediakit::Parser &parser);
|
ApiArgsType getAllArgs(const mediakit::Parser &parser);
|
||||||
void getStatisticJson(const std::function<void(Json::Value &val)> &cb);
|
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 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);
|
const std::function<void(const toolkit::SockException &ex, const std::string &key)> &cb);
|
||||||
|
|
||||||
|
|||||||
@ -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_hls = option.enable_hls || (args.schema == HLS_SCHEMA);
|
||||||
option.enable_mp4 = false;
|
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) {
|
if (!ex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,6 +46,10 @@ void TsPlayerImp::onPlayResult(const SockException &ex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TsPlayerImp::onShutdown(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) {
|
while (_demuxer) {
|
||||||
try {
|
try {
|
||||||
// shared_from_this()可能抛异常 [AUTO-TRANSLATED:6af9bd3c]
|
// shared_from_this()可能抛异常 [AUTO-TRANSLATED:6af9bd3c]
|
||||||
|
|||||||
@ -32,7 +32,7 @@ PlayerProxy::PlayerProxy(
|
|||||||
setOnClose(nullptr);
|
setOnClose(nullptr);
|
||||||
setOnConnect(nullptr);
|
setOnConnect(nullptr);
|
||||||
setOnDisconnect(nullptr);
|
setOnDisconnect(nullptr);
|
||||||
|
|
||||||
_reconnect_delay_min = reconnect_delay_min > 0 ? reconnect_delay_min : 2;
|
_reconnect_delay_min = reconnect_delay_min > 0 ? reconnect_delay_min : 2;
|
||||||
_reconnect_delay_max = reconnect_delay_max > 0 ? reconnect_delay_max : 60;
|
_reconnect_delay_max = reconnect_delay_max > 0 ? reconnect_delay_max : 60;
|
||||||
_reconnect_delay_step = reconnect_delay_step > 0 ? reconnect_delay_step : 3;
|
_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) {
|
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) {
|
void PlayerProxy::setOnConnect(std::function<void(const TranslationInfo &)> cb) {
|
||||||
_on_connect = cb ? std::move(cb) : [](const TranslationInfo&) {};
|
_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.byte_speed = _media_src ? _media_src->getBytesSpeed() : -1;
|
||||||
_transtalion_info.start_time_stamp = _media_src ? _media_src->getCreateStamp() : 0;
|
_transtalion_info.start_time_stamp = _media_src ? _media_src->getCreateStamp() : 0;
|
||||||
_transtalion_info.stream_info.clear();
|
_transtalion_info.stream_info.clear();
|
||||||
@ -72,22 +71,21 @@ void PlayerProxy::setTranslationInfo()
|
|||||||
back.codec_type = track->getTrackType();
|
back.codec_type = track->getTrackType();
|
||||||
back.codec_name = track->getCodecName();
|
back.codec_name = track->getCodecName();
|
||||||
switch (back.codec_type) {
|
switch (back.codec_type) {
|
||||||
case TrackAudio : {
|
case TrackAudio: {
|
||||||
auto audio_track = dynamic_pointer_cast<AudioTrack>(track);
|
auto audio_track = dynamic_pointer_cast<AudioTrack>(track);
|
||||||
back.audio_sample_rate = audio_track->getAudioSampleRate();
|
back.audio_sample_rate = audio_track->getAudioSampleRate();
|
||||||
back.audio_channel = audio_track->getAudioChannel();
|
back.audio_channel = audio_track->getAudioChannel();
|
||||||
back.audio_sample_bit = audio_track->getAudioSampleBit();
|
back.audio_sample_bit = audio_track->getAudioSampleBit();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TrackVideo : {
|
case TrackVideo: {
|
||||||
auto video_track = dynamic_pointer_cast<VideoTrack>(track);
|
auto video_track = dynamic_pointer_cast<VideoTrack>(track);
|
||||||
back.video_width = video_track->getVideoWidth();
|
back.video_width = video_track->getVideoWidth();
|
||||||
back.video_height = video_track->getVideoHeight();
|
back.video_height = video_track->getVideoHeight();
|
||||||
back.video_fps = video_track->getVideoFps();
|
back.video_fps = video_track->getVideoFps();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default: break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,7 +118,8 @@ void PlayerProxy::play(const string &strUrlTmp) {
|
|||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
// 取消定时器,避免hls拉流索引文件因为网络波动失败重连成功后出现循环重试的情况 [AUTO-TRANSLATED:91e5f0c8]
|
// 取消定时器,避免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->_timer.reset();
|
||||||
strongSelf->_live_ticker.resetTime();
|
strongSelf->_live_ticker.resetTime();
|
||||||
strongSelf->_live_status = 0;
|
strongSelf->_live_status = 0;
|
||||||
@ -129,7 +128,7 @@ void PlayerProxy::play(const string &strUrlTmp) {
|
|||||||
*piFailedCnt = 0; // 连续播放失败次数清0
|
*piFailedCnt = 0; // 连续播放失败次数清0
|
||||||
strongSelf->onPlaySuccess();
|
strongSelf->onPlaySuccess();
|
||||||
strongSelf->setTranslationInfo();
|
strongSelf->setTranslationInfo();
|
||||||
strongSelf->_on_connect(strongSelf->_transtalion_info);
|
strongSelf->_on_connect(strongSelf->_transtalion_info);
|
||||||
|
|
||||||
InfoL << "play " << strUrlTmp << " success";
|
InfoL << "play " << strUrlTmp << " success";
|
||||||
} else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) {
|
} else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) {
|
||||||
@ -151,6 +150,10 @@ void PlayerProxy::play(const string &strUrlTmp) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
NOTICE_EMIT(BroadcastPlayerProxyFailedArgs, Broadcast::kBroadcastPlayerProxyFailed, *strongSelf, err);
|
NOTICE_EMIT(BroadcastPlayerProxyFailedArgs, Broadcast::kBroadcastPlayerProxyFailed, *strongSelf, err);
|
||||||
}
|
}
|
||||||
|
if (strongSelf->_on_play) {
|
||||||
|
strongSelf->_on_play(err);
|
||||||
|
strongSelf->_on_play = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// 注销直接拉流代理产生的流:#532 [AUTO-TRANSLATED:c6343a3b]
|
// 注销直接拉流代理产生的流:#532 [AUTO-TRANSLATED:c6343a3b]
|
||||||
// Unregister the stream generated by the direct stream proxy: #532
|
// Unregister the stream generated by the direct stream proxy: #532
|
||||||
@ -291,7 +294,7 @@ float PlayerProxy::getLossRate(MediaSource &sender, TrackType type) {
|
|||||||
return getPacketLossRate(type);
|
return getPacketLossRate(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
toolkit::EventPoller::Ptr PlayerProxy::getOwnerPoller(MediaSource &sender) {
|
toolkit::EventPoller::Ptr PlayerProxy::getOwnerPoller(MediaSource &sender) {
|
||||||
return getPoller();
|
return getPoller();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,10 +317,10 @@ void PlayerProxy::onPlaySuccess() {
|
|||||||
// rtmp拉流代理 [AUTO-TRANSLATED:21173335]
|
// rtmp拉流代理 [AUTO-TRANSLATED:21173335]
|
||||||
// Rtmp stream proxy
|
// Rtmp stream proxy
|
||||||
if (reset_when_replay || !_muxer) {
|
if (reset_when_replay || !_muxer) {
|
||||||
auto old = _option.enable_rtmp;
|
auto old = _option.enable_rtmp;
|
||||||
_option.enable_rtmp = false;
|
_option.enable_rtmp = false;
|
||||||
_muxer = std::make_shared<MultiMediaSourceMuxer>(_tuple, getDuration(), _option);
|
_muxer = std::make_shared<MultiMediaSourceMuxer>(_tuple, getDuration(), _option);
|
||||||
_option.enable_rtmp = old;
|
_option.enable_rtmp = old;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 其他拉流代理 [AUTO-TRANSLATED:e5f2e45d]
|
// 其他拉流代理 [AUTO-TRANSLATED:e5f2e45d]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user