Skip to content

Commit 36d0d35

Browse files
authored
Merge pull request #186 from WizardCM/api-enhancements
JS API Enhancements
2 parents 6179b62 + 92864c0 commit 36d0d35

File tree

5 files changed

+193
-68
lines changed

5 files changed

+193
-68
lines changed

README.md

+122-45
Original file line numberDiff line numberDiff line change
@@ -4,103 +4,171 @@ CEF Based obs-studio browser plugin
44

55
## JS Bindings
66

7-
obs-browser provides a global object that allows access to some obs specific functionality from javascript.
7+
obs-browser provides a global object that allows access to some OBS-specific functionality from JavaScript.
88

9-
### Get OBS Studio Browser Plugin Version
10-
```
11-
window.obsstudio.pluginVersion
12-
// => 1.24.0
13-
```
9+
### Get Browser Plugin Version
1410

15-
### Register for visibility callbacks
16-
```
11+
```js
1712
/**
18-
* onVisibilityChange gets callbacks when the visibility of the browser source changes in OBS
19-
*
20-
* @param {bool} visibility - True -> visible, False -> hidden
13+
* @returns {number} OBS Browser plugin version
2114
*/
22-
window.obsstudio.onVisibilityChange = function(visibility) {
23-
24-
};
15+
window.obsstudio.pluginVersion
16+
// => 1.24.0
2517
```
2618

27-
### Register for active/inactive callbacks
28-
```
19+
### Register for event callbacks
20+
21+
```js
2922
/**
30-
* onActiveChange gets callbacks when the active/inactive state of the browser source changes in OBS
31-
*
32-
* @param {bool} True -> active, False -> inactive
23+
* @typedef {Object} OBSEvent
24+
* @property {object} detail - data from event
3325
*/
34-
window.obsstudio.onActiveChange = function(active) {
35-
36-
};
37-
```
3826

