From 24689fefd1b913678a3aa4145c94a1f9fb68f2d6 Mon Sep 17 00:00:00 2001 From: ljx0305 Date: Mon, 1 Apr 2024 17:31:04 +0800 Subject: [PATCH 1/5] Fix compilation error (#3432) --- server/WebApi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/WebApi.cpp b/server/WebApi.cpp index faac203d..a1ef1f65 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -1919,7 +1919,7 @@ void installWebApi() { api_regist("/index/api/stack/start", [](API_ARGS_JSON_ASYNC) { CHECK_SECRET(); - auto ret = VideoStackManager::Instance().startVideoStack(allArgs.args()); + auto ret = VideoStackManager::Instance().startVideoStack(allArgs.args); val["code"] = ret; val["msg"] = ret ? "failed" : "success"; invoker(200, headerOut, val.toStyledString()); From 2159e90f787ff07d27275ae74db4caa159c00dc5 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Fri, 5 Apr 2024 22:07:09 +0800 Subject: [PATCH 2/5] Add demo of reading H.264 file and pushing RTSP/RTMP stream --- api/tests/h264_pusher.c | 152 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 api/tests/h264_pusher.c diff --git a/api/tests/h264_pusher.c b/api/tests/h264_pusher.c new file mode 100644 index 00000000..bb87b03b --- /dev/null +++ b/api/tests/h264_pusher.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved. + * + * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit). + * + * Use of this source code is governed by MIT-like license that can be found in the + * LICENSE file in the root of the source tree. All contributing project authors + * may be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include +#ifdef _WIN32 +#include "windows.h" +#else +#include "unistd.h" +#endif +#include "mk_mediakit.h" + +static int exit_flag = 0; +static void s_on_exit(int sig) { + exit_flag = 1; +} + +static void on_h264_frame(void *user_data, mk_h264_splitter splitter, const char *data, int size) { +#ifdef _WIN32 + Sleep(40); +#else + usleep(40 * 1000); +#endif + static int dts = 0; + mk_frame frame = mk_frame_create(MKCodecH264, dts, dts, data, size, NULL, NULL); + dts += 40; + mk_media_input_frame((mk_media)user_data, frame); + mk_frame_unref(frame); +} + +typedef struct { + mk_pusher pusher; + char *url; +} Context; + +void release_context(void *user_data) { + Context *ptr = (Context *)user_data; + if (ptr->pusher) { + mk_pusher_release(ptr->pusher); + } + free(ptr->url); + free(ptr); + log_info("停止推流"); +} + +void on_push_result(void *user_data, int err_code, const char *err_msg) { + Context *ptr = (Context *)user_data; + if (err_code == 0) { + log_info("推流成功: %s", ptr->url); + } else { + log_warn("推流%s失败: %d(%s)", ptr->url, err_code, err_msg); + } +} + +void on_push_shutdown(void *user_data, int err_code, const char *err_msg) { + Context *ptr = (Context *)user_data; + log_warn("推流%s中断: %d(%s)", ptr->url, err_code, err_msg); +} + +void API_CALL on_regist(void *user_data, mk_media_source sender, int regist) { + Context *ptr = (Context *)user_data; + const char *schema = mk_media_source_get_schema(sender); + if (strcasestr(ptr->url, schema) != ptr->url) { + // 协议匹配失败 + return; + } + + if (!regist) { + // 注销 + if (ptr->pusher) { + mk_pusher_release(ptr->pusher); + ptr->pusher = NULL; + } + } else { + // 注册 + if (!ptr->pusher) { + ptr->pusher = mk_pusher_create_src(sender); + mk_pusher_set_on_result2(ptr->pusher, on_push_result, ptr, NULL); + mk_pusher_set_on_shutdown2(ptr->pusher, on_push_shutdown, ptr, NULL); + // 开始推流 + mk_pusher_publish(ptr->pusher, ptr->url); + } + } +} + +int main(int argc, char *argv[]) { + if (argc < 3) { + log_error("Usage: /path/to/h264/file rtsp_or_rtmp_url"); + return -1; + } + mk_config config = { .ini = NULL, + .ini_is_path = 1, + .log_level = 0, + .log_mask = LOG_CONSOLE, + .log_file_path = NULL, + .log_file_days = 0, + .ssl = NULL, + .ssl_is_path = 1, + .ssl_pwd = NULL, + .thread_num = 0 }; + mk_env_init(&config); + + FILE *fp = fopen(argv[1], "rb"); + if (!fp) { + log_error("打开文件失败!"); + return -1; + } + + mk_media media = mk_media_create("__defaultVhost__", "live", "test", 0, 0, 0); + // h264的codec + codec_args v_args = { 0 }; + mk_track v_track = mk_track_create(MKCodecH264, &v_args); + mk_media_init_track(media, v_track); + mk_media_init_complete(media); + mk_track_unref(v_track); + + Context *ctx = (Context *)malloc(sizeof(Context)); + memset(ctx, 0, sizeof(Context)); + ctx->url = strdup(argv[2]); + + mk_media_set_on_regist2(media, on_regist, ctx, release_context); + + // 创建h264分帧器 + mk_h264_splitter splitter = mk_h264_splitter_create(on_h264_frame, media, 0); + signal(SIGINT, s_on_exit); // 设置退出信号 + signal(SIGTERM, s_on_exit); // 设置退出信号 + + char buf[1024]; + while (!exit_flag) { + int size = fread(buf, 1, sizeof(buf) - 1, fp); + if (size > 0) { + mk_h264_splitter_input_data(splitter, buf, size); + } else { + // 文件读完了,重新开始 + fseek(fp, 0, SEEK_SET); + } + } + + log_info("文件读取完毕"); + mk_h264_splitter_release(splitter); + mk_media_release(media); + fclose(fp); + return 0; +} \ No newline at end of file From 071f008108b1408ca7d3521ace97ebf213b67951 Mon Sep 17 00:00:00 2001 From: lidaofu-hub <61726674+lidaofu-hub@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:09:40 +0800 Subject: [PATCH 3/5] add c api for MediaSource (#3433) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补充MediaSource C API 获取源地址 获取源类型 获取创建时间戳 --------- Co-authored-by: 李道甫 --- api/include/mk_common.h | 4 ++++ api/include/mk_events_objects.h | 10 ++++++++++ api/source/mk_events_objects.cpp | 24 ++++++++++++++++++++++++ api/source/mk_util.cpp | 4 ---- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/api/include/mk_common.h b/api/include/mk_common.h index 90b4c8a6..b6f480cd 100755 --- a/api/include/mk_common.h +++ b/api/include/mk_common.h @@ -24,6 +24,10 @@ # define API_CALL #endif +#ifndef _WIN32 +#define _strdup strdup +#endif + #if defined(_WIN32) && defined(_MSC_VER) # if !defined(GENERATE_EXPORT) # if defined(MediaKitApi_EXPORTS) diff --git a/api/include/mk_events_objects.h b/api/include/mk_events_objects.h index ddbaf87d..428f9dc6 100644 --- a/api/include/mk_events_objects.h +++ b/api/include/mk_events_objects.h @@ -103,6 +103,16 @@ API_EXPORT int API_CALL mk_media_source_get_track_count(const mk_media_source ct API_EXPORT mk_track API_CALL mk_media_source_get_track(const mk_media_source ctx, int index); // MediaSource::broadcastMessage API_EXPORT int API_CALL mk_media_source_broadcast_msg(const mk_media_source ctx, const char *msg, size_t len); +// MediaSource::getOriginUrl() +API_EXPORT const char* API_CALL mk_media_source_get_origin_url(const mk_media_source ctx); +// MediaSource::getOriginType() +API_EXPORT int API_CALL mk_media_source_get_origin_type(const mk_media_source ctx); +// MediaSource::getCreateStamp() +API_EXPORT uint64_t API_CALL mk_media_source_get_create_stamp(const mk_media_source ctx); +// MediaSource::isRecording() 0:hls,1:MP4 +API_EXPORT int API_CALL mk_media_source_is_recording(const mk_media_source ctx, int type); + + /** * 直播源在ZLMediaKit中被称作为MediaSource, diff --git a/api/source/mk_events_objects.cpp b/api/source/mk_events_objects.cpp index 7046f1ab..758e38a3 100644 --- a/api/source/mk_events_objects.cpp +++ b/api/source/mk_events_objects.cpp @@ -228,6 +228,30 @@ API_EXPORT int API_CALL mk_media_source_broadcast_msg(const mk_media_source ctx, return src->broadcastMessage(any); } +API_EXPORT const char* API_CALL mk_media_source_get_origin_url(const mk_media_source ctx) { + assert(ctx); + MediaSource *src = (MediaSource *)ctx; + return _strdup(src->getOriginUrl().c_str()); +} + +API_EXPORT int API_CALL mk_media_source_get_origin_type(const mk_media_source ctx) { + assert(ctx); + MediaSource *src = (MediaSource *)ctx; + return static_cast(src->getOriginType()); +} + +API_EXPORT uint64_t API_CALL mk_media_source_get_create_stamp(const mk_media_source ctx) { + assert(ctx); + MediaSource *src = (MediaSource *)ctx; + return src->getCreateStamp(); +} + +API_EXPORT int API_CALL mk_media_source_is_recording(const mk_media_source ctx,int type) { + assert(ctx); + MediaSource *src = (MediaSource *)ctx; + return src->isRecording((Recorder::type)type); +} + API_EXPORT int API_CALL mk_media_source_close(const mk_media_source ctx,int force){ assert(ctx); MediaSource *src = (MediaSource *)ctx; diff --git a/api/source/mk_util.cpp b/api/source/mk_util.cpp index 66d0d3b2..eda27162 100644 --- a/api/source/mk_util.cpp +++ b/api/source/mk_util.cpp @@ -21,10 +21,6 @@ using namespace std; using namespace toolkit; using namespace mediakit; -#ifndef _WIN32 -#define _strdup strdup -#endif - API_EXPORT void API_CALL mk_free(void *ptr) { free(ptr); } From edca6622081f08ff209371c2bd1adcbad13a85d1 Mon Sep 17 00:00:00 2001 From: Dw9 Date: Fri, 5 Apr 2024 22:11:50 +0800 Subject: [PATCH 4/5] fix webrtc echo error (#3442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 遵循着pr #3360 的修改方式解决webrtc echo模式失败的问题 --- webrtc/WebRtcEchoTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webrtc/WebRtcEchoTest.cpp b/webrtc/WebRtcEchoTest.cpp index 40be2613..cf7527a8 100644 --- a/webrtc/WebRtcEchoTest.cpp +++ b/webrtc/WebRtcEchoTest.cpp @@ -45,7 +45,7 @@ void WebRtcEchoTest::onCheckSdp(SdpType type, RtcSession &sdp) { for (auto &m : sdp.media) { for (auto &ssrc : m.rtp_rtx_ssrc) { if (!ssrc.msid.empty()) { - ssrc.msid = "zlmediakit msid"; + ssrc.msid = "zlmediakit-mslabel zlmediakit-label-" + m.mid; } } } From e6506a96d438622923d6522fe8fc54dfa2848b5f Mon Sep 17 00:00:00 2001 From: Dw9 Date: Mon, 8 Apr 2024 10:16:45 +0800 Subject: [PATCH 5/5] Update h264_pusher.c, fix build issue (#3444) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复win构建失败 strcasestr->strstr --- api/tests/h264_pusher.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/tests/h264_pusher.c b/api/tests/h264_pusher.c index bb87b03b..81a018b0 100644 --- a/api/tests/h264_pusher.c +++ b/api/tests/h264_pusher.c @@ -68,7 +68,7 @@ void on_push_shutdown(void *user_data, int err_code, const char *err_msg) { void API_CALL on_regist(void *user_data, mk_media_source sender, int regist) { Context *ptr = (Context *)user_data; const char *schema = mk_media_source_get_schema(sender); - if (strcasestr(ptr->url, schema) != ptr->url) { + if (strstr(ptr->url, schema) != ptr->url) { // 协议匹配失败 return; } @@ -149,4 +149,4 @@ int main(int argc, char *argv[]) { mk_media_release(media); fclose(fp); return 0; -} \ No newline at end of file +}