Skip to content

Commit 599dab5

Browse files
committed
Add obs-websocket 5.0.0 integration
This adds integration into obs-websocket's new plugin API. The vendor name registered is `obs-browser`. Added vendor requests: - `emit_event` - Takes `event_name` and ?`event_data` parameters. Emits a custom event to all browser sources.
1 parent d78acd7 commit 599dab5

File tree

4 files changed

+175
-0
lines changed

4 files changed

+175
-0
lines changed

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ Descriptions for these events can be [found here](https://obsproject.com/docs/re
7575
* obsVirtualcamStarted
7676
* obsVirtualcamStopped
7777
* obsExit
78+
* [Any custom event emitted via obs-websocket vendor requests]
7879

7980

8081
### Control OBS
@@ -346,6 +347,14 @@ window.obsstudio.onActiveChange = function(active) {
346347
};
347348
```
348349

350+
### obs-websocket Vendor
351+
obs-browser includes integration with obs-websocket's Vendor requests. The vendor name to use is `obs-browser`, and available requests are:
352+
353+
- `emit_event` - Takes `event_name` and ?`event_data` parameters. Emits a custom event to all browser sources. To subscribe to events, see [here](#register-for-event-callbacks)
354+
- See [#340](https://github.com/obsproject/obs-browser/pull/340) for example usage.
355+
356+
There are no available vendor events at this time.
357+
349358
## Building
350359

351360
OBS Browser cannot be built standalone. It is built as part of OBS Studio.

deps/.clang-format

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Language: Cpp
2+
SortIncludes: false
3+
DisableFormat: true

deps/obs-websocket-api.h

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
obs-websocket
3+
Copyright (C) 2016-2021 Stephane Lepin <[email protected]>
4+
Copyright (C) 2020-2021 Kyle Manning <[email protected]>
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation; either version 2 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License along
17+
with this program. If not, see <https://www.gnu.org/licenses/>
18+
*/
19+
20+
#ifndef _OBS_WEBSOCKET_API_H
21+
#define _OBS_WEBSOCKET_API_H
22+
23+
#include <obs.h>
24+
25+
#define OBS_WEBSOCKET_API_VERSION 1
26+
27+
#ifdef __cplusplus
28+
extern "C" {
29+
#endif
30+
31+
typedef void* obs_websocket_vendor;
32+
typedef void (*obs_websocket_request_callback_function)(obs_data_t*, obs_data_t*, void*);
33+
34+
struct obs_websocket_request_callback {
35+
obs_websocket_request_callback_function callback;
36+
void *priv_data;
37+
};
38+
39+
inline proc_handler_t *ph;
40+
41+
static inline proc_handler_t *obs_websocket_get_ph(void)
42+
{
43+
proc_handler_t *global_ph = obs_get_proc_handler();
44+
assert(global_ph != NULL);
45+
46+
calldata_t cd = {0};
47+
if (!proc_handler_call(global_ph, "obs_websocket_api_get_ph", &cd))
48+
blog(LOG_DEBUG, "Unable to fetch obs-websocket proc handler object. obs-websocket not installed?");
49+
proc_handler_t *ret = (proc_handler_t*)calldata_ptr(&cd, "ph");
50+
calldata_free(&cd);
51+
52+
return ret;
53+
}
54+
55+
static inline bool obs_websocket_run_simple_proc(obs_websocket_vendor vendor, const char *proc_name, calldata_t *cd)
56+
{
57+
if (!ph || !vendor || !proc_name || !strlen(proc_name) || !cd)
58+
return false;
59+
60+
calldata_set_ptr(cd, "vendor", vendor);
61+
62+
proc_handler_call(ph, proc_name, cd);
63+
return calldata_bool(cd, "success");
64+
}
65+
66+
// ALWAYS CALL VIA `obs_module_post_load()` CALLBACK!
67+
// Registers a new "vendor" (Example: obs-ndi)
68+
static inline obs_websocket_vendor obs_websocket_register_vendor(const char *vendor_name)
69+
{
70+
ph = obs_websocket_get_ph();
71+
if (!ph)
72+
return NULL;
73+
74+
calldata_t cd = {0};
75+
76+
calldata_set_string(&cd, "name", vendor_name);
77+
78+
proc_handler_call(ph, "vendor_register", &cd);
79+
obs_websocket_vendor ret = calldata_ptr(&cd, "vendor");
80+
calldata_free(&cd);
81+
82+
return ret;
83+
}
84+
85+
// Registers a new request for a vendor
86+
static inline bool obs_websocket_vendor_register_request(obs_websocket_vendor vendor, const char *request_type, obs_websocket_request_callback_function request_callback, void* priv_data)
87+
{
88+
calldata_t cd = {0};
89+
90+
struct obs_websocket_request_callback cb = {};
91+
cb.callback = request_callback;
92+
cb.priv_data = priv_data;
93+
94+
calldata_set_string(&cd, "type", request_type);
95+
calldata_set_ptr(&cd, "callback", &cb);
96+
97+
bool success = obs_websocket_run_simple_proc(vendor, "vendor_request_register", &cd);
98+
calldata_free(&cd);
99+
100+
return success;
101+
}
102+
103+
// Unregisters an existing vendor request
104+
static inline bool obs_websocket_vendor_unregister_request(obs_websocket_vendor vendor, const char *request_type)
105+
{
106+
calldata_t cd = {0};
107+
108+
calldata_set_string(&cd, "type", request_type);
109+
110+
bool success = obs_websocket_run_simple_proc(vendor, "vendor_request_unregister", &cd);
111+
calldata_free(&cd);
112+
113+
return success;
114+
}
115+
116+
// Does not affect event_data refcount.
117+
// Emits an event under the vendor's name
118+
static inline bool obs_websocket_vendor_emit_event(obs_websocket_vendor vendor, const char *event_name, obs_data_t *event_data)
119+
{
120+
calldata_t cd = {0};
121+
122+
calldata_set_string(&cd, "type", event_name);
123+
calldata_set_ptr(&cd, "data", (void*)event_data);
124+
125+
bool success = obs_websocket_run_simple_proc(vendor, "vendor_event_emit", &cd);
126+
calldata_free(&cd);
127+
128+
return success;
129+
}
130+
131+
#ifdef __cplusplus
132+
}
133+
#endif
134+
135+
#endif

obs-browser-plugin.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "browser-config.h"
3636

3737
#include "json11/json11.hpp"
38+
#include "obs-websocket-api.h"
3839
#include "cef-headers.hpp"
3940

4041
#ifdef _WIN32
@@ -736,6 +737,33 @@ bool obs_module_load(void)
736737
return true;
737738
}
738739

740+
void obs_module_post_load(void)
741+
{
742+
auto vendor = obs_websocket_register_vendor("obs-browser");
743+
if (!vendor)
744+
return;
745+
746+
auto emit_event_request_cb = [](obs_data_t *request_data, obs_data_t *,
747+
void *) {
748+
const char *event_name =
749+
obs_data_get_string(request_data, "event_name");
750+
if (!event_name)
751+
return;
752+
753+
OBSDataAutoRelease event_data =
754+
obs_data_get_obj(request_data, "event_data");
755+
const char *event_data_string =
756+
event_data ? obs_data_get_json(event_data) : "{}";
757+
758+
DispatchJSEvent(event_name, event_data_string, nullptr);
759+
};
760+
761+
if (!obs_websocket_vendor_register_request(
762+
vendor, "emit_event", emit_event_request_cb, nullptr))
763+
blog(LOG_WARNING,
764+
"[obs-browser]: Failed to register obs-websocket request emit_event");
765+
}
766+
739767
void obs_module_unload(void)
740768
{
741769
#ifdef USE_QT_LOOP

0 commit comments

Comments
 (0)