From 899d9653a4d3840a43d49126756db7f86421b522 Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Fri, 20 Mar 2026 21:59:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=9B=B4=E6=96=B0=E6=B5=81?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E7=9A=84=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BF=AE=E6=94=B9=E5=B7=B2=E6=9C=89=E6=8B=89=E6=B5=81?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E7=9A=84URL=E5=92=8C=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/WebApi.cpp | 11 ++++++++ server/WebApi.h | 2 ++ server/pyinvoker.cpp | 14 ++++++++++ src/Player/PlayerProxy.cpp | 55 +++++++++++++++++++++----------------- src/Player/PlayerProxy.h | 4 ++- 5 files changed, 61 insertions(+), 25 deletions(-) diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 148f4500..d99186a2 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -592,6 +592,17 @@ void getStatisticJson(const function &cb) { #endif } +void updateStreamProxy(const mediakit::MediaTuple &tuple, const std::string &url, const toolkit::mINI &args) { + auto key = tuple.shortUrl(); + auto player = s_player_proxy.find(key); + if (!player) { + throw std::runtime_error("proxy player not found: " + key); + } + player->getPoller()->async([url, args, player]() { + player->update(url, args); + }); +} + void addStreamProxy(const MediaTuple &tuple, const string &url, int retry_count, bool force, const ProtocolOption &option, float timeout_sec, const mINI &args, const function &cb) { diff --git a/server/WebApi.h b/server/WebApi.h index 8883d918..6c405f72 100755 --- a/server/WebApi.h +++ b/server/WebApi.h @@ -252,6 +252,8 @@ void addStreamProxy(const mediakit::MediaTuple &tuple, const std::string &url, i const mediakit::ProtocolOption &option, float timeout_sec, const toolkit::mINI &args, const std::function &cb); +void updateStreamProxy(const mediakit::MediaTuple &tuple, const std::string &url, const toolkit::mINI &args); + template class ServiceController { public: diff --git a/server/pyinvoker.cpp b/server/pyinvoker.cpp index 111a3a03..ccd0ca7f 100644 --- a/server/pyinvoker.cpp +++ b/server/pyinvoker.cpp @@ -374,6 +374,20 @@ PYBIND11_EMBEDDED_MODULE(mk_loader, m) { py::arg("timeout_sec") = 0.0f, py::arg("opt") = py::dict() ); + // update_stream_proxy(vhost, app, stream, url, opt={}) + // 更新已有拉流代理的 url 和参数,流不存在时抛出异常 + m.def("update_stream_proxy", + [](const std::string &vhost, const std::string &app, const std::string &stream, + const std::string &url, const py::dict &opt) { + mINI args = to_native(opt); + MediaTuple tuple { vhost.empty() ? DEFAULT_VHOST : vhost, app, stream, "" }; + py::gil_scoped_release release; + updateStreamProxy(tuple, url, args); + }, + py::arg("vhost"), py::arg("app"), py::arg("stream"), py::arg("url"), + py::arg("opt") = py::dict() + ); + m.def("set_fastapi", [](const py::object &check_route, const py::object &submit_coro) { static void *fastapi_tag = nullptr; NoticeCenter::Instance().delListener(&fastapi_tag, Broadcast::kBroadcastHttpRequest); diff --git a/src/Player/PlayerProxy.cpp b/src/Player/PlayerProxy.cpp index e442cce5..1e1037bb 100644 --- a/src/Player/PlayerProxy.cpp +++ b/src/Player/PlayerProxy.cpp @@ -42,6 +42,16 @@ PlayerProxy::PlayerProxy( (*this)[Client::kWaitTrackReady] = false; } +void PlayerProxy::update(const std::string &url, const toolkit::mINI &args) { + CHECK(getPoller()->isCurrentThread()); + _pull_url = url; + this->mINI::clear(); + (*this)[Client::kWaitTrackReady] = false; + for (auto &pr : args) { + (*this)[pr.first] = pr.second; + } +} + void PlayerProxy::setPlayCallbackOnce(function cb) { _on_play = std::move(cb); } @@ -99,11 +109,12 @@ static int getMaxTrackSize(const std::string &url) { return 2; } -void PlayerProxy::play(const string &strUrlTmp) { - _option.max_track = getMaxTrackSize(strUrlTmp); +void PlayerProxy::play(const string &url) { + _pull_url = url; + _option.max_track = getMaxTrackSize(_pull_url); weak_ptr weakSelf = shared_from_this(); std::shared_ptr piFailedCnt(new int(0)); // 连续播放失败次数 - setOnPlayResult([weakSelf, strUrlTmp, piFailedCnt](const SockException &err) { + setOnPlayResult([weakSelf, piFailedCnt](const SockException &err) { auto strongSelf = weakSelf.lock(); if (!strongSelf) { return; @@ -131,20 +142,20 @@ void PlayerProxy::play(const string &strUrlTmp) { strongSelf->setTranslationInfo(); strongSelf->_on_connect(strongSelf->_transtalion_info); - InfoL << "play " << strUrlTmp << " success"; + InfoL << "play " << strongSelf->_pull_url << " success"; strongSelf->_status = std::make_shared("playing"); } else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { // 播放失败,延时重试播放 [AUTO-TRANSLATED:d7537c9c] // Play failed, retry playing with delay strongSelf->_on_disconnect(); - strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++); + strongSelf->rePlay((*piFailedCnt)++); } else { // 达到了最大重试次数,回调关闭 [AUTO-TRANSLATED:610f31f3] // Reached the maximum number of retries, callback to close strongSelf->_on_close(err); } }); - setOnShutdown([weakSelf, strUrlTmp, piFailedCnt](const SockException &err) { + setOnShutdown([weakSelf, piFailedCnt](const SockException &err) { auto strongSelf = weakSelf.lock(); if (!strongSelf) { return; @@ -188,7 +199,7 @@ void PlayerProxy::play(const string &strUrlTmp) { // Play interrupted abnormally, retry playing with delay if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { strongSelf->_repull_count++; - strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++); + strongSelf->rePlay((*piFailedCnt)++); } else { // 达到了最大重试次数,回调关闭 [AUTO-TRANSLATED:610f31f3] // Reached the maximum number of retries, callback to close @@ -197,14 +208,13 @@ void PlayerProxy::play(const string &strUrlTmp) { }); try { _status = std::make_shared("connecting"); - MediaPlayer::play(strUrlTmp); + MediaPlayer::play(_pull_url ); } catch (std::exception &ex) { _status = std::make_shared(std::string("play failed: ") + ex.what()); ErrorL << ex.what(); onPlayResult(SockException(Err_other, ex.what())); return; } - _pull_url = strUrlTmp; setDirectProxy(); } @@ -244,24 +254,21 @@ PlayerProxy::~PlayerProxy() { } } -void PlayerProxy::rePlay(const string &strUrl, int iFailedCnt) { +void PlayerProxy::rePlay(int iFailedCnt) { auto iDelay = MAX(_reconnect_delay_min * 1000, MIN(iFailedCnt * _reconnect_delay_step * 1000, _reconnect_delay_max * 1000)); weak_ptr weakSelf = shared_from_this(); - _timer = std::make_shared( - iDelay / 1000.0f, - [weakSelf, strUrl, iFailedCnt]() { - // 播放失败次数越多,则延时越长 [AUTO-TRANSLATED:5af39264] - // The more times the playback fails, the longer the delay - auto strongPlayer = weakSelf.lock(); - if (!strongPlayer) { - return false; - } - WarnL << "重试播放[" << iFailedCnt << "]:" << strUrl; - strongPlayer->MediaPlayer::play(strUrl); - strongPlayer->setDirectProxy(); + _timer = std::make_shared(iDelay / 1000.0f, [weakSelf, iFailedCnt]() { + // 播放失败次数越多,则延时越长 [AUTO-TRANSLATED:5af39264] + // The more times the playback fails, the longer the delay + auto strongPlayer = weakSelf.lock(); + if (!strongPlayer) { return false; - }, - getPoller()); + } + WarnL << "重试播放[" << iFailedCnt << "]:" << strongPlayer->_pull_url; + strongPlayer->MediaPlayer::play(strongPlayer->_pull_url); + strongPlayer->setDirectProxy(); + return false; + }, getPoller()); } bool PlayerProxy::close(MediaSource &sender) { diff --git a/src/Player/PlayerProxy.h b/src/Player/PlayerProxy.h index fe1f468c..853e6632 100644 --- a/src/Player/PlayerProxy.h +++ b/src/Player/PlayerProxy.h @@ -140,6 +140,8 @@ public: const MediaTuple& getMediaTuple() const { return _tuple; } const ProtocolOption& getOption() const { return _option; } + void update(const std::string &url, const toolkit::mINI &args); + private: // MediaSourceEvent override bool close(MediaSource &sender) override; @@ -150,7 +152,7 @@ private: float getLossRate(MediaSource &sender, TrackType type) override; toolkit::EventPoller::Ptr getOwnerPoller(MediaSource &sender) override; - void rePlay(const std::string &strUrl, int iFailedCnt); + void rePlay(int iFailedCnt); void onPlaySuccess(); void setDirectProxy(); void setTranslationInfo();