@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.
@@ -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
- element = mediaElement instanceof HTMLAudioElement ? mediaElement : preloader.getElement(clip.file, clip.type);
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
- element = mediaElement instanceof HTMLVideoElement ? mediaElement : preloader.getElement(clip.file, clip.type);
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
- mediaElement.setSinkId(sinkId).catch(() => {
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
- this._elements[file] = { element, type, inUse: true };
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.10",
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.10",
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"