@clockworkdog/cogs-client 3.0.0-alpha.10 → 3.0.0-alpha.11
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/dist/browser/index.mjs +485 -475
- package/dist/browser/index.umd.js +5 -5
- package/dist/state-based/MediaClipManager.js +21 -7
- package/dist/state-based/MediaPreloader.js +8 -1
- package/dist/state-based/SurfaceManager.d.ts +2 -1
- package/dist/state-based/SurfaceManager.js +3 -1
- package/dist/utils/getStateAtTime.js +5 -0
- package/package.json +2 -2
|
@@ -36,8 +36,6 @@ export class MediaClipManager {
|
|
|
36
36
|
_state;
|
|
37
37
|
setState(newState) {
|
|
38
38
|
this._state = newState;
|
|
39
|
-
clearTimeout(this.timeout);
|
|
40
|
-
this.loop();
|
|
41
39
|
}
|
|
42
40
|
timeout;
|
|
43
41
|
loop = async () => {
|
|
@@ -52,21 +50,31 @@ export class MediaClipManager {
|
|
|
52
50
|
}
|
|
53
51
|
export function assertElement(mediaElement, parentElement, clip, constructAssetURL, preloader) {
|
|
54
52
|
let element;
|
|
53
|
+
const assetURL = constructAssetURL(clip.file);
|
|
55
54
|
switch (clip.type) {
|
|
56
55
|
case 'image':
|
|
57
56
|
{
|
|
58
57
|
element = mediaElement instanceof HTMLImageElement ? mediaElement : document.createElement('img');
|
|
59
|
-
const assetURL = constructAssetURL(clip.file);
|
|
60
58
|
if (!element.src.includes(assetURL)) {
|
|
61
59
|
element.src = assetURL;
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
break;
|
|
65
63
|
case 'audio':
|
|
66
|
-
|
|
64
|
+
if (mediaElement instanceof HTMLAudioElement && mediaElement.src.includes(assetURL)) {
|
|
65
|
+
element = mediaElement;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
element = preloader.getElement(clip.file, clip.type);
|
|
69
|
+
}
|
|
67
70
|
break;
|
|
68
71
|
case 'video':
|
|
69
|
-
|
|
72
|
+
if (mediaElement instanceof HTMLVideoElement && mediaElement.src.includes(assetURL)) {
|
|
73
|
+
element = mediaElement;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
element = preloader.getElement(clip.file, clip.type);
|
|
77
|
+
}
|
|
70
78
|
break;
|
|
71
79
|
}
|
|
72
80
|
parentElement.replaceChildren(element);
|
|
@@ -93,9 +101,15 @@ export function assertAudialProperties(mediaElement, properties, sinkId) {
|
|
|
93
101
|
mediaElement.volume = properties.volume;
|
|
94
102
|
}
|
|
95
103
|
if (mediaElement.sinkId !== sinkId) {
|
|
96
|
-
|
|
104
|
+
try {
|
|
105
|
+
mediaElement.setSinkId(sinkId).catch(() => {
|
|
106
|
+
/* Do nothing, will be tried in next loop */
|
|
107
|
+
});
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
109
|
+
}
|
|
110
|
+
catch (_) {
|
|
97
111
|
/* Do nothing, will be tried in next loop */
|
|
98
|
-
}
|
|
112
|
+
}
|
|
99
113
|
}
|
|
100
114
|
}
|
|
101
115
|
const OUTER_TARGET_SYNC_THRESHOLD_MS = 50; // When outside of this range we attempt to sync playback
|
|
@@ -17,7 +17,12 @@ export class MediaPreloader {
|
|
|
17
17
|
// Clean up previous elements
|
|
18
18
|
for (const [filename, media] of Object.entries(this._elements)) {
|
|
19
19
|
if (!(filename in this._state)) {
|
|
20
|
+
if (media.inUse) {
|
|
21
|
+
console.warn(`Failed to clean up element ${media.element.src}`);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
20
24
|
media.element.src = '';
|
|
25
|
+
media.element.load();
|
|
21
26
|
delete this._elements[filename];
|
|
22
27
|
}
|
|
23
28
|
media.inUse = media.element.isConnected;
|
|
@@ -64,7 +69,9 @@ export class MediaPreloader {
|
|
|
64
69
|
else {
|
|
65
70
|
const element = document.createElement(type);
|
|
66
71
|
element.src = this._constructAssetURL(file);
|
|
67
|
-
|
|
72
|
+
if (type === 'video') {
|
|
73
|
+
this._elements[file] = { element, type, inUse: true };
|
|
74
|
+
}
|
|
68
75
|
return element;
|
|
69
76
|
}
|
|
70
77
|
}
|
|
@@ -8,12 +8,13 @@ export declare const DATA_CLIP_ID = "data-clip-id";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class SurfaceManager {
|
|
10
10
|
private constructAssetUrl;
|
|
11
|
+
private getAudioOutput;
|
|
11
12
|
private mediaPreloader;
|
|
12
13
|
private _state;
|
|
13
14
|
setState(newState: MediaSurfaceState): void;
|
|
14
15
|
private _element;
|
|
15
16
|
get element(): HTMLDivElement;
|
|
16
17
|
private resources;
|
|
17
|
-
constructor(constructAssetUrl: (file: string) => string, testState?: MediaSurfaceState, mediaPreloader?: MediaPreloader);
|
|
18
|
+
constructor(constructAssetUrl: (file: string) => string, getAudioOutput: (outputLabel: string) => string, testState?: MediaSurfaceState, mediaPreloader?: MediaPreloader);
|
|
18
19
|
update(): void;
|
|
19
20
|
}
|
|
@@ -8,6 +8,7 @@ export const DATA_CLIP_ID = 'data-clip-id';
|
|
|
8
8
|
*/
|
|
9
9
|
export class SurfaceManager {
|
|
10
10
|
constructAssetUrl;
|
|
11
|
+
getAudioOutput;
|
|
11
12
|
mediaPreloader;
|
|
12
13
|
_state = {};
|
|
13
14
|
setState(newState) {
|
|
@@ -19,8 +20,9 @@ export class SurfaceManager {
|
|
|
19
20
|
return this._element;
|
|
20
21
|
}
|
|
21
22
|
resources = {};
|
|
22
|
-
constructor(constructAssetUrl, testState, mediaPreloader = new MediaPreloader(constructAssetUrl)) {
|
|
23
|
+
constructor(constructAssetUrl, getAudioOutput, testState, mediaPreloader = new MediaPreloader(constructAssetUrl)) {
|
|
23
24
|
this.constructAssetUrl = constructAssetUrl;
|
|
25
|
+
this.getAudioOutput = getAudioOutput;
|
|
24
26
|
this.mediaPreloader = mediaPreloader;
|
|
25
27
|
this._element = document.createElement('div');
|
|
26
28
|
this._element.className = 'surface-manager';
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { defaultAudioOptions, defaultImageOptions, defaultVideoOptions } from '../types/MediaSchema';
|
|
2
2
|
export function getStateAtTime(state, time) {
|
|
3
|
+
//If there are any null keyframes the clip has been terminated
|
|
4
|
+
const nullKeyframes = state.keyframes.filter((kf) => kf[1] === null);
|
|
5
|
+
if (nullKeyframes.some((kf) => kf[0] <= time)) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
3
8
|
switch (state.type) {
|
|
4
9
|
case 'image': {
|
|
5
10
|
const firstTimestamp = state.keyframes[0][0];
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Connect to COGS to build a custom Media Master",
|
|
4
4
|
"author": "Clockwork Dog <info@clockwork.dog>",
|
|
5
5
|
"homepage": "https://github.com/clockwork-dog/cogs-sdk/tree/main/packages/javascript",
|
|
6
|
-
"version": "3.0.0-alpha.
|
|
6
|
+
"version": "3.0.0-alpha.11",
|
|
7
7
|
"keywords": [],
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"cy:generate": "cypress run --e2e"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@clockworkdog/timesync": "^3.0.0-alpha.
|
|
40
|
+
"@clockworkdog/timesync": "^3.0.0-alpha.11",
|
|
41
41
|
"howler": "clockwork-dog/howler.js#fix-looping-clips",
|
|
42
42
|
"reconnecting-websocket": "^4.4.0",
|
|
43
43
|
"zod": "^4.1.13"
|