Skip to content

Commit

Permalink
fix: change streamPhases type to array of tuples, use humanStringify
Browse files Browse the repository at this point in the history
Config streamPhases type change to enable validation of time values as numbers.
And to facilitate working with it down the line in TypeScript.
Use humanStringify() to support showing values like Infinity for getPlayback duration.
Fix LiveryBridgeInteractive to enable selecting quality -1 for ABR.
Have MockPlayerBridge return an error as expected when selecting an illegal quality index.
And tweak some other things for testing purposes.
  • Loading branch information
difosfor committed Feb 9, 2024
1 parent 672ba53 commit 201239a
Show file tree
Hide file tree
Showing 8 changed files with 417 additions and 259 deletions.
424 changes: 275 additions & 149 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"test": "vitest run"
},
"dependencies": {
"lit": "^3.1.1",
"lit": "^3.1.2",
"zod": "^3.22.4"
},
"devDependencies": {
Expand All @@ -50,23 +50,23 @@
"@open-wc/eslint-config": "^12.0.3",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@typescript-eslint/eslint-plugin": "^6.19.1",
"@typescript-eslint/parser": "^6.19.1",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"browserslist-to-esbuild": "^2.1.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-deprecation": "^2.0.0",
"eslint-plugin-tsdoc": "^0.2.17",
"git-branch-is": "^4.0.0",
"happy-dom": "^13.3.4",
"husky": "^9.0.7",
"lint-staged": "^15.2.0",
"happy-dom": "^13.3.8",
"husky": "^9.0.10",
"lint-staged": "^15.2.2",
"markdownlint-cli": "^0.39.0",
"prettier": "^3.2.4",
"prettier": "^3.2.5",
"prettier-plugin-organize-imports": "^3.2.4",
"semantic-release": "^23.0.0",
"semantic-release": "^23.0.2",
"typescript": "^5.3.3",
"vite": "^5.0.12",
"vite": "^5.1.1",
"vite-plugin-dts": "^3.7.2",
"vitest": "^1.2.2"
},
Expand Down
128 changes: 66 additions & 62 deletions src/MockPlayerBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,28 @@ const buildQuality = (index: number) => ({
},
});

const config: Config = {
controls: {
cast: true,
contact: true,
error: true,
fullscreen: true,
mute: true,
pip: true,
play: true,
quality: true,
scrubber: true,
},
customerId: 'dummy-customer-id',
streamPhase: 'PRE',
streamPhases: {
[Date.now() - 3600]: 'LIVE',
[Date.now()]: 'POST',
[Date.now() + 3600]: 'PRE',
},
tenantId: 'dummy-tenant-id',
};

