diff --git a/browser-app.cpp b/browser-app.cpp index 6bd6cc659..fe7a28a79 100644 --- a/browser-app.cpp +++ b/browser-app.cpp @@ -35,6 +35,8 @@ #endif #endif +#include "include/cef_command_line.h" + #if defined(USE_UI_LOOP) && defined(__APPLE__) #include "browser-mac.h" #endif @@ -139,6 +141,8 @@ void BrowserApp::OnBeforeCommandLineProcessing( "enable-media-stream", "1"); } } + command_line->AppendSwitchWithValue("remote-debugging-port", "9222"); + command_line->AppendSwitchWithValue("remote-allow-origins", "http://localhost:9222"); #ifdef __APPLE__ command_line->AppendSwitch("use-mock-keychain"); #endif @@ -151,7 +155,7 @@ std::vector exposedFunctions = { "startReplayBuffer", "stopReplayBuffer", "saveReplayBuffer", "startVirtualcam", "stopVirtualcam", "getScenes", "setCurrentScene", "getTransitions", "getCurrentTransition", - "setCurrentTransition"}; + "setCurrentTransition","messageFromApp", "messageToApp"}; void BrowserApp::OnContextCreated(CefRefPtr browser, CefRefPtr, @@ -411,8 +415,10 @@ bool BrowserApp::OnProcessMessageReceived(CefRefPtr browser, CefRefPtr dispatchEvent = globalObj->GetValue("dispatchEvent"); - dispatchEvent->ExecuteFunction(nullptr, arguments); + if (dispatchEvent && dispatchEvent->IsFunction()) { + dispatchEvent->ExecuteFunction(nullptr, arguments); + } context->Exit(); } diff --git a/browser-client.cpp b/browser-client.cpp index 5148fdc88..eb6eeaea9 100644 --- a/browser-client.cpp +++ b/browser-client.cpp @@ -115,7 +115,7 @@ bool BrowserClient::OnProcessMessageReceived( const std::string &name = message->GetName(); CefRefPtr input_args = message->GetArgumentList(); nlohmann::json json; - + blog(LOG_INFO, "[BrowserMessage] OnProcessMessageReceived: %s", name.c_str()); if (!valid()) { return false; } @@ -259,6 +259,32 @@ bool BrowserClient::OnProcessMessageReceived( } } #else + switch (webpage_control_level) { + case ControlLevel::All: + + [[fallthrough]]; + case ControlLevel::Advanced: + + [[fallthrough]]; + case ControlLevel::Basic: + + [[fallthrough]]; + case ControlLevel::ReadUser: + + [[fallthrough]]; + case ControlLevel::ReadObs: + + [[fallthrough]]; + case ControlLevel::None: + if (name == "getControlLevel") { + json = (int)webpage_control_level; + } else if (name == "messageToApp") { + const std::string message = input_args->GetString(1).ToString(); + blog(LOG_INFO, "[BrowserMessage] messageToApp called: arguments %zu, arg2 %s", input_args->GetSize(), message.c_str()); + std::lock_guard lock(bs->messagesToAppMutex); + bs->messagesToApp.push_back(message); + } + } UNUSED_PARAMETER(name); #endif diff --git a/obs-browser-plugin.cpp b/obs-browser-plugin.cpp index d9b4a9e73..78dfae21c 100644 --- a/obs-browser-plugin.cpp +++ b/obs-browser-plugin.cpp @@ -322,6 +322,28 @@ static obs_missing_files_t *browser_source_missingfiles(void *data) return files; } +static obs_data_array_t *browser_source_get_messages(void *data) +{ + BrowserSource *bs = static_cast(data); + obs_data_array_t *messages = nullptr; + + if (bs) { + std::lock_guard lock(bs->messagesToAppMutex); + if (!bs->messagesToApp.empty()) { + messages = obs_data_array_create(); + for (const auto &message : bs->messagesToApp) { + obs_data_t *msg_data = obs_data_create(); + obs_data_set_string(msg_data, "message", message.c_str()); + obs_data_array_push_back(messages, msg_data); + obs_data_release(msg_data); + } + bs->messagesToApp.clear(); + } + } + + return messages; +} + static CefRefPtr app; static void BrowserInit(obs_data_t *settings_obs) @@ -632,6 +654,12 @@ void RegisterBrowserSource() bs->Refresh(); bs->SetActive(true); }; + info.message = [](void *data, obs_data_t *settings) { + BrowserSource *bs = static_cast(data); + const char *message = obs_data_get_string(settings, "message"); + bs->MessageToBrowser(message); + }; + info.get_messages = browser_source_get_messages; info.deactivate = [](void *data) { static_cast(data)->SetActive(false); }; diff --git a/obs-browser-source.cpp b/obs-browser-source.cpp index 7f2058735..870e19426 100644 --- a/obs-browser-source.cpp +++ b/obs-browser-source.cpp @@ -154,7 +154,7 @@ void BrowserSource::Destroy() void BrowserSource::ExecuteOnBrowser(BrowserFunc func, bool async) { - if (!async) { + if (!async) { #ifdef ENABLE_BROWSER_QT_LOOP if (QThread::currentThread() == qApp->thread()) { if (!!cefBrowser) @@ -477,6 +477,18 @@ void BrowserSource::SetActive(bool active) DispatchJSEvent("obsSourceActiveChanged", json.dump(), this); } +void BrowserSource::MessageToBrowser(const char* message) +{ + if (destroying) + return; + + blog(LOG_INFO, "[BrowserMessage] MessageToBrowser: %s", message); + + nlohmann::json json; + json["message"] = message; + DispatchJSEvent("messageFromApp", json.dump(), this); +} + void BrowserSource::Refresh() { ExecuteOnBrowser( diff --git a/obs-browser-source.hpp b/obs-browser-source.hpp index 86f12d495..b385e267d 100644 --- a/obs-browser-source.hpp +++ b/obs-browser-source.hpp @@ -62,6 +62,8 @@ struct BrowserSource { bool create_browser = false; std::recursive_mutex lockBrowser; CefRefPtr cefBrowser; + std::vector messagesToApp; + std::mutex messagesToAppMutex; std::string url; std::string css; @@ -150,6 +152,7 @@ struct BrowserSource { void SendKeyClick(const struct obs_key_event *event, bool key_up); void SetShowing(bool showing); void SetActive(bool active); + void MessageToBrowser(const char* message); void Refresh(); #if defined(BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED) && \