@clockworkdog/cogs-client 1.5.6 → 2.0.0-beta.1
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/LICENSE +21 -0
- package/README.md +90 -21
- package/dist/AudioPlayer.d.ts +2 -2
- package/dist/AudioPlayer.js +2 -3
- package/dist/CogsConnection.d.ts +62 -55
- package/dist/CogsConnection.js +88 -42
- package/dist/RtspStreamer.js +1 -1
- package/dist/VideoPlayer.d.ts +2 -2
- package/dist/VideoPlayer.js +4 -4
- package/dist/browser/index.js +118 -68
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -2
- package/dist/types/AllMediaClipStatesMessage.d.ts +1 -1
- package/dist/types/AudioState.d.ts +1 -1
- package/dist/types/CogsClientMessage.d.ts +4 -4
- package/dist/types/ManifestTypes.d.ts +33 -0
- package/dist/types/ManifestTypes.js +2 -0
- package/dist/types/MediaClipStateMessage.d.ts +1 -1
- package/dist/types/MediaObjectFit.d.ts +1 -1
- package/dist/types/PluginManifestJson.d.ts +27 -14
- package/dist/types/ShowPhase.d.ts +7 -0
- package/dist/types/{valueTypes.js → ShowPhase.js} +2 -2
- package/dist/types/VideoState.js +1 -1
- package/dist/types/utils.d.ts +9 -0
- package/dist/types/utils.js +2 -0
- package/package.json +3 -2
- package/dist/types/valueTypes.d.ts +0 -18
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Clockwork Dog
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -30,10 +30,61 @@ yarn add @clockworkdog/cogs-client
|
|
|
30
30
|
|
|
31
31
|
## Usage
|
|
32
32
|
|
|
33
|
-
### Create a `cogs-plugin-manifest.
|
|
33
|
+
### Create a `cogs-plugin-manifest.js` file
|
|
34
34
|
|
|
35
35
|
See [PluginManifestJson](https://clockwork-dog.github.io/cogs-client-lib/interfaces/PluginManifestJson.html) for details of what to include.
|
|
36
36
|
|
|
37
|
+
If using Typescript set `"allowJs": true` in your `tsconfig.json`.
|
|
38
|
+
|
|
39
|
+
Use the `@type {const}` JSDoc annotation to allow the manifest to be imported as a literal type and `@satisfies {import("@clockworkdog/cogs-client").PluginManifestJson}` to allow your editor to check the validity of the manifest.
|
|
40
|
+
|
|
41
|
+
e.g.
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
module.exports =
|
|
45
|
+
/**
|
|
46
|
+
* @type {const}
|
|
47
|
+
* @satisfies {import("@clockworkdog/cogs-client").PluginManifestJsonReadonly}
|
|
48
|
+
*/
|
|
49
|
+
({
|
|
50
|
+
name: 'Big Button',
|
|
51
|
+
icon: 'bullseye-pointer',
|
|
52
|
+
description: 'A big, colorful touchscreen button',
|
|
53
|
+
version: '1',
|
|
54
|
+
config: [
|
|
55
|
+
{
|
|
56
|
+
name: 'Color',
|
|
57
|
+
value: { type: 'string', default: 'red' },
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
state: [
|
|
61
|
+
{
|
|
62
|
+
name: 'Enabled',
|
|
63
|
+
value: { type: 'boolean', default: false },
|
|
64
|
+
writableFromCogs: true,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
events: {
|
|
68
|
+
toCogs: [
|
|
69
|
+
{
|
|
70
|
+
name: 'Pressed',
|
|
71
|
+
value: { type: 'boolean' },
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
fromCogs: [
|
|
75
|
+
{
|
|
76
|
+
name: 'Explosion',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
media: {
|
|
81
|
+
audio: true,
|
|
82
|
+
video: true,
|
|
83
|
+
images: true,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
37
88
|
### Import the library
|
|
38
89
|
|
|
39
90
|
#### Browser
|
|
@@ -48,7 +99,7 @@ const { CogsConnection, CogsAudioPlayer } = COGS;
|
|
|
48
99
|
const { CogsConnection, CogsAudioPlayer } = require('@clockworkdog/cogs-client');
|
|
49
100
|
```
|
|
50
101
|
|
|
51
|
-
####
|
|
102
|
+
#### Typescript / ES6
|
|
52
103
|
|
|
53
104
|
```ts
|
|
54
105
|
import { CogsConnection, CogsAudioPlayer } from '@clockworkdog/cogs-client';
|
|
@@ -56,35 +107,35 @@ import { CogsConnection, CogsAudioPlayer } from '@clockworkdog/cogs-client';
|
|
|
56
107
|
|
|
57
108
|
### Connect to COGS
|
|
58
109
|
|
|
110
|
+
Initialize a [CogsConnection](https://clockwork-dog.github.io/cogs-client-lib/interfaces/CogsConnection.html) with the manifest you created above.
|
|
111
|
+
|
|
59
112
|
```ts
|
|
60
113
|
let connected = false;
|
|
61
114
|
|
|
62
|
-
|
|
115
|
+
import manifest from './cogs-plugin-manifest.js'; // Requires `"allowJs": true` in `tsconfig.json`
|
|
116
|
+
|
|
117
|
+
const cogsConnection = new CogsConnection(manifest);
|
|
63
118
|
cogsConnection.addEventListener('open', () => {
|
|
64
119
|
connected = true;
|
|
65
120
|
});
|
|
66
121
|
cogsConnection.addEventListener('close', () => {
|
|
67
122
|
connected = false;
|
|
68
123
|
});
|
|
69
|
-
cogsConnection.addEventListener('config', (
|
|
70
|
-
|
|
71
|
-
//
|
|
72
|
-
// `config` is of type `{ [configKey: string]: number | string | boolean }`
|
|
124
|
+
cogsConnection.addEventListener('config', ({ config }) => {
|
|
125
|
+
// Handle new config
|
|
126
|
+
// `config` is of type `{ [name: string]: number | string | boolean }`
|
|
73
127
|
});
|
|
74
|
-
cogsConnection.addEventListener('
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
// `updates` is of type `{ [portName: string]: number | string | boolean }`
|
|
128
|
+
cogsConnection.addEventListener('state', ({ state }) => {
|
|
129
|
+
// Handle state updates
|
|
130
|
+
// `state` is of type `{ [name: string]: number | string | boolean }`
|
|
78
131
|
});
|
|
79
|
-
cogsConnection.addEventListener('event', (
|
|
80
|
-
|
|
81
|
-
//
|
|
82
|
-
// `
|
|
83
|
-
// `value` is the type defined in COGS, one of `number | string | boolean | undefined`
|
|
132
|
+
cogsConnection.addEventListener('event', ({ name, value }) => {
|
|
133
|
+
// Handle events from COGS
|
|
134
|
+
// `name` is the event name.
|
|
135
|
+
// `value` is of the type defined in manifest, one of `number | string | boolean | undefined`.
|
|
84
136
|
});
|
|
85
|
-
cogsConnection.addEventListener('message', (
|
|
86
|
-
|
|
87
|
-
// Handle message. See `types/CogsClientMessage.ts`
|
|
137
|
+
cogsConnection.addEventListener('message', ({ message }) => {
|
|
138
|
+
// Handle low-level COGS messages. See `types/CogsClientMessage.ts`
|
|
88
139
|
});
|
|
89
140
|
|
|
90
141
|
function sendEventToCogs() {
|
|
@@ -92,12 +143,30 @@ function sendEventToCogs() {
|
|
|
92
143
|
}
|
|
93
144
|
|
|
94
145
|
function sendPortUpdateToCogs() {
|
|
95
|
-
cogsConnection.
|
|
146
|
+
cogsConnection.setState({ port1: 100 });
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Support audio actions
|
|
151
|
+
|
|
152
|
+
Add `audio` to `cogs-plugin-manifest.js`:
|
|
153
|
+
|
|
154
|
+
```js
|
|
155
|
+
{
|
|
156
|
+
media: {
|
|
157
|
+
audio: true;
|
|
158
|
+
}
|
|
96
159
|
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Add [CogsAudioPlayer](https://clockwork-dog.github.io/cogs-client-lib/classes/CogsAudioPlayer.html) to your page:
|
|
97
163
|
|
|
164
|
+
```ts
|
|
98
165
|
const audioPlayer = new CogsAudioPlayer(cogsConnection);
|
|
166
|
+
|
|
167
|
+
// Optional
|
|
99
168
|
audioPlayer.addEventListener('state', (audioState) => {
|
|
100
|
-
// Handle audio state. See `types/AudioState.ts`
|
|
169
|
+
// Handle audio state changes. See `types/AudioState.ts`
|
|
101
170
|
});
|
|
102
171
|
```
|
|
103
172
|
|
package/dist/AudioPlayer.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import CogsConnection from './CogsConnection';
|
|
2
2
|
import { AudioState } from './types/AudioState';
|
|
3
3
|
import MediaClipStateMessage from './types/MediaClipStateMessage';
|
|
4
|
-
|
|
4
|
+
type EventTypes = {
|
|
5
5
|
state: AudioState;
|
|
6
6
|
audioClipState: MediaClipStateMessage;
|
|
7
7
|
};
|
|
@@ -10,7 +10,7 @@ export default class AudioPlayer {
|
|
|
10
10
|
private globalVolume;
|
|
11
11
|
private audioClipPlayers;
|
|
12
12
|
private sinkId;
|
|
13
|
-
constructor(cogsConnection: CogsConnection);
|
|
13
|
+
constructor(cogsConnection: CogsConnection<any>);
|
|
14
14
|
setGlobalVolume(volume: number): void;
|
|
15
15
|
playAudioClip(path: string, { playId, volume, fade, loop }: {
|
|
16
16
|
playId: string;
|
package/dist/AudioPlayer.js
CHANGED
|
@@ -16,8 +16,7 @@ class AudioPlayer {
|
|
|
16
16
|
cogsConnection.sendMediaClipState(detail);
|
|
17
17
|
});
|
|
18
18
|
// Listen for audio control messages
|
|
19
|
-
cogsConnection.addEventListener('message', (
|
|
20
|
-
const message = event.detail;
|
|
19
|
+
cogsConnection.addEventListener('message', ({ message }) => {
|
|
21
20
|
switch (message.type) {
|
|
22
21
|
case 'media_config_update':
|
|
23
22
|
if (this.globalVolume !== message.globalVolume) {
|
|
@@ -408,7 +407,7 @@ class AudioPlayer {
|
|
|
408
407
|
}
|
|
409
408
|
createPlayer(path, config) {
|
|
410
409
|
const player = new howler_1.Howl({
|
|
411
|
-
src: urls_1.assetUrl(path),
|
|
410
|
+
src: (0, urls_1.assetUrl)(path),
|
|
412
411
|
autoplay: false,
|
|
413
412
|
loop: false,
|
|
414
413
|
volume: 1,
|
package/dist/CogsConnection.d.ts
CHANGED
|
@@ -1,57 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ShowPhase from './types/ShowPhase';
|
|
2
2
|
import CogsClientMessage from './types/CogsClientMessage';
|
|
3
3
|
import MediaClipStateMessage from './types/MediaClipStateMessage';
|
|
4
4
|
import AllMediaClipStatesMessage from './types/AllMediaClipStatesMessage';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
[port: string]: PortValue;
|
|
11
|
-
};
|
|
12
|
-
inputEvents?: {
|
|
13
|
-
[key: string]: EventValue | null;
|
|
14
|
-
};
|
|
15
|
-
}> {
|
|
16
|
-
open: undefined;
|
|
17
|
-
close: undefined;
|
|
18
|
-
message: CogsClientMessage;
|
|
19
|
-
config: CustomTypes['config'];
|
|
20
|
-
updates: Partial<CustomTypes['inputPorts']>;
|
|
21
|
-
event: CustomTypes['inputEvents'] extends {
|
|
22
|
-
[key: string]: EventValue | null;
|
|
23
|
-
} ? EventKeyValue<CustomTypes['inputEvents']> : Record<string, never>;
|
|
24
|
-
}
|
|
25
|
-
export declare type TimerState = Omit<Extract<CogsClientMessage, {
|
|
26
|
-
type: 'adjustable_timer_update';
|
|
27
|
-
}>, 'type'> & {
|
|
28
|
-
startedAt: number;
|
|
29
|
-
};
|
|
30
|
-
export default class CogsConnection<CustomTypes extends {
|
|
31
|
-
config?: {
|
|
32
|
-
[configKey: string]: ConfigValue;
|
|
33
|
-
};
|
|
34
|
-
inputPorts?: {
|
|
35
|
-
[port: string]: PortValue;
|
|
36
|
-
};
|
|
37
|
-
outputPorts?: {
|
|
38
|
-
[port: string]: PortValue;
|
|
39
|
-
};
|
|
40
|
-
inputEvents?: {
|
|
41
|
-
[key: string]: EventValue | null;
|
|
42
|
-
};
|
|
43
|
-
outputEvents?: {
|
|
44
|
-
[key: string]: EventValue | null;
|
|
45
|
-
};
|
|
46
|
-
} = Record<never, never>> {
|
|
5
|
+
import { PluginManifestEventJson } from './types/PluginManifestJson';
|
|
6
|
+
import * as ManifestTypes from './types/ManifestTypes';
|
|
7
|
+
import { DeepReadonly } from './types/utils';
|
|
8
|
+
export default class CogsConnection<Manifest extends ManifestTypes.PluginManifest> {
|
|
9
|
+
readonly manifest: Manifest;
|
|
47
10
|
private websocket;
|
|
48
11
|
private eventTarget;
|
|
49
12
|
private currentConfig;
|
|
50
|
-
get config():
|
|
51
|
-
private
|
|
52
|
-
get
|
|
53
|
-
private currentOutputPortValues;
|
|
54
|
-
get outputPortValues(): CustomTypes['outputPorts'];
|
|
13
|
+
get config(): ManifestTypes.ConfigAsObject<Manifest>;
|
|
14
|
+
private currentState;
|
|
15
|
+
get state(): ManifestTypes.StateAsObject<Manifest>;
|
|
55
16
|
private _showPhase;
|
|
56
17
|
get showPhase(): ShowPhase;
|
|
57
18
|
private _timerState;
|
|
@@ -62,14 +23,18 @@ export default class CogsConnection<CustomTypes extends {
|
|
|
62
23
|
private audioOutputs;
|
|
63
24
|
private _selectedAudioOutput;
|
|
64
25
|
get selectedAudioOutput(): string;
|
|
65
|
-
constructor({ hostname, port }?: {
|
|
26
|
+
constructor(manifest: Manifest, { hostname, port }?: {
|
|
66
27
|
hostname?: string;
|
|
67
28
|
port?: number;
|
|
68
|
-
},
|
|
29
|
+
}, initialClientState?: Partial<ManifestTypes.StateAsObject<Manifest, {
|
|
30
|
+
writableFromClient: true;
|
|
31
|
+
}>> | undefined);
|
|
69
32
|
get isConnected(): boolean;
|
|
70
33
|
close(): void;
|
|
71
|
-
sendEvent<EventName extends
|
|
72
|
-
|
|
34
|
+
sendEvent<EventName extends ManifestTypes.EventToCogsKey<Manifest>>(eventName: EventName, ...[eventValue]: ManifestTypes.EventToCogsAsObject<Manifest>[EventName] extends undefined ? [] : [ManifestTypes.EventToCogsAsObject<Manifest>[EventName]]): void;
|
|
35
|
+
setState(values: Partial<ManifestTypes.StateAsObject<Manifest, {
|
|
36
|
+
writableFromClient: true;
|
|
37
|
+
}>>): void;
|
|
73
38
|
getAudioSinkId(audioOutput: string): string | undefined;
|
|
74
39
|
sendInitialMediaClipStates(allMediaClipStates: AllMediaClipStatesMessage): void;
|
|
75
40
|
sendMediaClipState(mediaClipState: MediaClipStateMessage): void;
|
|
@@ -80,8 +45,50 @@ export default class CogsConnection<CustomTypes extends {
|
|
|
80
45
|
* This is only relevant for plugins, not for Media Master content.
|
|
81
46
|
*/
|
|
82
47
|
setPluginWindowVisible(visible: boolean): void;
|
|
83
|
-
addEventListener<
|
|
84
|
-
|
|
48
|
+
addEventListener<EventType extends CogsConnectionEvent<Manifest>['type']>(type: EventType, listener: (event: CogsConnectionEvent<Manifest> & {
|
|
49
|
+
type: EventType;
|
|
50
|
+
}) => void, options?: boolean | AddEventListenerOptions): void;
|
|
51
|
+
removeEventListener<EventType extends CogsConnectionEvent<Manifest>['type']>(type: EventType, listener: (event: Extract<CogsConnectionEvent<Manifest>, {
|
|
52
|
+
type: EventType;
|
|
53
|
+
}>) => void, options?: boolean | EventListenerOptions): void;
|
|
85
54
|
private dispatchEvent;
|
|
86
55
|
}
|
|
87
|
-
export {
|
|
56
|
+
export type TimerState = Omit<Extract<CogsClientMessage, {
|
|
57
|
+
type: 'adjustable_timer_update';
|
|
58
|
+
}>, 'type'> & {
|
|
59
|
+
startedAt: number;
|
|
60
|
+
};
|
|
61
|
+
export declare class CogsConnectionOpenEvent extends Event {
|
|
62
|
+
readonly type = "open";
|
|
63
|
+
constructor();
|
|
64
|
+
}
|
|
65
|
+
export declare class CogsConnectionCloseEvent extends Event {
|
|
66
|
+
readonly type = "close";
|
|
67
|
+
constructor();
|
|
68
|
+
}
|
|
69
|
+
export declare class CogsMessageEvent extends Event {
|
|
70
|
+
readonly message: CogsClientMessage;
|
|
71
|
+
readonly type = "message";
|
|
72
|
+
constructor(message: CogsClientMessage);
|
|
73
|
+
}
|
|
74
|
+
export declare class CogsConfigChangedEvent<CogsConfig> extends Event {
|
|
75
|
+
readonly config: CogsConfig;
|
|
76
|
+
readonly type = "config";
|
|
77
|
+
constructor(config: CogsConfig);
|
|
78
|
+
}
|
|
79
|
+
export declare class CogsStateChangedEvent<CogsState> extends Event {
|
|
80
|
+
readonly state: CogsState;
|
|
81
|
+
readonly type = "state";
|
|
82
|
+
constructor(state: CogsState);
|
|
83
|
+
}
|
|
84
|
+
export declare class CogsIncomingEvent<CogsEvent extends DeepReadonly<PluginManifestEventJson> | PluginManifestEventJson> extends Event {
|
|
85
|
+
readonly name: CogsEvent['name'];
|
|
86
|
+
readonly value: ManifestTypes.TypeFromCogsValueType<CogsEvent['value']>;
|
|
87
|
+
readonly type = "event";
|
|
88
|
+
constructor(name: CogsEvent['name'], value: ManifestTypes.TypeFromCogsValueType<CogsEvent['value']>);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Allows CogsIncomingEvent of each supported value type
|
|
92
|
+
*/
|
|
93
|
+
export type CogsIncomingEventTypes<CogsEvent extends DeepReadonly<PluginManifestEventJson> | PluginManifestEventJson> = CogsEvent extends unknown ? CogsIncomingEvent<CogsEvent> : never;
|
|
94
|
+
export type CogsConnectionEvent<Manifest extends ManifestTypes.PluginManifest> = CogsConnectionOpenEvent | CogsConnectionCloseEvent | CogsMessageEvent | CogsConfigChangedEvent<ManifestTypes.ConfigAsObject<Manifest>> | CogsStateChangedEvent<Partial<ManifestTypes.StateAsObject<Manifest>>> | CogsIncomingEventTypes<ManifestTypes.EventsFromCogs<Manifest>>;
|
package/dist/CogsConnection.js
CHANGED
|
@@ -3,35 +3,51 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
|
|
6
|
+
exports.CogsIncomingEvent = exports.CogsStateChangedEvent = exports.CogsConfigChangedEvent = exports.CogsMessageEvent = exports.CogsConnectionCloseEvent = exports.CogsConnectionOpenEvent = void 0;
|
|
7
|
+
const ShowPhase_1 = __importDefault(require("./types/ShowPhase"));
|
|
7
8
|
const reconnecting_websocket_1 = __importDefault(require("reconnecting-websocket"));
|
|
8
9
|
const urls_1 = require("./helpers/urls");
|
|
9
10
|
class CogsConnection {
|
|
10
|
-
|
|
11
|
+
get config() {
|
|
12
|
+
return { ...this.currentConfig };
|
|
13
|
+
}
|
|
14
|
+
get state() {
|
|
15
|
+
return { ...this.currentState };
|
|
16
|
+
}
|
|
17
|
+
get showPhase() {
|
|
18
|
+
return this._showPhase;
|
|
19
|
+
}
|
|
20
|
+
get timerState() {
|
|
21
|
+
return this._timerState ? { ...this._timerState } : null;
|
|
22
|
+
}
|
|
23
|
+
get selectedAudioOutput() {
|
|
24
|
+
return this._selectedAudioOutput;
|
|
25
|
+
}
|
|
26
|
+
constructor(manifest, { hostname = document.location.hostname, port = urls_1.COGS_SERVER_PORT } = {}, initialClientState = undefined) {
|
|
11
27
|
var _a;
|
|
28
|
+
this.manifest = manifest;
|
|
12
29
|
this.eventTarget = new EventTarget();
|
|
13
30
|
this.currentConfig = {}; // Received on open connection
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
16
|
-
this._showPhase = valueTypes_1.ShowPhase.Setup;
|
|
31
|
+
this.currentState = {}; // Received on open connection - TODO: set initial state from manifest?
|
|
32
|
+
this._showPhase = ShowPhase_1.default.Setup;
|
|
17
33
|
this._timerState = null;
|
|
18
34
|
/**
|
|
19
35
|
* Cached audio outputs use to look up the device/sink ID when a different device label is requested
|
|
20
36
|
*/
|
|
21
37
|
this.audioOutputs = undefined;
|
|
22
38
|
this._selectedAudioOutput = '';
|
|
23
|
-
this.
|
|
39
|
+
this.currentState = { ...initialClientState };
|
|
24
40
|
const { useReconnectingWebsocket, path, pathParams } = websocketParametersFromUrl(document.location.href);
|
|
25
41
|
const socketUrl = `ws://${hostname}:${port}${path}${pathParams ? '?' + pathParams : ''}`;
|
|
26
42
|
this.websocket = useReconnectingWebsocket ? new reconnecting_websocket_1.default(socketUrl) : new WebSocket(socketUrl);
|
|
27
43
|
this.websocket.onopen = () => {
|
|
28
44
|
this.currentConfig = {}; // Received on open connection
|
|
29
|
-
this.
|
|
30
|
-
this.dispatchEvent(
|
|
31
|
-
this.
|
|
45
|
+
this.currentState = {}; // Received on open connection
|
|
46
|
+
this.dispatchEvent(new CogsConnectionOpenEvent());
|
|
47
|
+
this.setState(this.currentState); // TODO: Remove this because you should set it manually...??
|
|
32
48
|
};
|
|
33
49
|
this.websocket.onclose = () => {
|
|
34
|
-
this.dispatchEvent(
|
|
50
|
+
this.dispatchEvent(new CogsConnectionCloseEvent());
|
|
35
51
|
};
|
|
36
52
|
this.websocket.onmessage = ({ data }) => {
|
|
37
53
|
try {
|
|
@@ -39,29 +55,30 @@ class CogsConnection {
|
|
|
39
55
|
try {
|
|
40
56
|
if (parsed.config) {
|
|
41
57
|
this.currentConfig = parsed.config;
|
|
42
|
-
this.dispatchEvent(
|
|
58
|
+
this.dispatchEvent(new CogsConfigChangedEvent(this.currentConfig));
|
|
43
59
|
}
|
|
44
60
|
else if (parsed.updates) {
|
|
45
|
-
this.
|
|
46
|
-
this.dispatchEvent(
|
|
61
|
+
this.currentState = { ...this.currentState, ...parsed.updates };
|
|
62
|
+
this.dispatchEvent(new CogsStateChangedEvent(parsed.updates));
|
|
47
63
|
}
|
|
48
64
|
else if (parsed.event && parsed.event.key) {
|
|
49
|
-
this.dispatchEvent(
|
|
65
|
+
this.dispatchEvent(new CogsIncomingEvent(parsed.event.key, parsed.event.value));
|
|
50
66
|
}
|
|
51
67
|
else if (typeof parsed.message === 'object') {
|
|
52
|
-
|
|
68
|
+
const message = parsed.message;
|
|
69
|
+
switch (message.type) {
|
|
53
70
|
case 'adjustable_timer_update':
|
|
54
71
|
this._timerState = {
|
|
55
72
|
startedAt: Date.now(),
|
|
56
|
-
durationMillis:
|
|
57
|
-
ticking:
|
|
73
|
+
durationMillis: message.durationMillis,
|
|
74
|
+
ticking: message.ticking,
|
|
58
75
|
};
|
|
59
76
|
break;
|
|
60
77
|
case 'show_phase':
|
|
61
|
-
this._showPhase =
|
|
78
|
+
this._showPhase = message.phase;
|
|
62
79
|
break;
|
|
63
80
|
}
|
|
64
|
-
this.dispatchEvent(
|
|
81
|
+
this.dispatchEvent(new CogsMessageEvent(message));
|
|
65
82
|
}
|
|
66
83
|
}
|
|
67
84
|
catch (e) {
|
|
@@ -82,29 +99,11 @@ class CogsConnection {
|
|
|
82
99
|
this.audioOutputs = audioOutputs;
|
|
83
100
|
}
|
|
84
101
|
};
|
|
85
|
-
this.addEventListener('open', refreshAudioOutputs);
|
|
102
|
+
this.eventTarget.addEventListener('open', refreshAudioOutputs);
|
|
86
103
|
(_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.addEventListener('devicechange', refreshAudioOutputs);
|
|
87
104
|
refreshAudioOutputs();
|
|
88
105
|
}
|
|
89
106
|
}
|
|
90
|
-
get config() {
|
|
91
|
-
return { ...this.currentConfig };
|
|
92
|
-
}
|
|
93
|
-
get inputPortValues() {
|
|
94
|
-
return { ...this.currentInputPortValues };
|
|
95
|
-
}
|
|
96
|
-
get outputPortValues() {
|
|
97
|
-
return { ...this.currentOutputPortValues };
|
|
98
|
-
}
|
|
99
|
-
get showPhase() {
|
|
100
|
-
return this._showPhase;
|
|
101
|
-
}
|
|
102
|
-
get timerState() {
|
|
103
|
-
return this._timerState ? { ...this._timerState } : null;
|
|
104
|
-
}
|
|
105
|
-
get selectedAudioOutput() {
|
|
106
|
-
return this._selectedAudioOutput;
|
|
107
|
-
}
|
|
108
107
|
get isConnected() {
|
|
109
108
|
return this.websocket.readyState === WebSocket.OPEN;
|
|
110
109
|
}
|
|
@@ -121,8 +120,8 @@ class CogsConnection {
|
|
|
121
120
|
}));
|
|
122
121
|
}
|
|
123
122
|
}
|
|
124
|
-
|
|
125
|
-
this.
|
|
123
|
+
setState(values) {
|
|
124
|
+
this.currentState = { ...this.currentState, ...values };
|
|
126
125
|
if (this.isConnected) {
|
|
127
126
|
this.websocket.send(JSON.stringify({ updates: values }));
|
|
128
127
|
}
|
|
@@ -163,8 +162,8 @@ class CogsConnection {
|
|
|
163
162
|
removeEventListener(type, listener, options) {
|
|
164
163
|
this.eventTarget.removeEventListener(type, listener, options);
|
|
165
164
|
}
|
|
166
|
-
dispatchEvent(
|
|
167
|
-
this.eventTarget.dispatchEvent(
|
|
165
|
+
dispatchEvent(event) {
|
|
166
|
+
this.eventTarget.dispatchEvent(event);
|
|
168
167
|
}
|
|
169
168
|
}
|
|
170
169
|
exports.default = CogsConnection;
|
|
@@ -206,3 +205,50 @@ function websocketParametersFromUrl(url) {
|
|
|
206
205
|
return { path: `/client/${encodeURIComponent(serial)}`, pathParams };
|
|
207
206
|
}
|
|
208
207
|
}
|
|
208
|
+
class CogsConnectionOpenEvent extends Event {
|
|
209
|
+
constructor() {
|
|
210
|
+
super('open');
|
|
211
|
+
this.type = 'open';
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.CogsConnectionOpenEvent = CogsConnectionOpenEvent;
|
|
215
|
+
class CogsConnectionCloseEvent extends Event {
|
|
216
|
+
constructor() {
|
|
217
|
+
super('close');
|
|
218
|
+
this.type = 'close';
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
exports.CogsConnectionCloseEvent = CogsConnectionCloseEvent;
|
|
222
|
+
class CogsMessageEvent extends Event {
|
|
223
|
+
constructor(message) {
|
|
224
|
+
super('message');
|
|
225
|
+
this.message = message;
|
|
226
|
+
this.type = 'message';
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
exports.CogsMessageEvent = CogsMessageEvent;
|
|
230
|
+
class CogsConfigChangedEvent extends Event {
|
|
231
|
+
constructor(config) {
|
|
232
|
+
super('config');
|
|
233
|
+
this.config = config;
|
|
234
|
+
this.type = 'config';
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.CogsConfigChangedEvent = CogsConfigChangedEvent;
|
|
238
|
+
class CogsStateChangedEvent extends Event {
|
|
239
|
+
constructor(state) {
|
|
240
|
+
super('state');
|
|
241
|
+
this.state = state;
|
|
242
|
+
this.type = 'state';
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
exports.CogsStateChangedEvent = CogsStateChangedEvent;
|
|
246
|
+
class CogsIncomingEvent extends Event {
|
|
247
|
+
constructor(name, value) {
|
|
248
|
+
super('event');
|
|
249
|
+
this.name = name;
|
|
250
|
+
this.value = value;
|
|
251
|
+
this.type = 'event';
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
exports.CogsIncomingEvent = CogsIncomingEvent;
|
package/dist/RtspStreamer.js
CHANGED
|
@@ -33,7 +33,7 @@ class RtspStreamer {
|
|
|
33
33
|
});
|
|
34
34
|
// Restart stream on RTCP BYE (stream ended)
|
|
35
35
|
pipeline.rtsp.onRtcp = (rtcp) => {
|
|
36
|
-
if (media_stream_library_browser_1.isRtcpBye(rtcp)) {
|
|
36
|
+
if ((0, media_stream_library_browser_1.isRtcpBye)(rtcp)) {
|
|
37
37
|
console.log('Video stream ended. Restarting.');
|
|
38
38
|
videoElement.pause();
|
|
39
39
|
setTimeout(startPipeline, 0);
|
package/dist/VideoPlayer.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import CogsConnection from './CogsConnection';
|
|
|
2
2
|
import { VideoState } from './types/VideoState';
|
|
3
3
|
import MediaClipStateMessage from './types/MediaClipStateMessage';
|
|
4
4
|
import { MediaObjectFit } from '.';
|
|
5
|
-
|
|
5
|
+
type EventTypes = {
|
|
6
6
|
state: VideoState;
|
|
7
7
|
videoClipState: MediaClipStateMessage;
|
|
8
8
|
};
|
|
@@ -14,7 +14,7 @@ export default class VideoPlayer {
|
|
|
14
14
|
private pendingClip?;
|
|
15
15
|
private parentElement;
|
|
16
16
|
private sinkId;
|
|
17
|
-
constructor(cogsConnection: CogsConnection
|
|
17
|
+
constructor(cogsConnection: CogsConnection<any>, parentElement?: HTMLElement);
|
|
18
18
|
setParentElement(parentElement: HTMLElement): void;
|
|
19
19
|
resetParentElement(): void;
|
|
20
20
|
setGlobalVolume(globalVolume: number): void;
|
package/dist/VideoPlayer.js
CHANGED
|
@@ -15,8 +15,7 @@ class VideoPlayer {
|
|
|
15
15
|
cogsConnection.sendMediaClipState(detail);
|
|
16
16
|
});
|
|
17
17
|
// Listen for video control messages
|
|
18
|
-
cogsConnection.addEventListener('message', (
|
|
19
|
-
const message = event.detail;
|
|
18
|
+
cogsConnection.addEventListener('message', ({ message }) => {
|
|
20
19
|
switch (message.type) {
|
|
21
20
|
case 'media_config_update':
|
|
22
21
|
this.setGlobalVolume(message.globalVolume);
|
|
@@ -261,7 +260,8 @@ class VideoPlayer {
|
|
|
261
260
|
path: this.activeClip.path,
|
|
262
261
|
state: !((_b = this.videoClipPlayers[this.activeClip.path].videoElement) === null || _b === void 0 ? void 0 : _b.paused) ? VideoState_1.ActiveVideoClipState.Playing : VideoState_1.ActiveVideoClipState.Paused,
|
|
263
262
|
loop: (_d = (_c = this.videoClipPlayers[this.activeClip.path].videoElement) === null || _c === void 0 ? void 0 : _c.loop) !== null && _d !== void 0 ? _d : false,
|
|
264
|
-
volume: ((_e = this.videoClipPlayers[this.activeClip.path].videoElement) === null || _e === void 0 ? void 0 : _e.muted)
|
|
263
|
+
volume: ((_e = this.videoClipPlayers[this.activeClip.path].videoElement) === null || _e === void 0 ? void 0 : _e.muted)
|
|
264
|
+
? 0
|
|
265
265
|
: (_g = (_f = this.videoClipPlayers[this.activeClip.path].videoElement) === null || _f === void 0 ? void 0 : _f.volume) !== null && _g !== void 0 ? _g : 0,
|
|
266
266
|
}
|
|
267
267
|
: undefined,
|
|
@@ -284,7 +284,7 @@ class VideoPlayer {
|
|
|
284
284
|
createVideoElement(path, config, { volume }) {
|
|
285
285
|
const videoElement = document.createElement('video');
|
|
286
286
|
videoElement.playsInline = true; // Required for iOS
|
|
287
|
-
videoElement.src = urls_1.assetUrl(path);
|
|
287
|
+
videoElement.src = (0, urls_1.assetUrl)(path);
|
|
288
288
|
videoElement.autoplay = false;
|
|
289
289
|
videoElement.loop = false;
|
|
290
290
|
setVideoElementVolume(videoElement, volume * this.globalVolume);
|