From 60efc37518d245274ee811a2be4917cb577c2d19 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Mon, 15 Dec 2025 17:15:52 +1100 Subject: [PATCH 1/5] Add support for downloading the tarball. --- CMakeLists.txt | 15 ++++----------- CMakePresets.json | 16 +++++++++++++--- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f50200..2ecb04d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,26 +20,19 @@ option(MOQ_LOCAL "Path to moq repo for local development" "") if(MOQ_LOCAL) add_subdirectory(${MOQ_LOCAL}/rs/libmoq moq) + target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE moq) else() include(FetchContent) FetchContent_Declare( moq - URL - https://github.com/kixelated/moq/releases/download/v${MOQ_VERSION}/moq-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}.tar.gz + URL https://github.com/moq-dev/moq/releases/download/libmoq-v${MOQ_VERSION}/moq-${MOQ_VERSION}-${MOQ_TARGET}.${MOQ_ARCHIVE} ) FetchContent_MakeAvailable(moq) - add_library(moq SHARED IMPORTED GLOBAL) - set_target_properties( - moq - PROPERTIES - IMPORTED_LOCATION "${moq_SOURCE_DIR}/lib/libmoq.dylib" - INTERFACE_INCLUDE_DIRECTORIES "${moq_SOURCE_DIR}/include" - ) + find_package(moq REQUIRED PATHS ${moq_SOURCE_DIR} NO_DEFAULT_PATH) + target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE moq::moq) endif() -target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE moq) - if(ENABLE_FRONTEND_API) find_package(obs-frontend-api REQUIRED) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE OBS::obs-frontend-api) diff --git a/CMakePresets.json b/CMakePresets.json index 54378a8..739c2a7 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -12,7 +12,10 @@ "cacheVariables": { "ENABLE_FRONTEND_API": false, "ENABLE_QT": false, - "CMAKE_EXPORT_COMPILE_COMMANDS": true + "CMAKE_EXPORT_COMPILE_COMMANDS": true, + "MOQ_VERSION": "0.1.2", + "MOQ_LIB": "libmoq.a", + "MOQ_ARCHIVE": "tar.gz" } }, { @@ -37,7 +40,8 @@ "CMAKE_OSX_DEPLOYMENT_TARGET": "12.0", "CMAKE_OSX_ARCHITECTURES": "arm64", "CODESIGN_IDENTITY": "$penv{CODESIGN_IDENT}", - "CODESIGN_TEAM": "$penv{CODESIGN_TEAM}" + "CODESIGN_TEAM": "$penv{CODESIGN_TEAM}", + "MOQ_TARGET": "aarch64-apple-darwin" } }, { @@ -71,6 +75,11 @@ "warnings": { "dev": true, "deprecated": true + }, + "cacheVariables": { + "MOQ_TARGET": "x86_64-pc-windows-msvc", + "MOQ_LIB": "moq.lib", + "MOQ_ARCHIVE": "zip" } }, { @@ -104,7 +113,8 @@ }, "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo", - "CMAKE_INSTALL_LIBDIR": "lib/CMAKE_SYSTEM_PROCESSOR-linux-gnu" + "CMAKE_INSTALL_LIBDIR": "lib/CMAKE_SYSTEM_PROCESSOR-linux-gnu", + "MOQ_TARGET": "x86_64-unknown-linux-gnu" } }, { From d02c5177c76aaa84372f2bf135566c8e161ff336 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Mon, 15 Dec 2025 18:36:18 +1100 Subject: [PATCH 2/5] Remove unused. --- CMakePresets.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 739c2a7..3ed6321 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -14,7 +14,6 @@ "ENABLE_QT": false, "CMAKE_EXPORT_COMPILE_COMMANDS": true, "MOQ_VERSION": "0.1.2", - "MOQ_LIB": "libmoq.a", "MOQ_ARCHIVE": "tar.gz" } }, @@ -78,7 +77,6 @@ }, "cacheVariables": { "MOQ_TARGET": "x86_64-pc-windows-msvc", - "MOQ_LIB": "moq.lib", "MOQ_ARCHIVE": "zip" } }, From c0555d23a0f48acb52df33dc418fd5d5b2251cea Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Wed, 17 Dec 2025 13:10:35 +1100 Subject: [PATCH 3/5] libmoq-consume changes --- src/moq-output.cpp | 29 ++++++++++++++++------------- src/moq-output.h | 1 + src/moq-service.cpp | 4 ++-- src/obs-moq.cpp | 3 ++- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/moq-output.cpp b/src/moq-output.cpp index 0cee381..a53eb2f 100644 --- a/src/moq-output.cpp +++ b/src/moq-output.cpp @@ -13,16 +13,18 @@ MoQOutput::MoQOutput(obs_data_t *, obs_output_t *output) path(), total_bytes_sent(0), connect_time_ms(0), + origin(moq_origin_create()), + broadcast(moq_publish_create()), session(0), video(0), - audio(0), - broadcast(moq_broadcast_create()) + audio(0) { } MoQOutput::~MoQOutput() { - moq_broadcast_close(broadcast); + moq_publish_close(broadcast); + moq_origin_close(origin); Stop(); } @@ -82,7 +84,7 @@ bool MoQOutput::Start() // Start establishing a session with the MoQ server // NOTE: You could publish the same broadcasts to multiple sessions if you want (redundant ingest). - session = moq_session_connect(server_url.c_str(), session_connect_callback, this); + session = moq_session_connect(server_url.data(), server_url.size(), origin, NULL, session_connect_callback, this); if (session < 0) { LOG_ERROR("Failed to initialize MoQ server: %d", session); return false; @@ -90,10 +92,9 @@ bool MoQOutput::Start() LOG_INFO("Publishing broadcast: %s", path.c_str()); - // Publish the one broadcast to the session. - // NOTE: You could publish multiple broadcasts to the same session if you want (multi ingest). + // Publish the broadcast to the origin we created. // TODO: There is currently no unpublish function. - auto result = moq_broadcast_publish(broadcast, session, path.c_str()); + auto result = moq_origin_publish(origin, path.data(), path.size(), broadcast); if (result < 0) { LOG_ERROR("Failed to publish broadcast to session: %d", result); return false; @@ -112,11 +113,11 @@ void MoQOutput::Stop(bool signal) } if (video > 0) { - moq_track_close(video); + moq_publish_media_close(video); } if (audio > 0) { - moq_track_close(audio); + moq_publish_media_close(audio); } if (signal) { @@ -154,7 +155,7 @@ void MoQOutput::AudioData(struct encoder_packet *packet) auto pts = util_mul_div64(packet->pts, 1000000ULL * packet->timebase_num, packet->timebase_den); - auto result = moq_track_write(audio, packet->data, packet->size, pts); + auto result = moq_publish_media_frame(audio, packet->data, packet->size, pts); if (result < 0) { LOG_ERROR("Failed to write audio frame: %d", result); return; @@ -175,7 +176,7 @@ void MoQOutput::VideoData(struct encoder_packet *packet) auto pts = util_mul_div64(packet->pts, 1000000ULL * packet->timebase_num, packet->timebase_den); - auto result = moq_track_write(video, packet->data, packet->size, pts); + auto result = moq_publish_media_frame(video, packet->data, packet->size, pts); if (result < 0) { LOG_ERROR("Failed to write video frame: %d", result); return; @@ -215,7 +216,8 @@ void MoQOutput::VideoInit() } const char *codec = obs_encoder_get_codec(encoder); - video = moq_track_create(broadcast, codec, extra_data, extra_size); + + video = moq_publish_media_init(broadcast, codec, strlen(codec), extra_data, extra_size); if (video < 0) { LOG_ERROR("Failed to initialize video track: %d", video); return; @@ -253,7 +255,8 @@ void MoQOutput::AudioInit() } const char *codec = obs_encoder_get_codec(encoder); - audio = moq_track_create(broadcast, codec, extra_data, extra_size); + + audio = moq_publish_media_init(broadcast, codec, strlen(codec), extra_data, extra_size); if (audio < 0) { LOG_ERROR("Failed to initialize audio track: %d", audio); return; diff --git a/src/moq-output.h b/src/moq-output.h index caa4102..e48bc06 100644 --- a/src/moq-output.h +++ b/src/moq-output.h @@ -40,6 +40,7 @@ class MoQOutput int connect_time_ms; std::chrono::steady_clock::time_point connect_start; + int origin; int session; int broadcast; int video; diff --git a/src/moq-service.cpp b/src/moq-service.cpp index e5e8cad..9b42f2c 100644 --- a/src/moq-service.cpp +++ b/src/moq-service.cpp @@ -1,8 +1,8 @@ #include "moq-service.h" // TODO: Define supported codecs. -const char *audio_codecs[] = {"aac", "opus", nullptr}; -const char *video_codecs[] = {"h264", "hevc", "av1", nullptr}; +const char *audio_codecs[] = {"aac", nullptr}; +const char *video_codecs[] = {"h264", nullptr}; MoQService::MoQService(obs_data_t *settings, obs_service_t *) : server(), path() { diff --git a/src/obs-moq.cpp b/src/obs-moq.cpp index ddbcfb0..83372e8 100644 --- a/src/obs-moq.cpp +++ b/src/obs-moq.cpp @@ -35,7 +35,8 @@ MODULE_EXPORT const char *obs_module_description(void) bool obs_module_load(void) { // Use RUST_LOG env var for more verbose output - moq_log_level("info"); + // The second argument is the string length of the first argument. + moq_log_level("info", 4); register_moq_output(); register_moq_service(); From 59cae6a170ac52fa404026735ae798ad48839fb9 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Thu, 18 Dec 2025 13:13:18 +1100 Subject: [PATCH 4/5] One last rename. --- src/moq-output.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/moq-output.cpp b/src/moq-output.cpp index a53eb2f..b9c0547 100644 --- a/src/moq-output.cpp +++ b/src/moq-output.cpp @@ -217,7 +217,7 @@ void MoQOutput::VideoInit() const char *codec = obs_encoder_get_codec(encoder); - video = moq_publish_media_init(broadcast, codec, strlen(codec), extra_data, extra_size); + video = moq_publish_media_ordered(broadcast, codec, strlen(codec), extra_data, extra_size); if (video < 0) { LOG_ERROR("Failed to initialize video track: %d", video); return; @@ -256,7 +256,7 @@ void MoQOutput::AudioInit() const char *codec = obs_encoder_get_codec(encoder); - audio = moq_publish_media_init(broadcast, codec, strlen(codec), extra_data, extra_size); + audio = moq_publish_media_ordered(broadcast, codec, strlen(codec), extra_data, extra_size); if (audio < 0) { LOG_ERROR("Failed to initialize audio track: %d", audio); return; From 5ff91c0149df95a9972b8fcf39c1693358f263f7 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Thu, 18 Dec 2025 13:13:59 +1100 Subject: [PATCH 5/5] And bump the MoQ version. --- CMakePresets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakePresets.json b/CMakePresets.json index 3ed6321..6ccaf28 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -13,7 +13,7 @@ "ENABLE_FRONTEND_API": false, "ENABLE_QT": false, "CMAKE_EXPORT_COMPILE_COMMANDS": true, - "MOQ_VERSION": "0.1.2", + "MOQ_VERSION": "0.2.0", "MOQ_ARCHIVE": "tar.gz" } },