From 90fcad41f2b17e5a89aba67498d58ac35480a05e Mon Sep 17 00:00:00 2001 From: Lidaofu <746101210@qq.com> Date: Sat, 9 Aug 2025 10:45:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20C=20Api=20=E5=A2=9E=E5=8A=A0=E9=83=A8?= =?UTF-8?q?=E5=88=86=E5=87=BD=E6=95=B0=20(#4382)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: C Api 增加mk_recorder_start_task(录制任务)、mk_rtp_server_create3(rtp多路复用)、mk_rtp_server_update_ssrc(更新ssrc)、mk_rtp_get_info(获取rtp信息)、mk_rtp_pause_check(暂停RTP超时检查)、mk_rtp_resume_check(恢复RTP超时检查)、mk_media_source_set_speed(回放流速度配置)等函数 --------- Co-authored-by: lidaofu --- api/include/mk_events_objects.h | 2 ++ api/include/mk_recorder.h | 15 ++++++++++ api/include/mk_rtp_server.h | 49 ++++++++++++++++++++++++++++++++ api/source/mk_events_objects.cpp | 8 ++++++ api/source/mk_media.cpp | 1 + api/source/mk_recorder.cpp | 21 ++++++++++++++ api/source/mk_rtp_server.cpp | 42 +++++++++++++++++++++++++++ 7 files changed, 138 insertions(+) diff --git a/api/include/mk_events_objects.h b/api/include/mk_events_objects.h index d4f2acfd..7179c728 100644 --- a/api/include/mk_events_objects.h +++ b/api/include/mk_events_objects.h @@ -193,6 +193,8 @@ API_EXPORT uint64_t API_CALL mk_media_source_get_alive_second(const mk_media_sou API_EXPORT int API_CALL mk_media_source_close(const mk_media_source ctx,int force); //MediaSource::seekTo() API_EXPORT int API_CALL mk_media_source_seek_to(const mk_media_source ctx,uint32_t stamp); +// MediaSource::setSpeed() +API_EXPORT void API_CALL mk_media_source_set_speed(const mk_media_source ctx, float speed); /** * rtp推流成功与否的回调(第一次成功后,后面将一直重试) diff --git a/api/include/mk_recorder.h b/api/include/mk_recorder.h index e70213e8..9228c923 100644 --- a/api/include/mk_recorder.h +++ b/api/include/mk_recorder.h @@ -125,6 +125,21 @@ API_EXPORT int API_CALL mk_recorder_start(int type, const char *vhost, const cha */ API_EXPORT int API_CALL mk_recorder_stop(int type, const char *vhost, const char *app, const char *stream); + + +/** + * 开始事件视频录制 + * @param vhost 虚拟主机 + * @param app 应用名 + * @param stream 流id + * @param path 录像文件保存相对路径,包括名称 + * @param back_ms 回溯录制时长 + * @param forward_ms 后续录制时长 + * @return 1:成功,0:失败 + * */ +API_EXPORT int API_CALL mk_recorder_start_task(const char *vhost, const char *app, const char *stream, const char *path, uint32_t back_ms, uint32_t forward_ms); + + /** * 加载mp4列表 * @param vhost 虚拟主机 diff --git a/api/include/mk_rtp_server.h b/api/include/mk_rtp_server.h index 1b837bec..b85e9831 100644 --- a/api/include/mk_rtp_server.h +++ b/api/include/mk_rtp_server.h @@ -21,6 +21,7 @@ typedef struct mk_rtp_server_t *mk_rtp_server; * @param port 监听端口,0则为随机 * @param tcp_mode tcp模式(0: 不监听端口 1: 监听端口 2: 主动连接到服务端) * @param stream_id 该端口绑定的流id + * @param multiple 多路复用RTP服务器 1: 开启 0: 不开启 * @return * Create GB28181 RTP server * @param port Listening port, 0 for random @@ -32,6 +33,7 @@ typedef struct mk_rtp_server_t *mk_rtp_server; */ API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create(uint16_t port, int tcp_mode, const char *stream_id); API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create2(uint16_t port, int tcp_mode, const char *vhost, const char *app, const char *stream_id); +API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create3(uint16_t port, int tcp_mode, const char *vhost, const char *app, const char *stream_id, int multiplex); /** * TCP 主动模式时连接到服务器是否成功的回调 @@ -110,6 +112,53 @@ typedef void(API_CALL *on_mk_rtp_server_detach)(void *user_data); API_EXPORT void API_CALL mk_rtp_server_set_on_detach(mk_rtp_server ctx, on_mk_rtp_server_detach cb, void *user_data); API_EXPORT void API_CALL mk_rtp_server_set_on_detach2(mk_rtp_server ctx, on_mk_rtp_server_detach cb, void *user_data, on_user_data_free user_data_free); +/** + * 更新RTP服务器过滤SSRC + * @param ctx 服务器对象 + * @param ssrc 十进制ssrc + * + */ +API_EXPORT void API_CALL mk_rtp_server_update_ssrc(mk_rtp_server ctx, uint32_t ssrc); + + +/** + * rtp信息获取回调 + * @param exist 存在rtp信息 0: 不存在 1: 存在 + * @param peer_ip 连接ip + * @param peer_port 连接端口 + * @param local_ip 本地ip + * @param local_port 本地端口 + * @param identifier 身份信息 + * + */ +typedef void(API_CALL *on_mk_rtp_get_info)(int exist, const char *peer_ip, uint16_t peer_port, const char *local_ip, uint16_t local_port, const char *identifier); + +/** + * 获取rtp推流信息 + * @param app 应用名 + * @param stream 流id + * @param cb rtp信息获取回调 + * + */ +API_EXPORT void API_CALL mk_rtp_get_info(const char *app, const char *stream, on_mk_rtp_get_info cb); + + +/** + * 暂停RTP超时检查 + * @param app 应用名 + * @param stream 流id + * + */ +API_EXPORT void API_CALL mk_rtp_pause_check(const char *app, const char *stream); + +/** + * 恢复RTP超时检查 + * @param app 应用名 + * @param stream 流id + * + */ +API_EXPORT void API_CALL mk_rtp_resume_check(const char *app, const char *stream); + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/api/source/mk_events_objects.cpp b/api/source/mk_events_objects.cpp index 908a912b..50d040bb 100644 --- a/api/source/mk_events_objects.cpp +++ b/api/source/mk_events_objects.cpp @@ -296,6 +296,13 @@ API_EXPORT int API_CALL mk_media_source_seek_to(const mk_media_source ctx,uint32 MediaSource *src = (MediaSource *)ctx; return src->seekTo(stamp); } + +API_EXPORT void API_CALL mk_media_source_set_speed(const mk_media_source ctx, float speed) { + assert(ctx); + MediaSource *src = (MediaSource *)ctx; + src->getOwnerPoller()->async([=]() mutable { src->speed(speed); }); +} + API_EXPORT void API_CALL mk_media_source_start_send_rtp(const mk_media_source ctx, const char *dst_url, uint16_t dst_port, const char *ssrc, int con_type, on_mk_media_source_send_rtp_result cb, void *user_data) { mk_media_source_start_send_rtp2(ctx, dst_url, dst_port, ssrc, con_type, cb, user_data, nullptr); } @@ -347,6 +354,7 @@ API_EXPORT void API_CALL mk_media_source_start_send_rtp4(const mk_media_source c args.close_delay_ms = (*ini_ptr)["close_delay_ms"].empty() ? 0 : (*ini_ptr)["close_delay_ms"].as(); args.rtcp_timeout_ms = (*ini_ptr)["rtcp_timeout_ms"].empty() ? 30000 : (*ini_ptr)["rtcp_timeout_ms"].as(); args.rtcp_send_interval_ms = (*ini_ptr)["rtcp_send_interval_ms"].empty() ? 5000 : (*ini_ptr)["rtcp_send_interval_ms"].as(); + args.enable_origin_recv_limit = (*ini_ptr)["enable_origin_recv_limit"].empty() ? false : (*ini_ptr)["enable_origin_recv_limit"].as(); std::shared_ptr ptr( user_data, user_data_free ? user_data_free : [](void *) {}); src->getOwnerPoller()->async([=]() mutable { diff --git a/api/source/mk_media.cpp b/api/source/mk_media.cpp index e2e07c46..788632b2 100755 --- a/api/source/mk_media.cpp +++ b/api/source/mk_media.cpp @@ -342,6 +342,7 @@ API_EXPORT void API_CALL mk_media_start_send_rtp4(mk_media ctx, const char *dst_ args.close_delay_ms = (*ini_ptr)["close_delay_ms"].empty() ? 30000 : (*ini_ptr)["close_delay_ms"].as(); args.rtcp_timeout_ms = (*ini_ptr)["rtcp_timeout_ms"].empty() ? 30000 : (*ini_ptr)["rtcp_timeout_ms"].as(); args.rtcp_send_interval_ms = (*ini_ptr)["rtcp_send_interval_ms"].empty() ? 5000 : (*ini_ptr)["rtcp_send_interval_ms"].as(); + args.enable_origin_recv_limit = (*ini_ptr)["enable_origin_recv_limit"].empty() ? false : (*ini_ptr)["enable_origin_recv_limit"].as(); // sender参数无用 [AUTO-TRANSLATED:21590ae5] // The sender parameter is useless auto ref = *obj; diff --git a/api/source/mk_recorder.cpp b/api/source/mk_recorder.cpp index d79f0654..7e5c9dfa 100644 --- a/api/source/mk_recorder.cpp +++ b/api/source/mk_recorder.cpp @@ -85,6 +85,27 @@ API_EXPORT int API_CALL mk_recorder_stop(int type, const char *vhost, const char return stopRecord((Recorder::type)type,vhost,app,stream); } +API_EXPORT int API_CALL mk_recorder_start_task(const char *vhost, const char *app, const char *stream, const char *path, uint32_t back_ms, uint32_t forward_ms) { + assert(vhost && app && stream); + auto src = MediaSource::find(vhost, app, stream); + if (!src) { + WarnL << "未找到相关的MediaSource,startRecordTask失败:" << vhost << "/" << app << "/" << stream; + return false; + } + bool ret; + src->getOwnerPoller()->async([=]() mutable { + std::string err; + try { + src->getMuxer()->startRecord(path, back_ms, forward_ms); + } catch (std::exception &ex) { + err = ex.what(); + WarnL << "MediaSource开启startRecordTask失败:" << vhost << "/" << app << "/" << stream << " what: " << err; + } + ret = err.empty(); + }); + return ret; +} + API_EXPORT void API_CALL mk_load_mp4_file(const char *vhost, const char *app, const char *stream, const char *file_path, int file_repeat) { mINI ini; mk_load_mp4_file2(vhost, app, stream, file_path, file_repeat, (mk_ini)&ini); diff --git a/api/source/mk_rtp_server.cpp b/api/source/mk_rtp_server.cpp index 316150e7..830f71b7 100644 --- a/api/source/mk_rtp_server.cpp +++ b/api/source/mk_rtp_server.cpp @@ -30,6 +30,13 @@ API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create2(uint16_t port, int tcp_m return (mk_rtp_server)server; } +API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create3(uint16_t port, int tcp_mode, const char *vhost, const char *app, const char *stream_id, int multiplex) { + RtpServer::Ptr *server = new RtpServer::Ptr(new RtpServer); + GET_CONFIG(std::string, local_ip, General::kListenIP) + (*server)->start(port, local_ip.c_str(), MediaTuple { vhost, app, stream_id, "" }, (RtpServer::TcpMode)tcp_mode,multiplex); + return (mk_rtp_server)server; +} + API_EXPORT void API_CALL mk_rtp_server_connect(mk_rtp_server ctx, const char *dst_url, uint16_t dst_port, on_mk_rtp_server_connected cb, void *user_data) { mk_rtp_server_connect2(ctx, dst_url, dst_port, cb, user_data, nullptr); } @@ -72,6 +79,41 @@ API_EXPORT void API_CALL mk_rtp_server_set_on_detach2(mk_rtp_server ctx, on_mk_r } } +API_EXPORT void API_CALL mk_rtp_server_update_ssrc(mk_rtp_server ctx, uint32_t ssrc) { + assert(ctx); + RtpServer::Ptr *server = (RtpServer::Ptr *)ctx; + (*server)->updateSSRC(ssrc); +} + + +API_EXPORT void API_CALL mk_rtp_get_info(const char *app, const char *stream, on_mk_rtp_get_info cb) { + assert(cb); + auto src = MediaSource::find(DEFAULT_VHOST, app, stream); + auto process = src ? src->getRtpProcess() : nullptr; + if (!process) { + cb(0, nullptr, 0, nullptr, 0, nullptr); + return; + } + SockInfo *info = process.get(); + cb(1, info->get_local_ip().c_str(), info->get_peer_port(), info->get_local_ip().c_str(), info->get_local_port(), info->getIdentifier().c_str()); +} + +API_EXPORT void API_CALL mk_rtp_pause_check(const char *app, const char *stream) { + auto src = MediaSource::find(DEFAULT_VHOST, app, stream); + auto process = src ? src->getRtpProcess() : nullptr; + if (process) { + process->setStopCheckRtp(true); + } +} + +API_EXPORT void API_CALL mk_rtp_resume_check(const char *app, const char *stream) { + auto src = MediaSource::find(DEFAULT_VHOST, app, stream); + auto process = src ? src->getRtpProcess() : nullptr; + if (process) { + process->setStopCheckRtp(false); + } +} + #else API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create(uint16_t port, int enable_tcp, const char *stream_id) {