@overwolf/ow-electron-packages-types 0.0.12 → 0.1.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,4 +38,8 @@ Alternatively, you can add it directly to your tsconfig file, like so:
38
38
  }
39
39
  ```
40
40
 
41
- This way, it will always be available in all of your files, even without an explicit import.
41
+ This way, it will always be available in all of your files, even without an explicit import.
42
+
43
+ ## Getting started with ow-electron packages
44
+
45
+ [ow-electron packages](./docs/packages.md)
File without changes
File without changes
@@ -0,0 +1,23 @@
1
+
2
+ # Working with ow-electron packages
3
+
4
+ In order to add more/remove certain ow-electron "packages" from the project, simply edit the `overwolf.packages` array in the [package.json](/package.json) file, like so:
5
+
6
+ ```json
7
+ {
8
+ ...
9
+ "overwolf": {
10
+ "packages": [
11
+ "gep",
12
+ "overlay",
13
+ "recorder"
14
+ ]
15
+ },
16
+ ...
17
+ }
18
+ ```
19
+
20
+ ## Available packages detailed information
21
+ * [recorder](./recorder/recorder.md)
22
+ * [gep](./gep/game-events-provider.md)
23
+ * [overlay](/overlay/overlay.md)
@@ -0,0 +1,95 @@
1
+
2
+ # API Specification
3
+
4
+ ## Properties
5
+
6
+ - `options`: Contains global options for debugging [RecordingAppOptions](types.md#recordingappoptions)
7
+
8
+ ## Methods
9
+
10
+ > **Important:** It is recommended to wrap the methods in a try/catch block to handle any possible exceptions from the recording API.
11
+
12
+ - `isActive()`: Checks if recording or replays status is active.
13
+ ```javascript
14
+ const active = await recorderApi.isActive();
15
+ ```
16
+
17
+ - `queryInformation()`: Queries system information, including supported encoders and available audio/video devices and monitors.
18
+ ```javascript
19
+ const info = await recorderApi.queryInformation();
20
+ console.log(info.monitors);
21
+ ```
22
+
23
+ - `registerGames(filter)`: Registers game launches, triggering the `game-launched` event for detected processes. Accepts the [GamesFilter](types.md#gamesfilter) object.
24
+ ```javascript
25
+ const gamesFilter = {
26
+ gameIds: [1111, 2222], // use [] for all games
27
+ };
28
+ recorderApi.registerGames(gamesFilter);
29
+ ```
30
+
31
+ - `createSettingsBuilder(options)`: Creates the [Settings Builder](types.md#capturesettingsbuilder) object.
32
+ - Parameters: [CaptureSettingsOptions](types.md#capturesettingsoptions)
33
+
34
+ - `startRecording(options, setting, listener)`: Starts recording based on provided settings.
35
+ - Parameters:
36
+ - [RecordingOptions](types.md#recordingoptions)
37
+ - [CaptureSettings](types.md#capturesettings)
38
+ - StopCallback with [RecordStopEventArgs](types.md#recordstopeventargs)
39
+
40
+ - `stopRecording(listener)`: Stops the recording.
41
+ - Parameters: StopCallback with [RecordStopEventArgs](types.md#recordstopeventargs)
42
+
43
+ - `splitRecording(listener)`: Manually splits the video at the moment of calling the method, creating a subfolder in the current output directory for the split videos.
44
+ - Parameters: SplitCallback with [SplitRecordArgs](types.md#splitrecordargs)
45
+
46
+ ## Events
47
+
48
+ - `recording-started`: Fired when video recording starts. Returns StartCallback with [RecordEventArgs](types.md#recordeventargs).
49
+ ```javascript
50
+ recorderApi.on('recording-started', (RecordEventArgs) => {
51
+ console.log(RecordEventArgs.filePath);
52
+ });
53
+ ```
54
+
55
+ - `recording-stopped`: Fired when video recording stops. Returns StopCallback with [RecordStopEventArgs](types.md#recordstopeventargs).
56
+ ```javascript
57
+ recorderApi.on('recording-stopped', (RecordStopEventArgs) => {
58
+ console.log(RecordStopEventArgs.duration);
59
+ });
60
+ ```
61
+
62
+ - `recording-split`: Fired when a recording video is split (manual/size/time). Returns SplitCallback with [SplitRecordArgs](types.md#splitrecordargs).
63
+ ```javascript
64
+ recorderApi.on('recording-split', (SplitRecordArgs) => {
65
+ console.log(SplitRecordArgs.splitCount);
66
+ });
67
+ ```
68
+
69
+ - `replays-started`: Fired when replays recording starts. Returns StartCallback with [RecordEventArgs](types.md#recordeventargs).
70
+ ```javascript
71
+ recorderApi.on('replays-started', (RecordEventArgs) => {
72
+ console.log(RecordEventArgs.filePath);
73
+ });
74
+ ```
75
+
76
+ - `replays-stopped`: Fired when replays recording stops. Returns ReplayStopCallback with [RecordEventArgs](types.md#recordeventargs).
77
+ ```javascript
78
+ recorderApi.on('replays-stopped', (RecordEventArgs) => {
79
+ console.log(RecordEventArgs.filePath);
80
+ });
81
+ ```
82
+
83
+ - `replay-captured`: Fired when a replay video is captured. Returns ReplayCallback with [ReplayVideo](types.md#replayvideo).
84
+ ```javascript
85
+ recorderApi.on('replay-captured', (ReplayVideo) => {
86
+ console.log(ReplayVideo.duration);
87
+ });
88
+ ```
89
+
90
+ - `stats`: Fired at every `statsIntervalMS` (defined in RecordingAppOptions) interval. Returns [RecorderStats](types.md#recorderstats).
91
+ ```javascript
92
+ recorderApi.on('stats', (RecorderStats) => {
93
+ console.log(RecorderStats.cpuUsage);
94
+ });
95
+ ```
@@ -0,0 +1,397 @@
1
+ # ow-electron Recording
2
+
3
+ This document will describe an example of implementing the ow-electron recording package, how to interact with its interfaces, types, and configurations.
4
+
5
+ [API Specification](api-specification.md)
6
+ [Types Definition](types.md)
7
+
8
+ ## About the ow-electron recorder
9
+
10
+ The ow-electron recorder uses OBS behind the scenes and exposes OBS functions to the app. Using the recorder package, it is possible to record video and audio using the machine's devices, and running games.
11
+
12
+ ## Recorder package features
13
+
14
+ ### Capture Audio / Video
15
+
16
+ - Capture video from a specific display device or capture from a running game.
17
+ - Capture any audio input or output device, such as speakers, a microphone, or the game sound alone.
18
+ - Split capture into separate video files on-demand or using a timer.
19
+ - Multiple audio and video encoders supported.
20
+ - Multiple output formats supported.
21
+ - Control bitrate and encoding rate.
22
+ - Options to allocate specific audio tracks to specific audio devices.
23
+
24
+ ### Replays Capture
25
+
26
+ - Record a buffer of X seconds to memory without saving to disk.
27
+ - Allow for on-demand video capture to disk with a portion or all of the in-memory buffer.
28
+ - For example, when a highlight is detected while the replay is running, capture can be turned on to run for a timer, using X seconds already captured by the replay.
29
+
30
+ ### Game Listener
31
+
32
+ - Using the recording package, we can register for general events from supported games, such as game launch or exit.
33
+ - This can be used to trigger seamless recording as the game is loaded or alternately to start a replay and later trigger capture during appropriate moments.
34
+
35
+ ### Usage stats
36
+
37
+ While the recorder is actively recording, usage stats are provided such as:
38
+
39
+ - CPU & memory usage
40
+ - Available disk space
41
+ - Active FPS
42
+ - Dropped frames information
43
+
44
+ ## Getting started
45
+
46
+ ### Installation
47
+
48
+ Make sure that the following node_modules are installed:
49
+
50
+ ```shell
51
+ npm install @overwolf/ow-electron @overwolf/ow-electron-builder @overwolf/ow-electron-packages-types
52
+ ```
53
+
54
+ > Currently, the recording api is in beta. To install the beta version use:
55
+ > `npm install @overwolf/ow-electron-packages-types@beta`
56
+ > Alternatively amend the beta package to your package.json and use `npm install` to update dependencies:
57
+
58
+ ```json
59
+ ...
60
+ "devDependencies": {
61
+ "@overwolf/ow-electron-packages-types": "beta",
62
+ }
63
+ ...
64
+ ```
65
+
66
+ To activate the recording package, place the "recorder" string under \`overwolf -> packages\` in your app's \`package.json\`:
67
+
68
+ ```
69
+ {
70
+ ...
71
+ "overwolf": {
72
+ "packages": [
73
+ "recorder"
74
+ ]
75
+ },
76
+ ...
77
+ }
78
+ ```
79
+
80
+ ### Recorder Usage
81
+
82
+ #### Import
83
+
84
+ ```javascript
85
+ import { app as electronApp } from 'electron';
86
+ import { overwolf } from '@overwolf/ow-electron';
87
+ ```
88
+
89
+ Import the app from 'electron' & overwolf from \`@overwolf/ow-electron\`.
90
+
91
+ #### Register
92
+
93
+ ```javascript
94
+ const owElectronApp = electronApp as overwolf.OverwolfApp;
95
+ owElectronPackages.on('ready', (e, packageName) => {
96
+ if (packageName === 'recorder') {
97
+ console.log('Recorder package is loaded');
98
+ }
99
+ });
100
+ ```
101
+
102
+ Register to the ready state, and once the ready event is fired, verify that the package name is \recorder\.
103
+
104
+ ```javascript
105
+ recorderApi.on('recording-started', (RecordEventArgs) => {
106
+ console.log(RecordEventArgs.filePath);
107
+ });
108
+ ```
109
+
110
+ Use event listeners to get notified by events. For more examples see: [Recording events](api-specification.md#events):
111
+
112
+ #### Query information
113
+
114
+ ```javascript
115
+ // obtain OBS Information
116
+ const obsInfo = await recorderApi.queryInformation();
117
+
118
+ // Get default audio encoder
119
+ console.log(obsInfo.audio.defaultEncoder);
120
+
121
+ // Get audio input devices array
122
+ console.log(obsInfo.audio.inputDevices);
123
+
124
+ // Get audio output devices array
125
+ console.log(obsInfo.audio.outputDevices);
126
+
127
+ // Get videos displays array
128
+ console.log(obsInfo.video.adapters);
129
+
130
+ // Get default video encoder
131
+ console.log(obsInfo.video.defaultEncoder);
132
+
133
+ // Get available supported video encoders
134
+ console.log(obsInfo.video.encoders);
135
+
136
+ // Get available supported audio encoders
137
+ console.log(obsInfo.audio.encoders);
138
+ ```
139
+
140
+ - Use the query information method to obtain information about the running machine:
141
+ - Display devices
142
+ - Audio Devices
143
+ - Supported codecs etc
144
+
145
+ #### Start Recording - Simple
146
+
147
+ ```javascript
148
+ async function startRecording(gameInfo: GameInfo = null) {
149
+ try {
150
+ // 1. create the default setting builder
151
+ const settingsBuilder = await recorderApi.createSettingsBuilder({
152
+ // with default audio (mic / desktop)
153
+ includeDefaultAudioSources: true,
154
+ });
155
+
156
+ /* changing default video settings
157
+ settingsBuilder.videoSettings.fps = 60;
158
+ settingsBuilder.videoSettings.baseWidth = 1920;
159
+ settingsBuilder.videoSettings.baseHeight = 1080;
160
+ */
161
+
162
+ // 2. do we want to capture game or display?
163
+ if (gameInfo) {
164
+ // game capture
165
+ settingsBuilder.addGameSource({
166
+ gameProcess: gameInfo.processInfo.pid, // or just 'Game.exe' name
167
+ captureOverlays: true, // capture overlay windows
168
+ });
169
+ } else {
170
+ // desktop capture
171
+ // |monitorId| from '''queryInformation()'''
172
+ settingsBuilder.addScreenSource({ monitorId });
173
+ }
174
+
175
+ // 3. Build the capture settings using the `build()` **method**
176
+ const captureSettings = settingsBuilder.build();
177
+
178
+ const outputFolder = path.join(app.getPath('videos'), app.name);
179
+
180
+ const fileName = game?.name ?? 'display';
181
+
182
+ // 4. Set the recording options
183
+ const recordingOptions: RecordingOptions = {
184
+ // note: if filepath already exits, it will override it.
185
+ filePath: path.join(outputFolder, 'MyRecording'),
186
+ autoShutdownOnGameExit: false, // when 'true' on game process exit, the recording will stop automatically
187
+ fileFormat: 'mp4',
188
+ };
189
+
190
+ // 5. Start recording
191
+ await recorderApi.startRecording(
192
+ recordingOptions,
193
+ captureSettings,
194
+ (stopResult) => {
195
+ // also can be handled at 'recording-stopped'
196
+ console.log('Recording stopped ', stopResult);
197
+ },
198
+ );
199
+
200
+ // we can start replay's also here...
201
+ } catch (err) {
202
+ console.log('Error while starting recording', err);
203
+ }
204
+ }
205
+ ```
206
+
207
+ 1. Create the capture settings options object.
208
+ 2. add capture source
209
+ 3. Use the capture settings options object to create the settings builder.
210
+ 4. Build the capture settings using the `build()` method
211
+ 5. Set the recording options
212
+ 6. Start recording
213
+
214
+ #### Stop Recording
215
+
216
+ ```javascript
217
+ async function stopRecording() {
218
+ try {
219
+ const active = await recorderApi.isActive();
220
+ if (!active) {
221
+ return;
222
+ }
223
+
224
+ // stop recording
225
+ await recorderApi.stopRecording((recordStopEventArgs) => {
226
+ console.log(recordStopEventArgs.duration);
227
+ });
228
+ } catch (err) {
229
+ console.log('Error while stopping recording', err);
230
+ }
231
+ }
232
+ ```
233
+
234
+ 1. Before attempting to stop the capture directly, we can use the `isActive()` method to check if the capture is active.
235
+ 2. Once we know the recording is active, We can call the `stopRecording()` method, include the optional callback to obtain details about the stopped capture.
236
+
237
+ #### Change Capture Sources
238
+
239
+ - Once we have the settingsBuilder object we can use it to select specific capture sources:
240
+
241
+ ##### Add Game Source:
242
+
243
+ ```javascript
244
+ const settingsBuilder = await recorderApi.createSettingsBuilder(
245
+ captureSettingsOptions,
246
+ );
247
+ const gameProcessId = 45623; // example process Id, Obtain process Id by registering to game listeners.
248
+
249
+ // sets the game with process id 45623 to be the source of the recording.
250
+ settingsBuilder.addGameSource({ gameProcess: gameProcessId });
251
+
252
+ // Build the capture settings using the `build()` **method**
253
+ const captureSettings = settingsBuilder.build();
254
+ ```
255
+
256
+ ##### Add Display Source:
257
+
258
+ ```javascript
259
+ const settingsBuilder = await recorderApi.createSettingsBuilder();
260
+ // Example display Id, Obtain machine displays by using the queryInformation() method
261
+ const displayAltId = 'my_display_id';
262
+
263
+ // Sets the display id to be the source of the recording.
264
+ settingsBuilder.addScreenSource({ monitorId: displayAltId });
265
+
266
+ // Build the capture settings using the `build()` **method**
267
+ const captureSettings = settingsBuilder.build();
268
+ ```
269
+
270
+ ##### Add Audio Default source:
271
+
272
+ ```javascript
273
+ const settingsBuilder = await recorderApi.createSettingsBuilder(
274
+ includeDefaultAudioSources: false,
275
+ );
276
+
277
+ // Sets the Default output audio device as the audio source for the recording,
278
+ // for example speakers or headphones.
279
+ // Any sound coming from this device will be recorded.
280
+ settingsBuilder.addAudioDefaultCapture('output');
281
+
282
+ // Alternatively you can use the default input device, like a microphone.
283
+ // settingsBuilder.addAudioDefaultCapture('input')
284
+
285
+ // Alternatively set other device ( Obtain devices from queryInformation() method)
286
+ // settingsBuilder.addAudioCapture({id: the_device_id, name: "my device"})
287
+
288
+ // Build the capture settings using the `build()` **method**
289
+ const captureSettings = settingsBuilder.build();
290
+ ```
291
+
292
+ #### Replays & Capture
293
+
294
+ ##### Start Replay
295
+
296
+ ```javascript
297
+ async function startReplays() {}
298
+ try {
299
+ // Create the capture settings options object.
300
+ const captureSettingsOptions: CaptureSettingsOptions = {
301
+ includeDefaultAudioSources: true,
302
+ }
303
+ // Build the capture settings using the build() method
304
+ const settings =
305
+ await recorderApi.createSettingsBuilder(captureSettingsOptions);
306
+
307
+ // set key frame every 1 second for more accurate stop timestamp;
308
+ // note: this require more resource from the recording engine
309
+ // settings.videoEncoderSettings.keyint_sec = 1;
310
+
311
+ const settingsCapture = settings.build();
312
+
313
+ const outputFolder = path.join(app.getPath('videos'), app.name, 'replays');
314
+ // Set the replays options
315
+ const replaysOptions: ReplayOptions = {
316
+ bufferSecond: 30,
317
+ rootFolder: outputFolder
318
+ fileFormat: 'mp4',
319
+ }
320
+
321
+ // Start replays
322
+ await recorderApi.startReplays(
323
+ replaysOptions,
324
+ // if recording (i.e start recording) is already on, settingsCapture is not mandatory
325
+ settingsCapture,
326
+ );
327
+
328
+ } catch (err) {
329
+ console.error('START replay ERROR', err);
330
+ }
331
+ ```
332
+
333
+ 1. Create the capture settings options object.
334
+ 2. Use the capture settings options object to create the settings builder.
335
+ 3. Build the capture settings using the build() method
336
+ 4. Set the replays options
337
+ 5. Start Replays
338
+
339
+ ##### Start Capturing Replays
340
+
341
+ ```javascript
342
+ async function startCaptureReplay() {
343
+ try {
344
+ const fileName = `MyReplay-${timestemp()}`; // probely
345
+ // Create the replay Capture Options object.
346
+ const replayCaptureOptions: CaptureReplayOptions = {
347
+ fileName: 'replay-capture',
348
+ pastDuration: 30000,
349
+ // timeout: 10000 // stop the replay in 10 second
350
+ };
351
+
352
+ // Use the replay capture options to start the capture replay.
353
+ // The captureReplay method returns the activeReplay,
354
+ // we can use it to control the capturing
355
+ const activeReplay = await recorderApi.captureReplay(
356
+ replayCaptureOptions,
357
+ (video) => {
358
+ console.log('replay video ready ', video);
359
+ // Once the captureReplay callback is returned we set the activeReplay
360
+ // as undefined to indicate that the replay capture is done.
361
+ activeReplay = undefined;
362
+ },
363
+ );
364
+ } catch (error) {
365
+ console.error('Error starting capture replay', error);
366
+ }
367
+ }
368
+ ```
369
+
370
+ 1. Create the replay Capture Options object.
371
+ 2. Use the replay capture options to start the capture replay.
372
+ 3. The captureReplay method returns the activeReplay, we can use it to control the capturing replay.
373
+ 4. Once the captureReplay callback is returned we set the activeReplay as undefined to indicate that the replay capture is done.
374
+
375
+ ##### Extend Capture Replay
376
+
377
+ ```javascript
378
+ // Check activeReplay is not undefined, which means the capture replay is currently recording.
379
+ if (!activeReplay) {
380
+ return;
381
+ }
382
+
383
+ // Obtain how long remains in ms until the timeout, and the capture is stopped.
384
+ console.log(activeReplay.timeout);
385
+
386
+ // Stop capture replay after 10000ms
387
+ activeReplay.stopAfter(10000);
388
+ ```
389
+
390
+ - While the capture replay is running we can extend it's timeout by using the activeReplay object
391
+
392
+ ##### Stopping Capture Replay
393
+
394
+ ```javascript
395
+ // Stop capture replay immediately
396
+ activeReplay.stop();
397
+ ```