39-
### Register for scene change callbacks
40-
```
41-
window.addEventListener('obsSceneChanged', function(evt) {
42-
var t = document.createTextNode(evt.detail.name);
43-
document.body.appendChild(t);
44-
});
27+
window.addEventListener('obsSceneChanged', function(event) {
28+
var t = document.createTextNode(event.detail.name)
29+
document.body.appendChild(t)
30+
})
4531
```
46-
#### Other events that are available
32+
33+
#### Available events
34+
35+
Descriptions for these events can be [found here](https://obsproject.com/docs/reference-frontend-api.html?highlight=paused#c.obs_frontend_event).
36+
37+
* obsSceneChanged
38+
* obsSourceVisibleChanged
39+
* obsSourceActiveChanged
4740
* obsStreamingStarting
4841
* obsStreamingStarted
4942
* obsStreamingStopping
5043
* obsStreamingStopped
5144
* obsRecordingStarting
5245
* obsRecordingStarted
46+
* obsRecordingPaused
47+
* obsRecordingUnpaused
5348
* obsRecordingStopping
5449
* obsRecordingStopped
50+
* obsReplaybufferStarting
51+
* obsReplaybufferStarted
52+
* obsReplaybufferStopping
53+
* obsReplaybufferStopped
5554

5655
### Get the current scene
57-
```
58-
window.obsstudio.getCurrentScene(function(data) { console.log(data); });
5956

60-
data is a Javascript object containing the following properties:
61-
* width
62-
* height
63-
* name
57+
```js
58+
/**
59+
* @typedef {Object} Scene
60+
* @property {string} name - name of the scene
61+
* @property {number} width - width of the scene
62+
* @property {number} height - height of the scene
63+
*/
64+
65+
/**
66+
* @param {function} callback
67+
* @returns {Scene}
68+
*/
69+
window.obsstudio.getCurrentScene(function(scene) {
70+
console.log(scene)
71+
})
6472
```
6573

6674
### Get OBS output status
75+
76+
```js
77+
/**
78+
* @typedef {Object} Status
79+
* @property {boolean} recording - not affected by pause state
80+
* @property {boolean} recordingPaused
81+
* @property {boolean} streaming
82+
* @property {boolean} replaybuffer
83+
*/
84+
85+
/**
86+
* @param {function} callback
87+
* @returns {Status}
88+
*/
89+
window.obsstudio.getStatus(function (status) {
90+
console.log(status)
91+
})
92+
```
93+
94+
### Save OBS Replay Buffer
95+
96+
```js
97+
/**
98+
* Does not accept any parameters and does not return anything
99+
*/
100+
window.obsstudio.saveReplayBuffer()
67101
```
68-
window.obsstudio.getStatus(function data) { console.log(data); });
69102

70-
data is a Javascript object containing the following properties:
71-
* recording (true/false)
72-
* streaming (true/false)
73-
* replaybuffer (true/false)
103+
### Register for visibility callbacks
104+
105+
**This method is legacy. Register an event listener instead.**
106+
107+
```js
108+
/**
109+
* onVisibilityChange gets callbacks when the visibility of the browser source changes in OBS
110+
*
111+
* @deprecated
112+
* @see obsSourceVisibleChanged
113+
* @param {boolean} visibility - True -> visible, False -> hidden
114+
*/
115+
window.obsstudio.onVisibilityChange = function(visibility) {
116+
117+
};
118+
```
119+
120+
### Register for active/inactive callbacks
121+
122+
**This method is legacy. Register an event listener instead.**
123+
124+
```js
125+
/**
126+
* onActiveChange gets callbacks when the active/inactive state of the browser source changes in OBS
127+
*
128+
* @deprecated
129+
* @see obsSourceActiveChanged
130+
* @param {bool} True -> active, False -> inactive
131+
*/
132+
window.obsstudio.onActiveChange = function(active) {
133+
134+
};
74135
```
75136

76137
## Building on OSX
77138

78139
### Building CEF
140+
79141
#### Getting
142+
80143
* Download CEF Mac 64 from [http://opensource.spotify.com/cefbuilds/index.html](http://opensource.spotify.com/cefbuilds/index.html)
81-
* Use CEF branch 3112
144+
* Use CEF branch 3770
82145
* Extract and cd into the folder
83146

84147
#### Setting Up Project
85-
```
148+
149+
```shell
86150
mkdir build
87151
cmake -D CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY=libc++ -G Xcode ..
88152
open cef.xcodeproj/
89153
```
90154

91155
#### Building
156+
92157
Build in Xcode (⌘+B)
93158

94159
TODO: tell user to move stuff, or update FindCEF.cmake
95160

96161
### Building OBS and obs-browser
162+
97163
#### Installing Dependencies
98-
```
164+
165+
```shell
99166
brew install ffmpeg x264 qt5 cmake
100167
```
101168

102169
#### Setting Up Project
103-
```
170+
171+
```shell
104172
git clone --recursive https://github.com/jp9000/obs-studio.git
105173
cd ./obs-studio
106174
git clone [email protected]:kc5nra/obs-browser.git ./plugins/obs-browser
@@ -112,17 +180,21 @@ open obs-studio.xcodeproj/
112180
```
113181

114182
#### Building
183+
115184
Build in Xcode (⌘+B)
116185

117186
## Building on Windows
118187

119188
### Building CEF
189+
120190
#### Getting
191+
121192
* Download CEF Windows 64bit from [http://opensource.spotify.com/cefbuilds/index.html](http://opensource.spotify.com/cefbuilds/index.html)
122193
* Use CEF branch 3440 or newer (3579 if you want shared texture support)
123194
* Extract and cd into the folder
124195

125196
#### Setting Up the Project
197+
126198
* Run cmake-gui
127199
* In "where is the source code", enter in the repo directory (example: C:/Users/User/Desktop/cef_binary_3.2743.1445.gdad7c0a_windows64).
128200
* In "where to build the binaries", enter the repo directory path with the 'build' subdirectory (example: C:/Users/User/Desktop/cef_binary_3.2743.1445.gdad7c0a_windows64/build).
@@ -132,16 +204,21 @@ Visual Studio 12 2013 Win64, Visual Studio 14 2015 Win64 or Visual Studio 15 201
132204
* Open cef.sln from the 'build' subdirectory
133205

134206
#### Building
207+
135208
* Build at least libcef_dll_wrapper (as Release), the rest is optional and are just clients to test with
136209

137210
### Building OBS and obs-browser
211+
138212
#### Follow the OBS build instructions
213+
139214
[https://github.com/jp9000/obs-studio/wiki/Install-Instructions#windows](https://github.com/jp9000/obs-studio/wiki/Install-Instructions#windows)
140215

141216
#### Setting Up Project
217+
142218
* Enable BUILD_BROWSER and set the CEF_ROOT_DIR path in cmake-gui for obs-studio (example: C:/Users/User/Desktop/cef_binary_3.2743.1445.gdad7c0a_windows64)
143219
* * Press 'Generate' to generate Visual Studio project files in the 'build' subdirectory.
144220
* Open obs-studio.sln from the 'build' subdirectory
145221

146222
#### Building
223+
147224
Build in Visual Studio

browser-app.cpp

+9-19
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,21 @@ void BrowserApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
120120
obsStudioObj->SetValue("pluginVersion", pluginVersion,
121121
V8_PROPERTY_ATTRIBUTE_NONE);
122122

123-
CefRefPtr<CefV8Value> func =
123+
CefRefPtr<CefV8Value> getCurrentScene =
124124
CefV8Value::CreateFunction("getCurrentScene", this);
125-
obsStudioObj->SetValue("getCurrentScene", func,
125+
obsStudioObj->SetValue("getCurrentScene", getCurrentScene,
126126
V8_PROPERTY_ATTRIBUTE_NONE);
127127

128128
CefRefPtr<CefV8Value> getStatus =
129129
CefV8Value::CreateFunction("getStatus", this);
130130
obsStudioObj->SetValue("getStatus", getStatus,
131131
V8_PROPERTY_ATTRIBUTE_NONE);
132132

133+
CefRefPtr<CefV8Value> saveReplayBuffer =
134+
CefV8Value::CreateFunction("saveReplayBuffer", this);
135+
obsStudioObj->SetValue("saveReplayBuffer", saveReplayBuffer,
136+
V8_PROPERTY_ATTRIBUTE_NONE);
137+
133138
#if !ENABLE_WASHIDDEN
134139
int id = browser->GetIdentifier();
135140
if (browserVis.find(id) != browserVis.end()) {
@@ -352,29 +357,14 @@ bool BrowserApp::Execute(const CefString &name, CefRefPtr<CefV8Value>,
352357
const CefV8ValueList &arguments,
353358
CefRefPtr<CefV8Value> &, CefString &)
354359
{
355-
if (name == "getCurrentScene") {
356-
if (arguments.size() == 1 && arguments[0]->IsFunction()) {
357-
callbackId++;
358-
callbackMap[callbackId] = arguments[0];
359-
}
360-
361-
CefRefPtr<CefProcessMessage> msg =
362-
CefProcessMessage::Create("getCurrentScene");
363-
CefRefPtr<CefListValue> args = msg->GetArgumentList();
364-
args->SetInt(0, callbackId);
365-
366-
CefRefPtr<CefBrowser> browser =
367-
CefV8Context::GetCurrentContext()->GetBrowser();
368-
SendBrowserProcessMessage(browser, PID_BROWSER, msg);
369-
370-
} else if (name == "getStatus") {
360+
if (name == "getCurrentScene" || name == "getStatus" || name == "saveReplayBuffer") {
371361
if (arguments.size() == 1 && arguments[0]->IsFunction()) {
372362
callbackId++;
373363
callbackMap[callbackId] = arguments[0];
374364
}
375365

376366
CefRefPtr<CefProcessMessage> msg =
377-
CefProcessMessage::Create("getStatus");
367+
CefProcessMessage::Create(name);
378368
CefRefPtr<CefListValue> args = msg->GetArgumentList();
379369
args->SetInt(0, callbackId);
380370

browser-client.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,11 @@ bool BrowserClient::OnProcessMessageReceived(
126126
json = Json::object{
127127
{"recording", obs_frontend_recording_active()},
128128
{"streaming", obs_frontend_streaming_active()},
129+
{"recordingPaused", obs_frontend_recording_paused()},
129130
{"replaybuffer", obs_frontend_replay_buffer_active()}};
130131

132+
} else if (name == "saveReplayBuffer") {
133+
obs_frontend_replay_buffer_save();
131134
} else {
132135
return false;
133136
}

obs-browser-plugin.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ void RegisterBrowserSource()
409409

410410
/* ========================================================================= */
411411

412-
extern void DispatchJSEvent(std::string eventName, std::string jsonString);
412+
extern void DispatchJSEvent(std::string eventName, std::string jsonString,
413+
BrowserSource *browser = nullptr);
413414

414415
static void handle_obs_frontend_event(enum obs_frontend_event event, void *)
415416
{
@@ -432,12 +433,30 @@ static void handle_obs_frontend_event(enum obs_frontend_event event, void *)
432433
case OBS_FRONTEND_EVENT_RECORDING_STARTED:
433434
DispatchJSEvent("obsRecordingStarted", "");
434435
break;
436+
case OBS_FRONTEND_EVENT_RECORDING_PAUSED:
437+
DispatchJSEvent("obsRecordingPaused", "");
438+
break;
439+
case OBS_FRONTEND_EVENT_RECORDING_UNPAUSED:
440+
DispatchJSEvent("obsRecordingUnpaused", "");
441+
break;
435442
case OBS_FRONTEND_EVENT_RECORDING_STOPPING:
436443
DispatchJSEvent("obsRecordingStopping", "");
437444
break;
438445
case OBS_FRONTEND_EVENT_RECORDING_STOPPED:
439446
DispatchJSEvent("obsRecordingStopped", "");
440447
break;
448+
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTING:
449+
DispatchJSEvent("obsReplaybufferStarting", nullptr);
450+
break;
451+
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTED:
452+
DispatchJSEvent("obsReplaybufferStarted", nullptr);
453+
break;
454+
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPING:
455+
DispatchJSEvent("obsReplaybufferStopping", nullptr);
456+
break;
457+
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPED:
458+
DispatchJSEvent("obsReplaybufferStopped", nullptr);
459+
break;
441460
case OBS_FRONTEND_EVENT_SCENE_CHANGED: {
442461
OBSSource source = obs_frontend_get_current_scene();
443462
obs_source_release(source);

0 commit comments

Comments
 (0)