diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8eb7bc0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = tab +indent_size = 4 +end_of_line = crlf +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = true diff --git a/CMakeLists.txt b/CMakeLists.txt index 79465a7..03e0ffb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,15 +29,26 @@ if(OS_MACOS) -Clink-arg=-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}) endif() +set(CMAKE_PREFIX_PATH "${QTDIR}") +set(CMAKE_INCLUDE_CURRENT_DIR ON) +find_qt(COMPONENTS Core Widgets Gui) + add_library(char-rtc-obs MODULE) -target_sources(char-rtc-obs PRIVATE char-rtc.c whip-service.c whip-service.h whip-output.c whip-output.h - "${CHAR_RTC_GENERATED_DIR}/bindings.h") +target_sources(char-rtc-obs PRIVATE + char-rtc.c + whip-service.c whip-service.h + whip-output.c whip-output.h + whip-setup.cpp whip-setup.h + "${CHAR_RTC_GENERATED_DIR}/bindings.h" + ) set_source_files_properties("${CHAR_RTC_GENERATED_DIR}/bindings.h" PROPERTIES GENERATED TRUE) -target_link_libraries(char-rtc-obs OBS::libobs char-rtc-backend) -target_include_directories(char-rtc-obs PRIVATE ${CHAR_RTC_GENERATED_DIR}) +target_link_libraries(char-rtc-obs char-rtc-backend + OBS::libobs OBS::frontend-api + Qt::Core Qt::Widgets Qt::Gui) +target_include_directories(char-rtc-obs PRIVATE ${CHAR_RTC_GENERATED_DIR} ${Qt5Core_INCLUDES} ${Qt5Widgets_INCLUDES} ${Qt5Gui_INCLUDES}) if(OS_WINDOWS) set(MODULE_DESCRIPTION "live.umm.gay module") diff --git a/char-rtc.c b/char-rtc.c index 2f68b88..ce01d81 100644 --- a/char-rtc.c +++ b/char-rtc.c @@ -1,7 +1,9 @@ #include +#include #include "whip-output.h" #include "whip-service.h" +#include "whip-setup.h" OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("char-rtc-obs", "en-US") @@ -14,8 +16,9 @@ MODULE_EXPORT bool obs_module_load() { char_rtc_install_logger(); - register_whip_output(); - register_whip_service(); + whip_register_output(); + whip_register_service(); + whip_register_setup_item(); return true; } diff --git a/whip-output.c b/whip-output.c index 63cbf98..c11bba6 100644 --- a/whip-output.c +++ b/whip-output.c @@ -226,7 +226,7 @@ struct obs_output_info whip_output_info = { .get_dropped_frames = whip_output_dropped_frames, }; -void register_whip_output() +void whip_register_output() { obs_register_output(&whip_output_info); } diff --git a/whip-output.h b/whip-output.h index 0d7d2f2..7c90986 100644 --- a/whip-output.h +++ b/whip-output.h @@ -14,4 +14,4 @@ struct whip_output { RTCOutput *whip_output; }; -void register_whip_output(void); +void whip_register_output(void); diff --git a/whip-service.c b/whip-service.c index 2f24db6..57fb482 100644 --- a/whip-service.c +++ b/whip-service.c @@ -2,6 +2,7 @@ struct whip_service_state { char *server; + char *bearer_token; }; static const char *whip_service_name(void *type_data) @@ -18,12 +19,15 @@ static void whip_service_update(void *data, obs_data_t *settings) bfree(service->server); service->server = bstrdup(obs_data_get_string(settings, "server")); + service->bearer_token = + bstrdup(obs_data_get_string(settings, "bearer_token")); } static void whip_service_destroy(void *data) { struct whip_service_state *service = data; + bfree(service->bearer_token); bfree(service->server); bfree(service); } @@ -82,6 +86,13 @@ static void whip_service_apply_encoder_settings(void *data, } } +static const char *whip_service_get_key(void *data) +{ + struct whip_service_state *service = data; + + return service->bearer_token; +} + struct obs_service_info whip_service_info = { .id = "whip_custom", .get_name = whip_service_name, @@ -92,9 +103,10 @@ struct obs_service_info whip_service_info = { .get_url = whip_service_url, .get_output_type = whip_service_get_output_type, .apply_encoder_settings = whip_service_apply_encoder_settings, + .get_key = whip_service_get_key, }; -void register_whip_service() +void whip_register_service() { obs_register_service(&whip_service_info); } diff --git a/whip-service.h b/whip-service.h index 379d884..833f4cf 100644 --- a/whip-service.h +++ b/whip-service.h @@ -2,4 +2,4 @@ #include "obs-module.h" -void register_whip_service(void); +void whip_register_service(void); diff --git a/whip-setup.cpp b/whip-setup.cpp new file mode 100644 index 0000000..0eaa60f --- /dev/null +++ b/whip-setup.cpp @@ -0,0 +1,69 @@ +#include +#include + +#include +#include +#include + +static void whip_setup_service(const char *key) +{ + obs_service_t *current_service = obs_frontend_get_streaming_service(); + obs_data_t *data = obs_data_create(); + + obs_data_set_string(data, "server", + "https://live.umm.gay/api/wish-server/whip"); + obs_data_set_string(data, "bearer_token", key); + + obs_data_t *hotkey_data = obs_hotkeys_save_service(current_service); + + obs_service_t *new_service = obs_service_create( + "whip_custom", "live.umm.gay", data, hotkey_data); + + obs_frontend_set_streaming_service(new_service); +} + +extern "C" void whip_register_setup_item() +{ + QAction *menuAction = (QAction *)obs_frontend_add_tools_menu_qaction( + "Use live.umm.gay"); + QObject::connect(menuAction, &QAction::triggered, [] { + QInputDialog *dlg = new QInputDialog(nullptr); + dlg->setWindowFlag(Qt::WindowStaysOnTopHint, true); + dlg->setWindowFlag(Qt::WindowContextHelpButtonHint, false); + + dlg->setWindowTitle("live.umm.gay: Enter Stream Key"); + dlg->setTextEchoMode(QLineEdit::Password); + dlg->setLabelText("Enter your stream key for live.umm.gay:"); + if (QLineEdit *edit = dlg->findChild()) { + edit->setPlaceholderText("channel:stream-key"); + edit->setStyleSheet("QLineEdit { color: #7f7f7f; }"); + + QObject::connect(edit, &QLineEdit::textChanged, [edit] { + if (edit->text().isEmpty()) { + edit->setStyleSheet( + "QLineEdit { color: #7f7f7f; }"); + } else { + edit->setStyleSheet(nullptr); + } + }); + } + + QObject::connect(dlg, &QInputDialog::finished, [dlg](int result) { + if (result == QDialog::Accepted) { + whip_setup_service( + dlg->textValue().toUtf8().constData()); + + QMessageBox mb( + QMessageBox::Information, + "live.umm.gay: Success", + "Your stream details have been successfully applied.", + QMessageBox::NoButton, + (QWidget *) + obs_frontend_get_main_window()); + mb.addButton("OK", QMessageBox::AcceptRole); + mb.exec(); + } + }); + dlg->open(); + }); +} diff --git a/whip-setup.h b/whip-setup.h new file mode 100644 index 0000000..d5c8f85 --- /dev/null +++ b/whip-setup.h @@ -0,0 +1,9 @@ +#ifdef __cplusplus +extern "C" { +#endif + +void whip_register_setup_item(); + +#ifdef __cplusplus +} +#endif