diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a68423..962c2ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,11 +16,25 @@ add_library(obs-moq MODULE) if(${BUILD_PLUGIN}) find_package(libobs REQUIRED) # FFmpeg dependency - include(FindPkgConfig) - pkg_check_modules(FFMPEG REQUIRED libavcodec libavutil libswscale libswresample) - target_include_directories(obs-moq PRIVATE ${FFMPEG_INCLUDE_DIRS}) - target_link_directories(obs-moq PRIVATE ${FFMPEG_LIBRARY_DIRS}) - target_link_libraries(obs-moq PRIVATE ${FFMPEG_LIBRARIES}) + if(WIN32) + find_path(FFMPEG_INCLUDE_DIR + NAMES libavcodec/avcodec.h + PATH_SUFFIXES include + REQUIRED) + find_library(AVCODEC_LIBRARY NAMES avcodec PATH_SUFFIXES lib REQUIRED) + find_library(AVUTIL_LIBRARY NAMES avutil PATH_SUFFIXES lib REQUIRED) + find_library(SWSCALE_LIBRARY NAMES swscale PATH_SUFFIXES lib REQUIRED) + find_library(SWRESAMPLE_LIBRARY NAMES swresample PATH_SUFFIXES lib REQUIRED) + + target_include_directories(obs-moq PRIVATE ${FFMPEG_INCLUDE_DIR}) + target_link_libraries(obs-moq PRIVATE ${AVCODEC_LIBRARY} ${AVUTIL_LIBRARY} ${SWSCALE_LIBRARY} ${SWRESAMPLE_LIBRARY}) + else() + include(FindPkgConfig) + pkg_check_modules(FFMPEG REQUIRED libavcodec libavutil libswscale libswresample) + target_include_directories(obs-moq PRIVATE ${FFMPEG_INCLUDE_DIRS}) + target_link_directories(obs-moq PRIVATE ${FFMPEG_LIBRARY_DIRS}) + target_link_libraries(obs-moq PRIVATE ${FFMPEG_LIBRARIES}) + endif() else() find_package(FFmpeg REQUIRED avcodec avutil swscale swresample) target_link_libraries(obs-moq PRIVATE FFmpeg::avcodec FFmpeg::avutil FFmpeg::swscale FFmpeg::swresample) diff --git a/src/moq-output.cpp b/src/moq-output.cpp index e08af33..ee42e7f 100644 --- a/src/moq-output.cpp +++ b/src/moq-output.cpp @@ -15,10 +15,29 @@ MoQOutput::MoQOutput(obs_data_t *, obs_output_t *output) connect_time_ms(0), origin(moq_origin_create()), session(0), - broadcast(moq_publish_create()) + broadcast(moq_publish_create()), + broadcast_published(false) { } +bool MoQOutput::PublishBroadcast() +{ + if (broadcast_published) { + return true; + } + + LOG_INFO("Publishing broadcast: %s", 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; + } + + broadcast_published = true; + return true; +} + MoQOutput::~MoQOutput() { moq_publish_close(broadcast); @@ -80,6 +99,11 @@ bool MoQOutput::Start() auto self = static_cast(user_data); if (error_code == 0) { + if (!self->PublishBroadcast()) { + obs_output_signal_stop(self->output, OBS_OUTPUT_ERROR); + return; + } + auto elapsed = std::chrono::steady_clock::now() - self->connect_start; self->connect_time_ms = static_cast(std::chrono::duration_cast(elapsed).count()); LOG_INFO("MoQ session established (%d ms): %s", self->connect_time_ms, @@ -97,16 +121,6 @@ bool MoQOutput::Start() return false; } - LOG_INFO("Publishing broadcast: %s", path.c_str()); - - // Publish the broadcast to the origin we created. - // TODO: There is currently no unpublish function. - 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; - } - obs_output_begin_data_capture(output, 0); return true; diff --git a/src/moq-output.h b/src/moq-output.h index a46e6a5..0fc3c11 100644 --- a/src/moq-output.h +++ b/src/moq-output.h @@ -27,6 +27,7 @@ class MoQOutput } private: + bool PublishBroadcast(); void VideoInit(obs_encoder_t *encoder); void VideoData(struct encoder_packet *packet); void AudioInit(obs_encoder_t *encoder); @@ -44,6 +45,7 @@ class MoQOutput int origin; int session; int broadcast; + bool broadcast_published; std::map video_tracks; std::map audio_tracks; };