新增on_stream_not_found Python事件

This commit is contained in:
xia-chu 2026-02-08 21:57:56 +08:00
parent 33c61613dc
commit 26e9ad32ba
4 changed files with 33 additions and 0 deletions

View File

@ -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")

View File

@ -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;

View File

@ -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<std::function<void()>>(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>();
}
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<bool>();
}
} // namespace mediakit
#endif

View File

@ -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;
};