From 26e9ad32ba7cf59fb05da6dd1026d366d551da28 Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Sun, 8 Feb 2026 21:57:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Eon=5Fstream=5Fnot=5Ffound=20P?= =?UTF-8?q?ython=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/mk_plugin.py | 7 +++++++ server/WebHook.cpp | 6 ++++++ server/pyinvoker.cpp | 17 +++++++++++++++++ server/pyinvoker.h | 3 +++ 4 files changed, 33 insertions(+) diff --git a/python/mk_plugin.py b/python/mk_plugin.py index 9d43da58..f3f91237 100644 --- a/python/mk_plugin.py +++ b/python/mk_plugin.py @@ -107,5 +107,12 @@ def on_rtsp_auth(args: dict, realm: str, user_name: str, must_no_encrypt: bool, # 返回True代表此事件被python拦截 return True +def on_stream_not_found(args: dict, sender:dict, invoker) -> bool: + mk_logger.log_info(f"on_stream_not_found, args: {args}, sender: {sender}") + # 立即通知播放器流不存在并关闭 + mk_loader.close_player_invoker_do(invoker) + # 返回True代表此事件被python拦截 + return True + def on_reload_config(): mk_logger.log_info(f"on_reload_config") \ No newline at end of file diff --git a/server/WebHook.cpp b/server/WebHook.cpp index e8cb1c54..b5e495bd 100755 --- a/server/WebHook.cpp +++ b/server/WebHook.cpp @@ -581,6 +581,12 @@ void installWebHook() { return; } +#if defined(ENABLE_PYTHON) + if (PythonInvoker::Instance().on_stream_not_found(args, sender, closePlayer)) { + return; + } +#endif + GET_CONFIG(string, hook_stream_not_found, Hook::kOnStreamNotFound); if (!hook_enable || hook_stream_not_found.empty()) { return; diff --git a/server/pyinvoker.cpp b/server/pyinvoker.cpp index 3b198be5..2691b5b4 100644 --- a/server/pyinvoker.cpp +++ b/server/pyinvoker.cpp @@ -224,6 +224,13 @@ PYBIND11_EMBEDDED_MODULE(mk_loader, m) { invoker(encrypted, pwd_or_md5); }); + m.def("close_player_invoker_do", [](const py::capsule &cap) { + // 执行c++代码时释放gil锁 + py::gil_scoped_release release; + auto &invoker = to_native>(cap); + invoker(); + }); + 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); @@ -346,6 +353,7 @@ PythonInvoker::~PythonInvoker() { _on_player_proxy_failed = py::function(); _on_get_rtsp_realm = py::function(); _on_rtsp_auth = py::function(); + _on_stream_not_found = py::function(); _module = py::module(); } delete _rel; @@ -370,6 +378,7 @@ void PythonInvoker::load(const std::string &module_name) { GET_FUNC(_module, on_player_proxy_failed); GET_FUNC(_module, on_get_rtsp_realm); GET_FUNC(_module, on_rtsp_auth); + GET_FUNC(_module, on_stream_not_found); if (hasattr(_module, "on_start")) { py::object on_start = _module.attr("on_start"); @@ -438,6 +447,14 @@ bool PythonInvoker::on_rtsp_auth(BroadcastOnRtspAuthArgs) const { return _on_rtsp_auth(to_python(args), realm, user_name, must_no_encrypt, to_python(invoker), to_python(sender)).cast(); } +bool PythonInvoker::on_stream_not_found(BroadcastNotFoundStreamArgs) const { + py::gil_scoped_acquire gil; // 确保在 Python 调用期间持有 GIL + if (!_on_stream_not_found) { + return false; + } + return _on_stream_not_found(to_python(args), to_python(sender), to_python(closePlayer)).cast(); +} + } // namespace mediakit #endif diff --git a/server/pyinvoker.h b/server/pyinvoker.h index cf603ba1..372f8afe 100644 --- a/server/pyinvoker.h +++ b/server/pyinvoker.h @@ -33,6 +33,7 @@ public: bool on_player_proxy_failed(BroadcastPlayerProxyFailedArgs) const; bool on_get_rtsp_realm(BroadcastOnGetRtspRealmArgs) const; bool on_rtsp_auth(BroadcastOnRtspAuthArgs) const; + bool on_stream_not_found(BroadcastNotFoundStreamArgs) const; private: PythonInvoker(); @@ -61,6 +62,8 @@ private: py::function _on_get_rtsp_realm; // rtsp播放或推流鉴权回调 py::function _on_rtsp_auth; + // 播放一个不存在的流时触发 + py::function _on_stream_not_found; };