/**
* Mock player bridge for testing purposes; returning dummy values where real values are not available.
* And with dummy support for custom command: `subscribeAuthToken` as used on the test page.
*/
export class MockPlayerBridge extends AbstractPlayerBridge {
config = config;
config: Config = {
controls: {
cast: true,
contact: true,
error: true,
fullscreen: true,
mute: true,
pip: true,
play: true,
quality: true,
scrubber: true,
},
customerId: 'dummy-customer-id',
streamPhase: 'LIVE',
streamPhases: [[Date.now(), 'LIVE']],
tenantId: 'dummy-tenant-id',
};

controlsDisabled = false;

Expand All @@ -63,6 +57,8 @@ export class MockPlayerBridge extends AbstractPlayerBridge {

private playbackMode: PlaybackMode = 'LIVE';

private playbackPosition = 0;

private playbackState: PlaybackState = 'PLAYING';

private playbackStateListeners: ((value: PlaybackState) => void)[] = [];
Expand All @@ -75,8 +71,6 @@ export class MockPlayerBridge extends AbstractPlayerBridge {

private qualitiesListeners: ((value?: Qualities) => void)[] = [];

private seekPosition = 0;

constructor(target?: ConstructorParameters<typeof AbstractPlayerBridge>[0]) {
super(target);

Expand Down Expand Up @@ -109,10 +103,10 @@ export class MockPlayerBridge extends AbstractPlayerBridge {

protected getPlayback() {
return {
buffer: Math.random() * 6,
duration: Math.random() * 6,
latency: Math.random() * 6,
position: this.seekPosition,
buffer: Math.random() * 2,
duration: Infinity,
latency: Math.random() * 3,
position: this.playbackPosition,
};
}

Expand All @@ -125,35 +119,35 @@ export class MockPlayerBridge extends AbstractPlayerBridge {
}

protected pause() {
this.playbackState = 'PAUSED';
this.playbackStateListeners.forEach((listener) =>
listener(this.playbackState),
);
this.setPlaybackState('PAUSED');
}

protected play() {
this.playbackState = 'PLAYING';
this.playbackStateListeners.forEach((listener) =>
listener(this.playbackState),
);
this.setPlaybackState('BUFFERING');
setTimeout(() => {
this.setPlaybackState('PLAYING');
}, 3000);
}

protected reload() {
this.playbackState = 'PLAYING';
this.playbackStateListeners.forEach((listener) =>
listener(this.playbackState),
);
this.play();
}

protected seek(position: number) {
this.playbackState = 'SEEKING';
this.seekPosition = position;
this.playbackStateListeners.forEach((listener) =>
listener(this.playbackState),
);
this.playbackPosition = position;
this.setPlaybackState('SEEKING');
setTimeout(() => {
this.setPlaybackState('PLAYING');
}, 3000);
}

protected selectQuality(index: number) {
if (index === this.qualities.selected) {
return;
}
if (!(index === -1 || !!this.qualities.list[index])) {
throw new Error(`Invalid qualities index: ${index}`);
}
this.qualities.selected = index;
this.qualitiesListeners.forEach((listener) => listener(this.qualities));
}
Expand All @@ -163,11 +157,17 @@ export class MockPlayerBridge extends AbstractPlayerBridge {
}

protected setDisplay(display: DisplayMode) {
if (display === this.display) {
return;
}
this.display = display;
this.displayListeners.forEach((listener) => listener(this.display));
}

protected setMuted(muted: boolean) {
if (muted === this.muted) {
return;
}
this.muted = muted;
this.mutedListeners.forEach((listener) => listener(this.muted));
}
Expand All @@ -177,27 +177,23 @@ export class MockPlayerBridge extends AbstractPlayerBridge {
}

protected subscribeConfig(listener: (value?: Config) => void) {
const changeConfig = (streamPhase: Config['streamPhase']) => {
if (streamPhase !== this.config.streamPhase) {
this.config.streamPhase = streamPhase;
this.config.streamPhases.push([Date.now(), streamPhase]);
}
};

changeConfig('POST');
setTimeout(() => {
this.config.controls = {
...this.config.controls,
cast: false,
scrubber: false,
};
this.config.streamPhase = 'LIVE';
listener(this.config);
}, 1500);
setTimeout(() => {
this.config.controls = {
...this.config.controls,
cast: true,
scrubber: true,
};
changeConfig('PRE');
listener(this.config);
}, 3000);
setTimeout(() => {
this.config.streamPhase = 'POST';
changeConfig('LIVE');
listener(this.config);
}, 4500);
}, 6000);

return this.config;
}

Expand Down Expand Up @@ -248,4 +244,12 @@ export class MockPlayerBridge extends AbstractPlayerBridge {
this.qualitiesListeners.push(listener);
return this.qualities;
}

private setPlaybackState(playbackState: PlaybackState) {
if (playbackState === this.playbackState) {
return;
}
this.playbackState = playbackState;
this.playbackStateListeners.forEach((listener) => listener(playbackState));
}
}
28 changes: 8 additions & 20 deletions src/livery-bridge-interactive/LiveryBridgeInteractive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import type { AbstractPlayerBridge } from '../AbstractPlayerBridge';
import { InteractiveBridge } from '../InteractiveBridge';
import '../livery-bridge-log/LiveryBridgeLog';
import { defineVersionedElement } from '../util/defineVersionedElement';
import { humanStringify } from '../util/humanStringify';
import { validateDisplayMode, type UserFeedback } from '../util/schema';
import { stringify } from '../util/stringify';

declare global {
interface HTMLElementTagNameMap {
Expand Down Expand Up @@ -130,6 +130,10 @@ export class LiveryBridgeInteractive extends LitElement {
align-items: center;
}
pre {
white-space: pre-wrap;
}
.panel {
margin: 5px;
border: 1px solid grey;
Expand Down Expand Up @@ -190,7 +194,7 @@ export class LiveryBridgeInteractive extends LitElement {
this.interactiveBridge.registerInteractiveCommand(
'test',
(arg, handler) => {
const argStr = stringify(arg);
const argStr = humanStringify(arg);
this.interactiveCommandArg = argStr;

window.setTimeout(() => handler(`${argStr}-result-2`), 2000);
Expand Down Expand Up @@ -433,7 +437,7 @@ export class LiveryBridgeInteractive extends LitElement {
}

return (value: unknown) => {
element.innerText = stringify(value, null, ' ');
element.innerText = humanStringify(value, true);
};
}

Expand Down Expand Up @@ -463,21 +467,7 @@ export class LiveryBridgeInteractive extends LitElement {

inputElement.setAttribute('style', 'display: inline-block');
inputElement.setAttribute('type', 'number');
inputElement.setAttribute('min', '0');
inputElement.value = '';

if (methodName === 'selectQuality') {
this.interactiveBridge
?.subscribeQualities(() => null)
.then((qualities) => {
inputElement.setAttribute('max', `${qualities.list.length - 1}`);
})
.catch((e) => {
throw e;
});
} else {
inputElement.removeAttribute('max');
}
break;
}
default: {
Expand All @@ -488,8 +478,6 @@ export class LiveryBridgeInteractive extends LitElement {
if (inputElement) {
inputElement.setAttribute('style', 'display: none');
inputElement.setAttribute('type', 'text');
inputElement.removeAttribute('min');
inputElement.removeAttribute('max');
}
}
}
Expand Down Expand Up @@ -640,7 +628,7 @@ export class LiveryBridgeInteractive extends LitElement {
const arg: unknown = !argStr ? undefined : JSON.parse(argStr);

const setText = (value: unknown) => {
this.playerCommandValue = stringify(value);
this.playerCommandValue = humanStringify(value);
};
this.interactiveBridge
.sendPlayerCommand(name, arg, setText)
Expand Down
6 changes: 3 additions & 3 deletions src/livery-bridge-log/LiveryBridgeLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { css, html, LitElement } from 'lit';
import { property, query } from 'lit/decorators.js';
import type { LiveryBridge } from '../LiveryBridge';
import { defineVersionedElement } from '../util/defineVersionedElement';
import { stringify } from '../util/stringify';
import { humanStringify } from '../util/humanStringify';

declare global {
interface HTMLElementTagNameMap {
Expand Down Expand Up @@ -71,7 +71,7 @@ export class LiveryBridgeLog extends LitElement {
this.removeSpy = this.bridge.spy((message) => {
// eslint-disable-next-line no-console
console.log(message);
this.addMessage(stringify(message, null, ' '));
this.addMessage(humanStringify(message, true));
});
} else {
window.addEventListener('message', this.handleWindowMessage);
Expand Down Expand Up @@ -111,7 +111,7 @@ export class LiveryBridgeLog extends LitElement {
// eslint-disable-next-line no-console
console.log(event.origin, event.data);

this.addMessage(`${event.origin}: ${stringify(event.data, null, ' ')}`);
this.addMessage(`${event.origin}: ${humanStringify(event.data, true)}`);
};
}

Expand Down
Loading

0 comments on commit 201239a

Please sign in to comment.