@mattebox/player-cast 0.2.0 → 0.4.0
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 +24 -5
- package/dist/cast-screen.js +1 -1
- package/dist/cast.d.ts +23 -19
- package/dist/cast.d.ts.map +1 -1
- package/dist/cast.js +61 -3
- package/dist/cast.js.map +1 -1
- package/dist/cdn/mattebox-player-cast.min.js +1 -1
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/defineProperty.js +12 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/objectSpread2.js +25 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/toPrimitive.js +14 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/toPropertyKey.js +9 -0
- package/dist/es2015/_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/typeof.js +11 -0
- package/dist/es2015/cast-screen.js +1 -1
- package/dist/es2015/cast.js +57 -3
- package/dist/es2015/icons.js +4 -4
- package/dist/es2015/index.js +2 -1
- package/dist/es2015/shared.js +2 -2
- package/dist/icons.d.ts +3 -27
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +4 -4
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/shared.js +2 -2
- package/package.json +5 -6
- package/NOTICE +0 -24
package/README.md
CHANGED
|
@@ -43,16 +43,35 @@ the session to the receiver, at the video's current time. When the session
|
|
|
43
43
|
ends, the engine resumes and the video continues from the time where the
|
|
44
44
|
receiver stopped.
|
|
45
45
|
|
|
46
|
-
The receiver plays the URL by itself
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
The receiver plays the URL by itself. A signed URL goes as it is, since it
|
|
47
|
+
is the source's URL. The source's DRM servers go in `customData.mattebox`:
|
|
48
|
+
`licenseUrl`, `licenseUrls` and `certificateUrl`. `@mattebox/cast-receiver`
|
|
49
|
+
reads them.
|
|
50
|
+
|
|
51
|
+
The `castload` event carries the load request before the button sends it.
|
|
52
|
+
Add the license headers there:
|
|
49
53
|
|
|
50
54
|
```ts
|
|
51
|
-
|
|
52
|
-
event.detail.customData = {
|
|
55
|
+
player.addEventListener('castload', (event) => {
|
|
56
|
+
event.detail.customData.mattebox.licenseHeaders = { Authorization: `Bearer ${token}` };
|
|
53
57
|
});
|
|
54
58
|
```
|
|
55
59
|
|
|
60
|
+
When the receiver's license server answers 401 or 403, the receiver asks
|
|
61
|
+
for a new token. The player dispatches `castunauthorized`. Reply with new
|
|
62
|
+
headers, or new servers:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
player.addEventListener('castunauthorized', (event) => {
|
|
66
|
+
event.detail.reply(fetchToken().then((token) => ({
|
|
67
|
+
licenseHeaders: { Authorization: `Bearer ${token}` },
|
|
68
|
+
})));
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The messages go on the `urn:x-cast:ch.mattebox.license` namespace
|
|
73
|
+
(`LICENSE_NAMESPACE`). The receiver waits 10 seconds for a reply.
|
|
74
|
+
|
|
56
75
|
`receiver` on the button names the receiver application. Without it, the
|
|
57
76
|
button uses the Default Media Receiver. With `sdk="none"`, the page loads
|
|
58
77
|
the SDK instead of the button. The
|
package/dist/cast-screen.js
CHANGED
|
@@ -4,7 +4,7 @@ import { icon } from "./icons.js";
|
|
|
4
4
|
import { BUTTON_STYLE, SLIDER_STYLE, describe, el, fill, format, iconSlots, show, style } from "./shared.js";
|
|
5
5
|
import { slider } from "./slider.js";
|
|
6
6
|
//#region src/cast-screen.ts
|
|
7
|
-
const STYLE_CSS = ":host{color:var(--mbx-text);font:400
|
|
7
|
+
const STYLE_CSS = ":host{color:var(--mbx-text);font:400 .9375em / 1.4 var(--mbx-font);text-align:center;background:#000000d9;justify-content:center;align-items:center;padding:1.0667em;display:flex;position:absolute;top:0;bottom:0;left:0;right:0}:host([hidden]){display:none}[part~=box]{flex-direction:column;align-items:center;width:100%;max-width:28em;display:flex}[part~=box]>:not([hidden])~:not([hidden]){margin-top:.8em}[part~=title]{font-size:1.2em;font-weight:600}[part~=row]{justify-content:center;align-items:center;width:100%;display:flex}[part~=row]>:not([hidden])~:not([hidden]){margin-left:.8em}[part~=slider]{flex:1}[part~=time]{font-variant-numeric:tabular-nums;color:var(--mbx-muted);font-size:.8667em}[part~=stop]{height:2.4em;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;background:0 0;border:1px solid;padding:0 1.0667em;font-weight:600}[part~=stop]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=stop]:focus:not(:focus-visible){outline:none}[hidden]{display:none}";
|
|
8
8
|
const STATES = ["play", "pause"];
|
|
9
9
|
const STEP = 5;
|
|
10
10
|
const PAGE = 30;
|
package/dist/cast.d.ts
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chromecast from the page, over Google's Cast sender framework. The SDK is
|
|
3
|
-
* a script the page loads, never a dependency (rule 2): the helper puts it
|
|
4
|
-
* on the page the first time a cast button connects, unless it is already
|
|
5
|
-
* there or the button says `sdk="none"`. Its context is one per page by
|
|
6
|
-
* Google's design, so the receiver id the first button gives is the one
|
|
7
|
-
* the page keeps.
|
|
8
|
-
*
|
|
9
|
-
* One `Cast` per player. It owns the handoff and nothing on the video is
|
|
10
|
-
* wrapped (rule 3): on start it pauses the video, freezes the engine, and
|
|
11
|
-
* sends the session's source to the receiver at the video's time; on end
|
|
12
|
-
* it thaws the engine, seeks the video to the receiver's last time, and
|
|
13
|
-
* plays if the receiver was playing. The cast screen drives the receiver
|
|
14
|
-
* through the SDK's remote player meanwhile.
|
|
15
|
-
*
|
|
16
|
-
* The receiver plays the URL by itself, so DRM and signed URLs are the
|
|
17
|
-
* page's to arrange: the button dispatches `castload` with the request
|
|
18
|
-
* before it goes out, and the page sets `customData` or cancels.
|
|
19
|
-
*/
|
|
20
1
|
import type { PlayerHost } from './host.js';
|
|
2
|
+
/** The custom namespace a receiver asks the sender for a new license token on. */
|
|
3
|
+
export declare const LICENSE_NAMESPACE = "urn:x-cast:ch.mattebox.license";
|
|
4
|
+
/** What the page replies to `castunauthorized`: new license headers or servers for the receiver. */
|
|
5
|
+
export interface LicenseReply {
|
|
6
|
+
readonly licenseHeaders?: Readonly<Record<string, string>>;
|
|
7
|
+
readonly licenseUrl?: string;
|
|
8
|
+
readonly licenseUrls?: Readonly<Record<string, string>>;
|
|
9
|
+
}
|
|
10
|
+
/** `castunauthorized`'s `detail`: the receiver's license server answered 401 or 403. */
|
|
11
|
+
export interface UnauthorizedDetail {
|
|
12
|
+
readonly keySystem: string;
|
|
13
|
+
readonly status: number;
|
|
14
|
+
/** Sends the new token to the receiver. Call it once, with the reply or a promise of it. */
|
|
15
|
+
reply(reply: LicenseReply | Promise<LicenseReply>): void;
|
|
16
|
+
}
|
|
17
|
+
/** `customData.mattebox`: the source's DRM servers, as `@mattebox/cast-receiver` reads them. */
|
|
18
|
+
export interface MatteboxCustomData {
|
|
19
|
+
licenseUrl?: string;
|
|
20
|
+
licenseUrls?: Readonly<Record<string, string>>;
|
|
21
|
+
certificateUrl?: string;
|
|
22
|
+
/** Headers for the license requests. The player has none of its own; a `castload` listener adds them. */
|
|
23
|
+
licenseHeaders?: Record<string, string>;
|
|
24
|
+
}
|
|
21
25
|
/** What the receiver plays. The page sees it as `castload`'s `detail`. */
|
|
22
26
|
export interface MediaInfo {
|
|
23
27
|
contentId: string;
|
package/dist/cast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cast.d.ts","sourceRoot":"","sources":["../src/cast.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cast.d.ts","sourceRoot":"","sources":["../src/cast.ts"],"names":[],"mappings":"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"}
|
package/dist/cast.js
CHANGED
|
@@ -4,6 +4,8 @@ function live(engine) {
|
|
|
4
4
|
const api = engine?.live;
|
|
5
5
|
return api !== void 0 && api.edge !== null;
|
|
6
6
|
}
|
|
7
|
+
/** The custom namespace a receiver asks the sender for a new license token on. */
|
|
8
|
+
const LICENSE_NAMESPACE = "urn:x-cast:ch.mattebox.license";
|
|
7
9
|
/** The Default Media Receiver: Google's player, which plays HLS and DASH by itself. */
|
|
8
10
|
const DEFAULT_RECEIVER = "CC1AD845";
|
|
9
11
|
const SDK_URL = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1";
|
|
@@ -99,7 +101,7 @@ function onSession(fw, ctx, state) {
|
|
|
99
101
|
const found = [...connected].find((cast) => cast.plays(playing));
|
|
100
102
|
if (found !== void 0 && owner === null) {
|
|
101
103
|
owner = found;
|
|
102
|
-
found.adopt();
|
|
104
|
+
found.adopt(ctx);
|
|
103
105
|
}
|
|
104
106
|
} else if (state === states.SESSION_ENDED || state === states.SESSION_START_FAILED) {
|
|
105
107
|
const ended = owner;
|
|
@@ -121,6 +123,7 @@ var CastOf = class {
|
|
|
121
123
|
this.pending = false;
|
|
122
124
|
this.casting = false;
|
|
123
125
|
this.handoff = null;
|
|
126
|
+
this.listening = null;
|
|
124
127
|
}
|
|
125
128
|
connect(receiver, sdk) {
|
|
126
129
|
connected.add(this);
|
|
@@ -200,6 +203,7 @@ var CastOf = class {
|
|
|
200
203
|
if (session === null) return;
|
|
201
204
|
const request = this.request(session.source, time, autoplay);
|
|
202
205
|
if (request === null) return;
|
|
206
|
+
this.listen(ctx.getCurrentSession());
|
|
203
207
|
const event = new CustomEvent("castload", {
|
|
204
208
|
detail: request,
|
|
205
209
|
bubbles: true,
|
|
@@ -210,8 +214,55 @@ var CastOf = class {
|
|
|
210
214
|
ctx.getCurrentSession()?.loadMedia(request).catch(() => {});
|
|
211
215
|
}
|
|
212
216
|
/** A session Chrome rejoined, already playing this player's source. */
|
|
213
|
-
adopt() {
|
|
217
|
+
adopt(ctx) {
|
|
214
218
|
this.freeze();
|
|
219
|
+
this.listen(ctx.getCurrentSession());
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Answers the receiver's token requests for this session: a
|
|
223
|
+
* `castunauthorized` event on the player, and the page's reply sent back.
|
|
224
|
+
*/
|
|
225
|
+
listen(session) {
|
|
226
|
+
this.unlisten();
|
|
227
|
+
if (session === null) return;
|
|
228
|
+
const fn = (_namespace, message) => {
|
|
229
|
+
let data;
|
|
230
|
+
try {
|
|
231
|
+
data = JSON.parse(message);
|
|
232
|
+
} catch {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (data.type !== "unauthorized") return;
|
|
236
|
+
const id = data.id;
|
|
237
|
+
let replied = false;
|
|
238
|
+
const detail = {
|
|
239
|
+
keySystem: typeof data.keySystem === "string" ? data.keySystem : "",
|
|
240
|
+
status: typeof data.status === "number" ? data.status : 0,
|
|
241
|
+
reply(reply) {
|
|
242
|
+
if (replied) return;
|
|
243
|
+
replied = true;
|
|
244
|
+
Promise.resolve(reply).then((answer) => session.sendMessage(LICENSE_NAMESPACE, {
|
|
245
|
+
type: "license",
|
|
246
|
+
id,
|
|
247
|
+
...answer
|
|
248
|
+
})).catch(() => {});
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
this.player.dispatchEvent(new CustomEvent("castunauthorized", {
|
|
252
|
+
detail,
|
|
253
|
+
bubbles: true
|
|
254
|
+
}));
|
|
255
|
+
};
|
|
256
|
+
session.addMessageListener(LICENSE_NAMESPACE, fn);
|
|
257
|
+
this.listening = {
|
|
258
|
+
session,
|
|
259
|
+
fn
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
unlisten() {
|
|
263
|
+
const held = this.listening;
|
|
264
|
+
this.listening = null;
|
|
265
|
+
held?.session.removeMessageListener(LICENSE_NAMESPACE, held.fn);
|
|
215
266
|
}
|
|
216
267
|
freeze() {
|
|
217
268
|
const engine = this.player.engine;
|
|
@@ -225,6 +276,7 @@ var CastOf = class {
|
|
|
225
276
|
/** The session ended: give the video back where the receiver left it. */
|
|
226
277
|
end(cleanly) {
|
|
227
278
|
this.pending = false;
|
|
279
|
+
this.unlisten();
|
|
228
280
|
if (!this.casting) return;
|
|
229
281
|
this.casting = false;
|
|
230
282
|
const handoff = this.handoff;
|
|
@@ -265,6 +317,12 @@ var CastOf = class {
|
|
|
265
317
|
const request = new media.LoadRequest(info);
|
|
266
318
|
request.currentTime = time;
|
|
267
319
|
request.autoplay = autoplay;
|
|
320
|
+
const drm = source.drm;
|
|
321
|
+
if (drm !== void 0) request.customData = { mattebox: {
|
|
322
|
+
...drm.licenseUrl === void 0 ? {} : { licenseUrl: drm.licenseUrl },
|
|
323
|
+
...drm.licenseUrls === void 0 ? {} : { licenseUrls: drm.licenseUrls },
|
|
324
|
+
...drm.certificateUrl === void 0 ? {} : { certificateUrl: drm.certificateUrl }
|
|
325
|
+
} };
|
|
268
326
|
return request;
|
|
269
327
|
}
|
|
270
328
|
};
|
|
@@ -285,6 +343,6 @@ function cast(player) {
|
|
|
285
343
|
return held;
|
|
286
344
|
}
|
|
287
345
|
//#endregion
|
|
288
|
-
export { cast };
|
|
346
|
+
export { LICENSE_NAMESPACE, cast };
|
|
289
347
|
|
|
290
348
|
//# sourceMappingURL=cast.js.map
|
package/dist/cast.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cast.js","names":[],"sources":["../src/cast.ts"],"sourcesContent":["/**\n * Chromecast from the page, over Google's Cast sender framework. The SDK is\n * a script the page loads, never a dependency (rule 2): the helper puts it\n * on the page the first time a cast button connects, unless it is already\n * there or the button says `sdk=\"none\"`. Its context is one per page by\n * Google's design, so the receiver id the first button gives is the one\n * the page keeps.\n *\n * One `Cast` per player. It owns the handoff and nothing on the video is\n * wrapped (rule 3): on start it pauses the video, freezes the engine, and\n * sends the session's source to the receiver at the video's time; on end\n * it thaws the engine, seeks the video to the receiver's last time, and\n * plays if the receiver was playing. The cast screen drives the receiver\n * through the SDK's remote player meanwhile.\n *\n * The receiver plays the URL by itself, so DRM and signed URLs are the\n * page's to arrange: the button dispatches `castload` with the request\n * before it goes out, and the page sets `customData` or cancels.\n */\nimport type { PlayerHost } from './host.js';\n\n/** Whether the session is live: the engine's `live` namespace, once it has an edge. */\nfunction live(engine: PlayerHost['engine']): boolean {\n const api = (engine as { live?: { edge: number | null } } | null)?.live;\n return api !== undefined && api.edge !== null;\n}\n\n// The slice of the sender SDK the helper reads. No `@types/chromecast`:\n// the SDK is not a dependency, and these names are what the page's script\n// puts on `window.cast.framework` and `window.chrome.cast`.\n\ninterface SdkEvent {\n readonly castState?: string;\n readonly sessionState?: string;\n}\n\ninterface SdkDevice {\n readonly friendlyName: string;\n}\n\ninterface SdkMediaSession {\n readonly media?: { readonly contentId?: string } | null;\n}\n\ninterface SdkSession {\n getCastDevice(): SdkDevice;\n getMediaSession(): SdkMediaSession | null;\n loadMedia(request: LoadRequest): Promise<unknown>;\n}\n\ninterface SdkContext {\n setOptions(options: { receiverApplicationId: string; autoJoinPolicy: string }): void;\n addEventListener(type: string, fn: (event: SdkEvent) => void): void;\n getCastState(): string;\n getCurrentSession(): SdkSession | null;\n requestSession(): Promise<unknown>;\n endCurrentSession(stopCasting: boolean): void;\n}\n\ninterface SdkRemotePlayer {\n isConnected: boolean;\n isMediaLoaded: boolean;\n isPaused: boolean;\n currentTime: number;\n duration: number;\n playerState: string | null;\n}\n\ninterface SdkRemoteController {\n addEventListener(type: string, fn: () => void): void;\n playOrPause(): void;\n seek(): void;\n stop(): void;\n}\n\n/** What the receiver plays. The page sees it as `castload`'s `detail`. */\nexport interface MediaInfo {\n contentId: string;\n contentType: string;\n streamType: string;\n tracks: Track[] | null;\n hlsSegmentFormat?: string;\n hlsVideoSegmentFormat?: string;\n}\n\nexport interface Track {\n trackContentId: string;\n trackContentType: string;\n subtype: string;\n name: string;\n language: string;\n}\n\nexport interface LoadRequest {\n media: MediaInfo;\n currentTime: number;\n autoplay: boolean;\n customData: unknown;\n}\n\ninterface Framework {\n CastContext: { getInstance(): SdkContext };\n RemotePlayer: new () => SdkRemotePlayer;\n RemotePlayerController: new (player: SdkRemotePlayer) => SdkRemoteController;\n CastContextEventType: { CAST_STATE_CHANGED: string; SESSION_STATE_CHANGED: string };\n CastState: { NO_DEVICES_AVAILABLE: string; CONNECTING: string; CONNECTED: string };\n SessionState: {\n SESSION_STARTED: string;\n SESSION_RESUMED: string;\n SESSION_ENDED: string;\n SESSION_START_FAILED: string;\n };\n RemotePlayerEventType: { ANY_CHANGE: string };\n}\n\ninterface ChromeCast {\n AutoJoinPolicy: { ORIGIN_SCOPED: string };\n media: {\n MediaInfo: new (contentId: string, contentType: string) => MediaInfo;\n LoadRequest: new (media: MediaInfo) => LoadRequest;\n Track: new (trackId: number, type: string) => Track;\n TrackType: { TEXT: string };\n TextTrackType: { SUBTITLES: string; CAPTIONS: string };\n StreamType: { BUFFERED: string; LIVE: string };\n };\n}\n\ninterface Globals {\n cast?: { framework?: Framework };\n chrome?: { cast?: ChromeCast };\n __onGCastApiAvailable?: (available: boolean) => void;\n}\n\n/** The Default Media Receiver: Google's player, which plays HLS and DASH by itself. */\nconst DEFAULT_RECEIVER = 'CC1AD845';\nconst SDK_URL = 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1';\n\nexport type CastState = 'unavailable' | 'idle' | 'connecting' | 'casting';\n\n/** What the cast screen shows of the receiver. */\nexport interface Remote {\n readonly loaded: boolean;\n readonly paused: boolean;\n readonly time: number;\n /** Infinity for a live stream, the way the video reports it. */\n readonly duration: number;\n}\n\nexport interface Cast {\n /**\n * Puts the SDK on the page unless `sdk` is `none` or it is already there,\n * and sets the context up with `receiver`, or the default receiver. The\n * first call on the page decides both; a later different receiver is an\n * error on the console, not a second context.\n */\n connect(receiver: string | null, sdk: string | null): void;\n /** The button left the player: a rejoined session no longer looks here. */\n disconnect(): void;\n state(): CastState;\n /** The receiver's name while casting, or null. */\n device(): string | null;\n remote(): Remote;\n /** Opens the device picker. `castload` goes out on `target` once a session starts. */\n start(target: HTMLElement): void;\n /** Ends the session and stops the receiver. */\n stop(): void;\n playPause(): void;\n seek(time: number): void;\n /** Runs `fn` on every change: devices, session, and the receiver's playback. Returns the unsubscribe. */\n watch(fn: () => void): () => void;\n}\n\n/** What the video is doing at the start of a cast, to give back at the end. */\ninterface Handoff {\n readonly live: boolean;\n}\n\n// The page-wide part: one SDK, one context, one remote player. Held in the\n// module because the SDK holds them in the window.\n\nlet framework: Promise<Framework | null> | null = null;\nlet configured: string | null = null;\nlet remotePlayer: SdkRemotePlayer | null = null;\nlet remoteController: SdkRemoteController | null = null;\nconst watchers = new Set<() => void>();\n/** The player whose session this is, so two players on a page do not both take a session. */\nlet owner: CastOf | null = null;\n/** The receiver's last known playback, read while it reports and kept once it stops. */\nconst NOTHING: Remote = { loaded: false, paused: true, time: 0, duration: Number.NaN };\nlet last: Remote = NOTHING;\n\nfunction globals(): Globals {\n return globalThis as Globals;\n}\n\nfunction notify(): void {\n for (const fn of [...watchers]) fn();\n}\n\n/**\n * The framework, once the page has it. Resolves null where the SDK never\n * arrives: a browser without Cast, a page whose CSP refused the script, or\n * `sdk=\"none\"` with no script of the page's own.\n */\nfunction load(sdk: string | null): Promise<Framework | null> {\n if (framework !== null) return framework;\n const held = globals();\n if (held.cast?.framework !== undefined) {\n framework = Promise.resolve(held.cast.framework);\n return framework;\n }\n // The SDK is Chromium's. Elsewhere the script only reports that it is\n // unavailable, so it is not fetched.\n if (!('chrome' in held)) {\n framework = Promise.resolve(null);\n return framework;\n }\n framework = new Promise((resolve) => {\n const previous = held.__onGCastApiAvailable;\n // The SDK calls this once it is in, on its own script or the page's.\n held.__onGCastApiAvailable = (available: boolean): void => {\n previous?.(available);\n resolve(available ? (globals().cast?.framework ?? null) : null);\n };\n if (sdk === 'none') return;\n const script = document.createElement('script');\n script.src = SDK_URL;\n script.async = true;\n script.addEventListener('error', () => resolve(null));\n document.head.append(script);\n });\n return framework;\n}\n\n/** The context, set up once per page. */\nfunction context(fw: Framework, receiver: string | null): SdkContext {\n const ctx = fw.CastContext.getInstance();\n const wanted = receiver ?? DEFAULT_RECEIVER;\n if (configured === null) {\n const policy = globals().chrome?.cast?.AutoJoinPolicy.ORIGIN_SCOPED ?? 'origin_scoped';\n ctx.setOptions({ receiverApplicationId: wanted, autoJoinPolicy: policy });\n configured = wanted;\n ctx.addEventListener(fw.CastContextEventType.CAST_STATE_CHANGED, notify);\n ctx.addEventListener(fw.CastContextEventType.SESSION_STATE_CHANGED, (event) => {\n onSession(fw, ctx, event.sessionState ?? '');\n });\n remotePlayer = new fw.RemotePlayer();\n remoteController = new fw.RemotePlayerController(remotePlayer);\n remoteController.addEventListener(fw.RemotePlayerEventType.ANY_CHANGE, () => {\n const remote = remotePlayer;\n if (remote?.isConnected === true && remote.isMediaLoaded) {\n last = {\n loaded: true,\n paused: remote.isPaused,\n time: remote.currentTime,\n duration: remote.duration > 0 ? remote.duration : Number.POSITIVE_INFINITY,\n };\n }\n notify();\n });\n } else if (receiver !== null && receiver !== configured) {\n console.error(`mattebox-player: the Cast context already uses receiver ${configured}`);\n }\n return ctx;\n}\n\nfunction onSession(fw: Framework, ctx: SdkContext, state: string): void {\n const states = fw.SessionState;\n if (state === states.SESSION_STARTED && owner !== null && owner.pending) {\n // A new session has loaded nothing yet, whatever the last one played.\n last = NOTHING;\n owner.begin(ctx);\n } else if (state === states.SESSION_RESUMED) {\n // Chrome rejoins a session of this origin on load. It is this player's\n // when the receiver plays what the player has.\n const playing = ctx.getCurrentSession()?.getMediaSession()?.media?.contentId;\n const found = [...connected].find((cast) => cast.plays(playing));\n if (found !== undefined && owner === null) {\n owner = found;\n found.adopt();\n }\n } else if (state === states.SESSION_ENDED || state === states.SESSION_START_FAILED) {\n const ended = owner;\n owner = null;\n ended?.end(state === states.SESSION_ENDED);\n }\n notify();\n}\n\n/** One per player, found again by its button and its screen. Weak, so a player that leaves is not held. */\nconst players = new WeakMap<PlayerHost, CastOf>();\n/** The players with a cast button attached, for a session Chrome rejoins on load. */\nconst connected = new Set<CastOf>();\n\nclass CastOf implements Cast {\n declare private readonly player: PlayerHost;\n declare private target: HTMLElement | null;\n declare private ctx: SdkContext | null;\n declare private fw: Framework | null;\n /** This player asked for a session and waits for it to start. */\n declare pending: boolean;\n declare private casting: boolean;\n declare private handoff: Handoff | null;\n\n constructor(player: PlayerHost) {\n this.player = player;\n this.target = null;\n this.ctx = null;\n this.fw = null;\n this.pending = false;\n this.casting = false;\n this.handoff = null;\n }\n\n connect(receiver: string | null, sdk: string | null): void {\n connected.add(this);\n void load(sdk).then((fw) => {\n if (fw === null) return;\n this.fw = fw;\n this.ctx = context(fw, receiver);\n notify();\n });\n }\n\n disconnect(): void {\n connected.delete(this);\n }\n\n state(): CastState {\n const ctx = this.ctx;\n const fw = this.fw;\n if (ctx === null || fw === null) return 'unavailable';\n if (this.casting) return 'casting';\n const cast = ctx.getCastState();\n if (cast === fw.CastState.NO_DEVICES_AVAILABLE) return 'unavailable';\n if (cast === fw.CastState.CONNECTING || this.pending) return 'connecting';\n return 'idle';\n }\n\n device(): string | null {\n if (!this.casting) return null;\n return this.ctx?.getCurrentSession()?.getCastDevice().friendlyName ?? null;\n }\n\n remote(): Remote {\n return last;\n }\n\n start(target: HTMLElement): void {\n const ctx = this.ctx;\n if (ctx === null || this.casting) return;\n // Another player on the page holds the session. The SDK has one, so\n // this click ends it, the way Chrome's own dialog offers to.\n if (owner !== null && owner !== this) {\n ctx.endCurrentSession(true);\n return;\n }\n this.target = target;\n this.pending = true;\n owner = this;\n notify();\n // Rejected when the viewer closes the picker; SESSION_START_FAILED\n // does not fire for that, so the wait ends here.\n ctx.requestSession().catch(() => {\n if (owner === this) owner = null;\n this.pending = false;\n notify();\n });\n }\n\n stop(): void {\n if (this.casting) this.ctx?.endCurrentSession(true);\n }\n\n playPause(): void {\n if (this.casting) remoteController?.playOrPause();\n }\n\n seek(time: number): void {\n if (!this.casting || remotePlayer === null) return;\n remotePlayer.currentTime = time;\n remoteController?.seek();\n }\n\n watch(fn: () => void): () => void {\n watchers.add(fn);\n return () => {\n watchers.delete(fn);\n };\n }\n\n /** Whether this player's session plays `url`. */\n plays(url: string | undefined): boolean {\n return url !== undefined && this.player.player?.session?.source.url === url;\n }\n\n /** A session started for this player: freeze the picture and send the source. */\n begin(ctx: SdkContext): void {\n this.pending = false;\n const session = this.player.player?.session ?? null;\n const video = this.player.video;\n const time = video.currentTime;\n const autoplay = !video.paused;\n this.freeze();\n if (session === null) return;\n const request = this.request(session.source, time, autoplay);\n if (request === null) return;\n const event = new CustomEvent<LoadRequest>('castload', {\n detail: request,\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n if (this.target?.dispatchEvent(event) === false) return;\n void ctx\n .getCurrentSession()\n ?.loadMedia(request)\n .catch(() => {\n // The receiver refused the media. The session stays, so the viewer\n // can stop it; the screen shows no time.\n });\n }\n\n /** A session Chrome rejoined, already playing this player's source. */\n adopt(): void {\n this.freeze();\n }\n\n private freeze(): void {\n const engine = this.player.engine;\n this.handoff = { live: live(engine) };\n this.player.video.pause();\n // The engine keeps its buffers and makes no request while the receiver\n // plays (engine guide 01, suspend and resume).\n engine?.suspend();\n this.casting = true;\n this.player.toggleAttribute('casting', true);\n notify();\n }\n\n /** The session ended: give the video back where the receiver left it. */\n end(cleanly: boolean): void {\n this.pending = false;\n if (!this.casting) return;\n this.casting = false;\n const handoff = this.handoff;\n this.handoff = null;\n const video = this.player.video;\n const engine = this.player.engine;\n engine?.resume();\n this.player.removeAttribute('casting');\n if (!cleanly || !last.loaded) return;\n // Live rejoins at the edge on its own; the receiver's time is on the\n // receiver's own timeline and means nothing here.\n if (handoff?.live !== true && Number.isFinite(last.time)) video.currentTime = last.time;\n if (!last.paused) video.play().catch(() => undefined);\n }\n\n /** The load request: the source, the time, the stream type, and the video's own text tracks. */\n private request(\n source: { readonly url: string; readonly type?: string },\n time: number,\n autoplay: boolean,\n ): LoadRequest | null {\n const media = globals().chrome?.cast?.media;\n if (media === undefined) return null;\n const engine = this.player.engine;\n const type = source.type ?? '';\n const info = new media.MediaInfo(source.url, type);\n info.streamType = live(engine) ? media.StreamType.LIVE : media.StreamType.BUFFERED;\n if (/mpegurl/i.test(type)) {\n // The receiver assumes MPEG-TS segments for HLS unless told. The\n // engine's presentation says which the stream has; a native session\n // has none, and CMAF is the assumption there.\n const ts = tsSegments(engine);\n info.hlsSegmentFormat = ts ? 'ts' : 'fmp4';\n info.hlsVideoSegmentFormat = ts ? 'mpeg2_ts' : 'fmp4';\n }\n const tracks: Track[] = [];\n for (const node of this.player.video.querySelectorAll('track[src]')) {\n const track = node as HTMLTrackElement;\n if (track.kind !== 'subtitles' && track.kind !== 'captions') continue;\n const out = new media.Track(tracks.length + 1, media.TrackType.TEXT);\n out.trackContentId = track.src;\n out.trackContentType = 'text/vtt';\n out.subtype =\n track.kind === 'captions' ? media.TextTrackType.CAPTIONS : media.TextTrackType.SUBTITLES;\n out.name = track.label;\n out.language = track.srclang;\n tracks.push(out);\n }\n info.tracks = tracks.length > 0 ? tracks : null;\n const request = new media.LoadRequest(info);\n request.currentTime = time;\n request.autoplay = autoplay;\n return request;\n }\n}\n\n/** Whether the engine's presentation carries MPEG-TS renditions. */\nfunction tsSegments(engine: PlayerHost['engine']): boolean {\n const presentation = engine?.stats.snapshot().presentation;\n if (presentation === null || presentation === undefined) return false;\n for (const period of presentation.periods) {\n for (const track of period.tracks) {\n for (const rendition of track.renditions) {\n if (/mp2t/i.test(rendition.mimeType)) return true;\n }\n }\n }\n return false;\n}\n\n/** The player's Cast, one per player, shared by its cast button and cast screen. */\nexport function cast(player: PlayerHost): Cast {\n let held = players.get(player);\n if (held === undefined) {\n held = new CastOf(player);\n players.set(player, held);\n }\n return held;\n}\n"],"mappings":";;AAsBA,SAAS,KAAK,QAAuC;CACnD,MAAM,MAAO,QAAsD;CACnE,OAAO,QAAQ,KAAA,KAAa,IAAI,SAAS;AAC3C;;AA6GA,MAAM,mBAAmB;AACzB,MAAM,UAAU;AA6ChB,IAAI,YAA8C;AAClD,IAAI,aAA4B;AAChC,IAAI,eAAuC;AAC3C,IAAI,mBAA+C;AACnD,MAAM,2BAAW,IAAI,IAAgB;;AAErC,IAAI,QAAuB;;AAE3B,MAAM,UAAkB;CAAE,QAAQ;CAAO,QAAQ;CAAM,MAAM;CAAG,UAAU;AAAW;AACrF,IAAI,OAAe;AAEnB,SAAS,UAAmB;CAC1B,OAAO;AACT;AAEA,SAAS,SAAe;CACtB,KAAK,MAAM,MAAM,CAAC,GAAG,QAAQ,GAAG,GAAG;AACrC;;;;;;AAOA,SAAS,KAAK,KAA+C;CAC3D,IAAI,cAAc,MAAM,OAAO;CAC/B,MAAM,OAAO,QAAQ;CACrB,IAAI,KAAK,MAAM,cAAc,KAAA,GAAW;EACtC,YAAY,QAAQ,QAAQ,KAAK,KAAK,SAAS;EAC/C,OAAO;CACT;CAGA,IAAI,EAAE,YAAY,OAAO;EACvB,YAAY,QAAQ,QAAQ,IAAI;EAChC,OAAO;CACT;CACA,YAAY,IAAI,SAAS,YAAY;EACnC,MAAM,WAAW,KAAK;EAEtB,KAAK,yBAAyB,cAA6B;GACzD,WAAW,SAAS;GACpB,QAAQ,YAAa,QAAQ,CAAC,CAAC,MAAM,aAAa,OAAQ,IAAI;EAChE;EACA,IAAI,QAAQ,QAAQ;EACpB,MAAM,SAAS,SAAS,cAAc,QAAQ;EAC9C,OAAO,MAAM;EACb,OAAO,QAAQ;EACf,OAAO,iBAAiB,eAAe,QAAQ,IAAI,CAAC;EACpD,SAAS,KAAK,OAAO,MAAM;CAC7B,CAAC;CACD,OAAO;AACT;;AAGA,SAAS,QAAQ,IAAe,UAAqC;CACnE,MAAM,MAAM,GAAG,YAAY,YAAY;CACvC,MAAM,SAAS,YAAY;CAC3B,IAAI,eAAe,MAAM;EACvB,MAAM,SAAS,QAAQ,CAAC,CAAC,QAAQ,MAAM,eAAe,iBAAiB;EACvE,IAAI,WAAW;GAAE,uBAAuB;GAAQ,gBAAgB;EAAO,CAAC;EACxE,aAAa;EACb,IAAI,iBAAiB,GAAG,qBAAqB,oBAAoB,MAAM;EACvE,IAAI,iBAAiB,GAAG,qBAAqB,wBAAwB,UAAU;GAC7E,UAAU,IAAI,KAAK,MAAM,gBAAgB,EAAE;EAC7C,CAAC;EACD,eAAe,IAAI,GAAG,aAAa;EACnC,mBAAmB,IAAI,GAAG,uBAAuB,YAAY;EAC7D,iBAAiB,iBAAiB,GAAG,sBAAsB,kBAAkB;GAC3E,MAAM,SAAS;GACf,IAAI,QAAQ,gBAAgB,QAAQ,OAAO,eACzC,OAAO;IACL,QAAQ;IACR,QAAQ,OAAO;IACf,MAAM,OAAO;IACb,UAAU,OAAO,WAAW,IAAI,OAAO,WAAW,OAAO;GAC3D;GAEF,OAAO;EACT,CAAC;CACH,OAAO,IAAI,aAAa,QAAQ,aAAa,YAC3C,QAAQ,MAAM,2DAA2D,YAAY;CAEvF,OAAO;AACT;AAEA,SAAS,UAAU,IAAe,KAAiB,OAAqB;CACtE,MAAM,SAAS,GAAG;CAClB,IAAI,UAAU,OAAO,mBAAmB,UAAU,QAAQ,MAAM,SAAS;EAEvE,OAAO;EACP,MAAM,MAAM,GAAG;CACjB,OAAO,IAAI,UAAU,OAAO,iBAAiB;EAG3C,MAAM,UAAU,IAAI,kBAAkB,CAAC,EAAE,gBAAgB,CAAC,EAAE,OAAO;EACnE,MAAM,QAAQ,CAAC,GAAG,SAAS,CAAC,CAAC,MAAM,SAAS,KAAK,MAAM,OAAO,CAAC;EAC/D,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM;GACzC,QAAQ;GACR,MAAM,MAAM;EACd;CACF,OAAO,IAAI,UAAU,OAAO,iBAAiB,UAAU,OAAO,sBAAsB;EAClF,MAAM,QAAQ;EACd,QAAQ;EACR,OAAO,IAAI,UAAU,OAAO,aAAa;CAC3C;CACA,OAAO;AACT;;AAGA,MAAM,0BAAU,IAAI,QAA4B;;AAEhD,MAAM,4BAAY,IAAI,IAAY;AAElC,IAAM,SAAN,MAA6B;CAU3B,YAAY,QAAoB;EAC9B,KAAK,SAAS;EACd,KAAK,SAAS;EACd,KAAK,MAAM;EACX,KAAK,KAAK;EACV,KAAK,UAAU;EACf,KAAK,UAAU;EACf,KAAK,UAAU;CACjB;CAEA,QAAQ,UAAyB,KAA0B;EACzD,UAAU,IAAI,IAAI;EAClB,KAAU,GAAG,CAAC,CAAC,MAAM,OAAO;GAC1B,IAAI,OAAO,MAAM;GACjB,KAAK,KAAK;GACV,KAAK,MAAM,QAAQ,IAAI,QAAQ;GAC/B,OAAO;EACT,CAAC;CACH;CAEA,aAAmB;EACjB,UAAU,OAAO,IAAI;CACvB;CAEA,QAAmB;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,KAAK,KAAK;EAChB,IAAI,QAAQ,QAAQ,OAAO,MAAM,OAAO;EACxC,IAAI,KAAK,SAAS,OAAO;EACzB,MAAM,OAAO,IAAI,aAAa;EAC9B,IAAI,SAAS,GAAG,UAAU,sBAAsB,OAAO;EACvD,IAAI,SAAS,GAAG,UAAU,cAAc,KAAK,SAAS,OAAO;EAC7D,OAAO;CACT;CAEA,SAAwB;EACtB,IAAI,CAAC,KAAK,SAAS,OAAO;EAC1B,OAAO,KAAK,KAAK,kBAAkB,CAAC,EAAE,cAAc,CAAC,CAAC,gBAAgB;CACxE;CAEA,SAAiB;EACf,OAAO;CACT;CAEA,MAAM,QAA2B;EAC/B,MAAM,MAAM,KAAK;EACjB,IAAI,QAAQ,QAAQ,KAAK,SAAS;EAGlC,IAAI,UAAU,QAAQ,UAAU,MAAM;GACpC,IAAI,kBAAkB,IAAI;GAC1B;EACF;EACA,KAAK,SAAS;EACd,KAAK,UAAU;EACf,QAAQ;EACR,OAAO;EAGP,IAAI,eAAe,CAAC,CAAC,YAAY;GAC/B,IAAI,UAAU,MAAM,QAAQ;GAC5B,KAAK,UAAU;GACf,OAAO;EACT,CAAC;CACH;CAEA,OAAa;EACX,IAAI,KAAK,SAAS,KAAK,KAAK,kBAAkB,IAAI;CACpD;CAEA,YAAkB;EAChB,IAAI,KAAK,SAAS,kBAAkB,YAAY;CAClD;CAEA,KAAK,MAAoB;EACvB,IAAI,CAAC,KAAK,WAAW,iBAAiB,MAAM;EAC5C,aAAa,cAAc;EAC3B,kBAAkB,KAAK;CACzB;CAEA,MAAM,IAA4B;EAChC,SAAS,IAAI,EAAE;EACf,aAAa;GACX,SAAS,OAAO,EAAE;EACpB;CACF;;CAGA,MAAM,KAAkC;EACtC,OAAO,QAAQ,KAAA,KAAa,KAAK,OAAO,QAAQ,SAAS,OAAO,QAAQ;CAC1E;;CAGA,MAAM,KAAuB;EAC3B,KAAK,UAAU;EACf,MAAM,UAAU,KAAK,OAAO,QAAQ,WAAW;EAC/C,MAAM,QAAQ,KAAK,OAAO;EAC1B,MAAM,OAAO,MAAM;EACnB,MAAM,WAAW,CAAC,MAAM;EACxB,KAAK,OAAO;EACZ,IAAI,YAAY,MAAM;EACtB,MAAM,UAAU,KAAK,QAAQ,QAAQ,QAAQ,MAAM,QAAQ;EAC3D,IAAI,YAAY,MAAM;EACtB,MAAM,QAAQ,IAAI,YAAyB,YAAY;GACrD,QAAQ;GACR,SAAS;GACT,UAAU;GACV,YAAY;EACd,CAAC;EACD,IAAI,KAAK,QAAQ,cAAc,KAAK,MAAM,OAAO;EACjD,IACG,kBAAkB,CAAC,EAClB,UAAU,OAAO,CAAC,CACnB,YAAY,CAGb,CAAC;CACL;;CAGA,QAAc;EACZ,KAAK,OAAO;CACd;CAEA,SAAuB;EACrB,MAAM,SAAS,KAAK,OAAO;EAC3B,KAAK,UAAU,EAAE,MAAM,KAAK,MAAM,EAAE;EACpC,KAAK,OAAO,MAAM,MAAM;EAGxB,QAAQ,QAAQ;EAChB,KAAK,UAAU;EACf,KAAK,OAAO,gBAAgB,WAAW,IAAI;EAC3C,OAAO;CACT;;CAGA,IAAI,SAAwB;EAC1B,KAAK,UAAU;EACf,IAAI,CAAC,KAAK,SAAS;EACnB,KAAK,UAAU;EACf,MAAM,UAAU,KAAK;EACrB,KAAK,UAAU;EACf,MAAM,QAAQ,KAAK,OAAO;EAE1B,KADoB,OAAO,QACnB,OAAO;EACf,KAAK,OAAO,gBAAgB,SAAS;EACrC,IAAI,CAAC,WAAW,CAAC,KAAK,QAAQ;EAG9B,IAAI,SAAS,SAAS,QAAQ,OAAO,SAAS,KAAK,IAAI,GAAG,MAAM,cAAc,KAAK;EACnF,IAAI,CAAC,KAAK,QAAQ,MAAM,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS;CACtD;;CAGA,QACE,QACA,MACA,UACoB;EACpB,MAAM,QAAQ,QAAQ,CAAC,CAAC,QAAQ,MAAM;EACtC,IAAI,UAAU,KAAA,GAAW,OAAO;EAChC,MAAM,SAAS,KAAK,OAAO;EAC3B,MAAM,OAAO,OAAO,QAAQ;EAC5B,MAAM,OAAO,IAAI,MAAM,UAAU,OAAO,KAAK,IAAI;EACjD,KAAK,aAAa,KAAK,MAAM,IAAI,MAAM,WAAW,OAAO,MAAM,WAAW;EAC1E,IAAI,WAAW,KAAK,IAAI,GAAG;GAIzB,MAAM,KAAK,WAAW,MAAM;GAC5B,KAAK,mBAAmB,KAAK,OAAO;GACpC,KAAK,wBAAwB,KAAK,aAAa;EACjD;EACA,MAAM,SAAkB,CAAC;EACzB,KAAK,MAAM,QAAQ,KAAK,OAAO,MAAM,iBAAiB,YAAY,GAAG;GACnE,MAAM,QAAQ;GACd,IAAI,MAAM,SAAS,eAAe,MAAM,SAAS,YAAY;GAC7D,MAAM,MAAM,IAAI,MAAM,MAAM,OAAO,SAAS,GAAG,MAAM,UAAU,IAAI;GACnE,IAAI,iBAAiB,MAAM;GAC3B,IAAI,mBAAmB;GACvB,IAAI,UACF,MAAM,SAAS,aAAa,MAAM,cAAc,WAAW,MAAM,cAAc;GACjF,IAAI,OAAO,MAAM;GACjB,IAAI,WAAW,MAAM;GACrB,OAAO,KAAK,GAAG;EACjB;EACA,KAAK,SAAS,OAAO,SAAS,IAAI,SAAS;EAC3C,MAAM,UAAU,IAAI,MAAM,YAAY,IAAI;EAC1C,QAAQ,cAAc;EACtB,QAAQ,WAAW;EACnB,OAAO;CACT;AACF;;AAGA,SAAS,WAAW,QAAuC;CACzD,MAAM,eAAe,QAAQ,MAAM,SAAS,CAAC,CAAC;CAC9C,IAAI,iBAAiB,QAAQ,iBAAiB,KAAA,GAAW,OAAO;CAChE,KAAK,MAAM,UAAU,aAAa,SAChC,KAAK,MAAM,SAAS,OAAO,QACzB,KAAK,MAAM,aAAa,MAAM,YAC5B,IAAI,QAAQ,KAAK,UAAU,QAAQ,GAAG,OAAO;CAInD,OAAO;AACT;;AAGA,SAAgB,KAAK,QAA0B;CAC7C,IAAI,OAAO,QAAQ,IAAI,MAAM;CAC7B,IAAI,SAAS,KAAA,GAAW;EACtB,OAAO,IAAI,OAAO,MAAM;EACxB,QAAQ,IAAI,QAAQ,IAAI;CAC1B;CACA,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"cast.js","names":[],"sources":["../src/cast.ts"],"sourcesContent":["/**\n * Chromecast from the page, over Google's Cast sender framework. The SDK is\n * a script the page loads, never a dependency (rule 2): the helper puts it\n * on the page the first time a cast button connects, unless it is already\n * there or the button says `sdk=\"none\"`. Its context is one per page by\n * Google's design, so the receiver id the first button gives is the one\n * the page keeps.\n *\n * One `Cast` per player. It owns the handoff and nothing on the video is\n * wrapped (rule 3): on start it pauses the video, freezes the engine, and\n * sends the session's source to the receiver at the video's time; on end\n * it thaws the engine, seeks the video to the receiver's last time, and\n * plays if the receiver was playing. The cast screen drives the receiver\n * through the SDK's remote player meanwhile.\n *\n * The receiver plays the URL by itself. The request's\n * `customData.mattebox` carries the source's DRM servers, the convention\n * `@mattebox/cast-receiver` reads. The button dispatches `castload` with the\n * request before it goes out, so the page adds license headers there, or\n * cancels. A receiver that gets a 401 or 403 from the license server asks\n * the sender for a new token on the `urn:x-cast:ch.mattebox.license`\n * namespace; the player dispatches `castunauthorized`, and the page replies.\n */\nimport type { Source } from '@mattebox/player-core';\nimport type { PlayerHost } from './host.js';\n\n/** Whether the session is live: the engine's `live` namespace, once it has an edge. */\nfunction live(engine: PlayerHost['engine']): boolean {\n const api = (engine as { live?: { edge: number | null } } | null)?.live;\n return api !== undefined && api.edge !== null;\n}\n\n// The slice of the sender SDK the helper reads. No `@types/chromecast`:\n// the SDK is not a dependency, and these names are what the page's script\n// puts on `window.cast.framework` and `window.chrome.cast`.\n\ninterface SdkEvent {\n readonly castState?: string;\n readonly sessionState?: string;\n}\n\ninterface SdkDevice {\n readonly friendlyName: string;\n}\n\ninterface SdkMediaSession {\n readonly media?: { readonly contentId?: string } | null;\n}\n\ninterface SdkSession {\n getCastDevice(): SdkDevice;\n getMediaSession(): SdkMediaSession | null;\n loadMedia(request: LoadRequest): Promise<unknown>;\n addMessageListener(namespace: string, fn: (namespace: string, message: string) => void): void;\n removeMessageListener(namespace: string, fn: (namespace: string, message: string) => void): void;\n sendMessage(namespace: string, message: unknown): Promise<unknown>;\n}\n\n/** The custom namespace a receiver asks the sender for a new license token on. */\nexport const LICENSE_NAMESPACE = 'urn:x-cast:ch.mattebox.license';\n\n/** What the page replies to `castunauthorized`: new license headers or servers for the receiver. */\nexport interface LicenseReply {\n readonly licenseHeaders?: Readonly<Record<string, string>>;\n readonly licenseUrl?: string;\n readonly licenseUrls?: Readonly<Record<string, string>>;\n}\n\n/** `castunauthorized`'s `detail`: the receiver's license server answered 401 or 403. */\nexport interface UnauthorizedDetail {\n readonly keySystem: string;\n readonly status: number;\n /** Sends the new token to the receiver. Call it once, with the reply or a promise of it. */\n reply(reply: LicenseReply | Promise<LicenseReply>): void;\n}\n\n/** `customData.mattebox`: the source's DRM servers, as `@mattebox/cast-receiver` reads them. */\nexport interface MatteboxCustomData {\n licenseUrl?: string;\n licenseUrls?: Readonly<Record<string, string>>;\n certificateUrl?: string;\n /** Headers for the license requests. The player has none of its own; a `castload` listener adds them. */\n licenseHeaders?: Record<string, string>;\n}\n\ninterface SdkContext {\n setOptions(options: { receiverApplicationId: string; autoJoinPolicy: string }): void;\n addEventListener(type: string, fn: (event: SdkEvent) => void): void;\n getCastState(): string;\n getCurrentSession(): SdkSession | null;\n requestSession(): Promise<unknown>;\n endCurrentSession(stopCasting: boolean): void;\n}\n\ninterface SdkRemotePlayer {\n isConnected: boolean;\n isMediaLoaded: boolean;\n isPaused: boolean;\n currentTime: number;\n duration: number;\n playerState: string | null;\n}\n\ninterface SdkRemoteController {\n addEventListener(type: string, fn: () => void): void;\n playOrPause(): void;\n seek(): void;\n stop(): void;\n}\n\n/** What the receiver plays. The page sees it as `castload`'s `detail`. */\nexport interface MediaInfo {\n contentId: string;\n contentType: string;\n streamType: string;\n tracks: Track[] | null;\n hlsSegmentFormat?: string;\n hlsVideoSegmentFormat?: string;\n}\n\nexport interface Track {\n trackContentId: string;\n trackContentType: string;\n subtype: string;\n name: string;\n language: string;\n}\n\nexport interface LoadRequest {\n media: MediaInfo;\n currentTime: number;\n autoplay: boolean;\n customData: unknown;\n}\n\ninterface Framework {\n CastContext: { getInstance(): SdkContext };\n RemotePlayer: new () => SdkRemotePlayer;\n RemotePlayerController: new (player: SdkRemotePlayer) => SdkRemoteController;\n CastContextEventType: { CAST_STATE_CHANGED: string; SESSION_STATE_CHANGED: string };\n CastState: { NO_DEVICES_AVAILABLE: string; CONNECTING: string; CONNECTED: string };\n SessionState: {\n SESSION_STARTED: string;\n SESSION_RESUMED: string;\n SESSION_ENDED: string;\n SESSION_START_FAILED: string;\n };\n RemotePlayerEventType: { ANY_CHANGE: string };\n}\n\ninterface ChromeCast {\n AutoJoinPolicy: { ORIGIN_SCOPED: string };\n media: {\n MediaInfo: new (contentId: string, contentType: string) => MediaInfo;\n LoadRequest: new (media: MediaInfo) => LoadRequest;\n Track: new (trackId: number, type: string) => Track;\n TrackType: { TEXT: string };\n TextTrackType: { SUBTITLES: string; CAPTIONS: string };\n StreamType: { BUFFERED: string; LIVE: string };\n };\n}\n\ninterface Globals {\n cast?: { framework?: Framework };\n chrome?: { cast?: ChromeCast };\n __onGCastApiAvailable?: (available: boolean) => void;\n}\n\n/** The Default Media Receiver: Google's player, which plays HLS and DASH by itself. */\nconst DEFAULT_RECEIVER = 'CC1AD845';\nconst SDK_URL = 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1';\n\nexport type CastState = 'unavailable' | 'idle' | 'connecting' | 'casting';\n\n/** What the cast screen shows of the receiver. */\nexport interface Remote {\n readonly loaded: boolean;\n readonly paused: boolean;\n readonly time: number;\n /** Infinity for a live stream, the way the video reports it. */\n readonly duration: number;\n}\n\nexport interface Cast {\n /**\n * Puts the SDK on the page unless `sdk` is `none` or it is already there,\n * and sets the context up with `receiver`, or the default receiver. The\n * first call on the page decides both; a later different receiver is an\n * error on the console, not a second context.\n */\n connect(receiver: string | null, sdk: string | null): void;\n /** The button left the player: a rejoined session no longer looks here. */\n disconnect(): void;\n state(): CastState;\n /** The receiver's name while casting, or null. */\n device(): string | null;\n remote(): Remote;\n /** Opens the device picker. `castload` goes out on `target` once a session starts. */\n start(target: HTMLElement): void;\n /** Ends the session and stops the receiver. */\n stop(): void;\n playPause(): void;\n seek(time: number): void;\n /** Runs `fn` on every change: devices, session, and the receiver's playback. Returns the unsubscribe. */\n watch(fn: () => void): () => void;\n}\n\n/** What the video is doing at the start of a cast, to give back at the end. */\ninterface Handoff {\n readonly live: boolean;\n}\n\n// The page-wide part: one SDK, one context, one remote player. Held in the\n// module because the SDK holds them in the window.\n\nlet framework: Promise<Framework | null> | null = null;\nlet configured: string | null = null;\nlet remotePlayer: SdkRemotePlayer | null = null;\nlet remoteController: SdkRemoteController | null = null;\nconst watchers = new Set<() => void>();\n/** The player whose session this is, so two players on a page do not both take a session. */\nlet owner: CastOf | null = null;\n/** The receiver's last known playback, read while it reports and kept once it stops. */\nconst NOTHING: Remote = { loaded: false, paused: true, time: 0, duration: Number.NaN };\nlet last: Remote = NOTHING;\n\nfunction globals(): Globals {\n return globalThis as Globals;\n}\n\nfunction notify(): void {\n for (const fn of [...watchers]) fn();\n}\n\n/**\n * The framework, once the page has it. Resolves null where the SDK never\n * arrives: a browser without Cast, a page whose CSP refused the script, or\n * `sdk=\"none\"` with no script of the page's own.\n */\nfunction load(sdk: string | null): Promise<Framework | null> {\n if (framework !== null) return framework;\n const held = globals();\n if (held.cast?.framework !== undefined) {\n framework = Promise.resolve(held.cast.framework);\n return framework;\n }\n // The SDK is Chromium's. Elsewhere the script only reports that it is\n // unavailable, so it is not fetched.\n if (!('chrome' in held)) {\n framework = Promise.resolve(null);\n return framework;\n }\n framework = new Promise((resolve) => {\n const previous = held.__onGCastApiAvailable;\n // The SDK calls this once it is in, on its own script or the page's.\n held.__onGCastApiAvailable = (available: boolean): void => {\n previous?.(available);\n resolve(available ? (globals().cast?.framework ?? null) : null);\n };\n if (sdk === 'none') return;\n const script = document.createElement('script');\n script.src = SDK_URL;\n script.async = true;\n script.addEventListener('error', () => resolve(null));\n document.head.append(script);\n });\n return framework;\n}\n\n/** The context, set up once per page. */\nfunction context(fw: Framework, receiver: string | null): SdkContext {\n const ctx = fw.CastContext.getInstance();\n const wanted = receiver ?? DEFAULT_RECEIVER;\n if (configured === null) {\n const policy = globals().chrome?.cast?.AutoJoinPolicy.ORIGIN_SCOPED ?? 'origin_scoped';\n ctx.setOptions({ receiverApplicationId: wanted, autoJoinPolicy: policy });\n configured = wanted;\n ctx.addEventListener(fw.CastContextEventType.CAST_STATE_CHANGED, notify);\n ctx.addEventListener(fw.CastContextEventType.SESSION_STATE_CHANGED, (event) => {\n onSession(fw, ctx, event.sessionState ?? '');\n });\n remotePlayer = new fw.RemotePlayer();\n remoteController = new fw.RemotePlayerController(remotePlayer);\n remoteController.addEventListener(fw.RemotePlayerEventType.ANY_CHANGE, () => {\n const remote = remotePlayer;\n if (remote?.isConnected === true && remote.isMediaLoaded) {\n last = {\n loaded: true,\n paused: remote.isPaused,\n time: remote.currentTime,\n duration: remote.duration > 0 ? remote.duration : Number.POSITIVE_INFINITY,\n };\n }\n notify();\n });\n } else if (receiver !== null && receiver !== configured) {\n console.error(`mattebox-player: the Cast context already uses receiver ${configured}`);\n }\n return ctx;\n}\n\nfunction onSession(fw: Framework, ctx: SdkContext, state: string): void {\n const states = fw.SessionState;\n if (state === states.SESSION_STARTED && owner !== null && owner.pending) {\n // A new session has loaded nothing yet, whatever the last one played.\n last = NOTHING;\n owner.begin(ctx);\n } else if (state === states.SESSION_RESUMED) {\n // Chrome rejoins a session of this origin on load. It is this player's\n // when the receiver plays what the player has.\n const playing = ctx.getCurrentSession()?.getMediaSession()?.media?.contentId;\n const found = [...connected].find((cast) => cast.plays(playing));\n if (found !== undefined && owner === null) {\n owner = found;\n found.adopt(ctx);\n }\n } else if (state === states.SESSION_ENDED || state === states.SESSION_START_FAILED) {\n const ended = owner;\n owner = null;\n ended?.end(state === states.SESSION_ENDED);\n }\n notify();\n}\n\n/** One per player, found again by its button and its screen. Weak, so a player that leaves is not held. */\nconst players = new WeakMap<PlayerHost, CastOf>();\n/** The players with a cast button attached, for a session Chrome rejoins on load. */\nconst connected = new Set<CastOf>();\n\nclass CastOf implements Cast {\n declare private readonly player: PlayerHost;\n declare private target: HTMLElement | null;\n declare private ctx: SdkContext | null;\n declare private fw: Framework | null;\n /** This player asked for a session and waits for it to start. */\n declare pending: boolean;\n declare private casting: boolean;\n declare private handoff: Handoff | null;\n /** The session this player listens on for license token requests, and its listener. */\n declare private listening: {\n readonly session: SdkSession;\n readonly fn: (namespace: string, message: string) => void;\n } | null;\n\n constructor(player: PlayerHost) {\n this.player = player;\n this.target = null;\n this.ctx = null;\n this.fw = null;\n this.pending = false;\n this.casting = false;\n this.handoff = null;\n this.listening = null;\n }\n\n connect(receiver: string | null, sdk: string | null): void {\n connected.add(this);\n void load(sdk).then((fw) => {\n if (fw === null) return;\n this.fw = fw;\n this.ctx = context(fw, receiver);\n notify();\n });\n }\n\n disconnect(): void {\n connected.delete(this);\n }\n\n state(): CastState {\n const ctx = this.ctx;\n const fw = this.fw;\n if (ctx === null || fw === null) return 'unavailable';\n if (this.casting) return 'casting';\n const cast = ctx.getCastState();\n if (cast === fw.CastState.NO_DEVICES_AVAILABLE) return 'unavailable';\n if (cast === fw.CastState.CONNECTING || this.pending) return 'connecting';\n return 'idle';\n }\n\n device(): string | null {\n if (!this.casting) return null;\n return this.ctx?.getCurrentSession()?.getCastDevice().friendlyName ?? null;\n }\n\n remote(): Remote {\n return last;\n }\n\n start(target: HTMLElement): void {\n const ctx = this.ctx;\n if (ctx === null || this.casting) return;\n // Another player on the page holds the session. The SDK has one, so\n // this click ends it, the way Chrome's own dialog offers to.\n if (owner !== null && owner !== this) {\n ctx.endCurrentSession(true);\n return;\n }\n this.target = target;\n this.pending = true;\n owner = this;\n notify();\n // Rejected when the viewer closes the picker; SESSION_START_FAILED\n // does not fire for that, so the wait ends here.\n ctx.requestSession().catch(() => {\n if (owner === this) owner = null;\n this.pending = false;\n notify();\n });\n }\n\n stop(): void {\n if (this.casting) this.ctx?.endCurrentSession(true);\n }\n\n playPause(): void {\n if (this.casting) remoteController?.playOrPause();\n }\n\n seek(time: number): void {\n if (!this.casting || remotePlayer === null) return;\n remotePlayer.currentTime = time;\n remoteController?.seek();\n }\n\n watch(fn: () => void): () => void {\n watchers.add(fn);\n return () => {\n watchers.delete(fn);\n };\n }\n\n /** Whether this player's session plays `url`. */\n plays(url: string | undefined): boolean {\n return url !== undefined && this.player.player?.session?.source.url === url;\n }\n\n /** A session started for this player: freeze the picture and send the source. */\n begin(ctx: SdkContext): void {\n this.pending = false;\n const session = this.player.player?.session ?? null;\n const video = this.player.video;\n const time = video.currentTime;\n const autoplay = !video.paused;\n this.freeze();\n if (session === null) return;\n const request = this.request(session.source, time, autoplay);\n if (request === null) return;\n this.listen(ctx.getCurrentSession());\n const event = new CustomEvent<LoadRequest>('castload', {\n detail: request,\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n if (this.target?.dispatchEvent(event) === false) return;\n void ctx\n .getCurrentSession()\n ?.loadMedia(request)\n .catch(() => {\n // The receiver refused the media. The session stays, so the viewer\n // can stop it; the screen shows no time.\n });\n }\n\n /** A session Chrome rejoined, already playing this player's source. */\n adopt(ctx: SdkContext): void {\n this.freeze();\n this.listen(ctx.getCurrentSession());\n }\n\n /**\n * Answers the receiver's token requests for this session: a\n * `castunauthorized` event on the player, and the page's reply sent back.\n */\n private listen(session: SdkSession | null): void {\n this.unlisten();\n if (session === null) return;\n const fn = (_namespace: string, message: string): void => {\n let data: { type?: unknown; id?: unknown; keySystem?: unknown; status?: unknown };\n try {\n data = JSON.parse(message) as typeof data;\n } catch {\n return;\n }\n if (data.type !== 'unauthorized') return;\n const id = data.id;\n let replied = false;\n const detail: UnauthorizedDetail = {\n keySystem: typeof data.keySystem === 'string' ? data.keySystem : '',\n status: typeof data.status === 'number' ? data.status : 0,\n reply(reply) {\n if (replied) return;\n replied = true;\n void Promise.resolve(reply)\n .then((answer) =>\n session.sendMessage(LICENSE_NAMESPACE, { type: 'license', id, ...answer }),\n )\n .catch(() => {\n // No reply reaches the receiver; it gives up after its own wait.\n });\n },\n };\n this.player.dispatchEvent(\n new CustomEvent<UnauthorizedDetail>('castunauthorized', { detail, bubbles: true }),\n );\n };\n session.addMessageListener(LICENSE_NAMESPACE, fn);\n this.listening = { session, fn };\n }\n\n private unlisten(): void {\n const held = this.listening;\n this.listening = null;\n held?.session.removeMessageListener(LICENSE_NAMESPACE, held.fn);\n }\n\n private freeze(): void {\n const engine = this.player.engine;\n this.handoff = { live: live(engine) };\n this.player.video.pause();\n // The engine keeps its buffers and makes no request while the receiver\n // plays (engine guide 01, suspend and resume).\n engine?.suspend();\n this.casting = true;\n this.player.toggleAttribute('casting', true);\n notify();\n }\n\n /** The session ended: give the video back where the receiver left it. */\n end(cleanly: boolean): void {\n this.pending = false;\n this.unlisten();\n if (!this.casting) return;\n this.casting = false;\n const handoff = this.handoff;\n this.handoff = null;\n const video = this.player.video;\n const engine = this.player.engine;\n engine?.resume();\n this.player.removeAttribute('casting');\n if (!cleanly || !last.loaded) return;\n // Live rejoins at the edge on its own; the receiver's time is on the\n // receiver's own timeline and means nothing here.\n if (handoff?.live !== true && Number.isFinite(last.time)) video.currentTime = last.time;\n if (!last.paused) video.play().catch(() => undefined);\n }\n\n /** The load request: the source, the time, the stream type, and the video's own text tracks. */\n private request(source: Source, time: number, autoplay: boolean): LoadRequest | null {\n const media = globals().chrome?.cast?.media;\n if (media === undefined) return null;\n const engine = this.player.engine;\n const type = source.type ?? '';\n const info = new media.MediaInfo(source.url, type);\n info.streamType = live(engine) ? media.StreamType.LIVE : media.StreamType.BUFFERED;\n if (/mpegurl/i.test(type)) {\n // The receiver assumes MPEG-TS segments for HLS unless told. The\n // engine's presentation says which the stream has; a native session\n // has none, and CMAF is the assumption there.\n const ts = tsSegments(engine);\n info.hlsSegmentFormat = ts ? 'ts' : 'fmp4';\n info.hlsVideoSegmentFormat = ts ? 'mpeg2_ts' : 'fmp4';\n }\n const tracks: Track[] = [];\n for (const node of this.player.video.querySelectorAll('track[src]')) {\n const track = node as HTMLTrackElement;\n if (track.kind !== 'subtitles' && track.kind !== 'captions') continue;\n const out = new media.Track(tracks.length + 1, media.TrackType.TEXT);\n out.trackContentId = track.src;\n out.trackContentType = 'text/vtt';\n out.subtype =\n track.kind === 'captions' ? media.TextTrackType.CAPTIONS : media.TextTrackType.SUBTITLES;\n out.name = track.label;\n out.language = track.srclang;\n tracks.push(out);\n }\n info.tracks = tracks.length > 0 ? tracks : null;\n const request = new media.LoadRequest(info);\n request.currentTime = time;\n request.autoplay = autoplay;\n const drm = source.drm;\n if (drm !== undefined) {\n const mattebox: MatteboxCustomData = {\n ...(drm.licenseUrl === undefined ? {} : { licenseUrl: drm.licenseUrl }),\n ...(drm.licenseUrls === undefined ? {} : { licenseUrls: drm.licenseUrls }),\n ...(drm.certificateUrl === undefined ? {} : { certificateUrl: drm.certificateUrl }),\n };\n request.customData = { mattebox };\n }\n return request;\n }\n}\n\n/** Whether the engine's presentation carries MPEG-TS renditions. */\nfunction tsSegments(engine: PlayerHost['engine']): boolean {\n const presentation = engine?.stats.snapshot().presentation;\n if (presentation === null || presentation === undefined) return false;\n for (const period of presentation.periods) {\n for (const track of period.tracks) {\n for (const rendition of track.renditions) {\n if (/mp2t/i.test(rendition.mimeType)) return true;\n }\n }\n }\n return false;\n}\n\n/** The player's Cast, one per player, shared by its cast button and cast screen. */\nexport function cast(player: PlayerHost): Cast {\n let held = players.get(player);\n if (held === undefined) {\n held = new CastOf(player);\n players.set(player, held);\n }\n return held;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var matteboxPlayerCast=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){let t=e==null?void 0:e.live;return t!==void 0&&t.edge!==null}let n=null,r=null,i=null,a=null,o=/* @__PURE__ */ new Set,s=null,c={loaded:!1,paused:!0,time:0,duration:NaN},l=c;function u(){return globalThis}function d(){for(let e of[...o])e()}function f(e){var t;if(n!==null)return n;let r=u();return((t=r.cast)==null?void 0:t.framework)===void 0?`chrome`in r?(n=new Promise(t=>{let n=r.__onGCastApiAvailable;if(r.__onGCastApiAvailable=e=>{var r,i;n==null||n(e),t(e?(r=(i=u().cast)==null?void 0:i.framework)==null?null:r:null)},e===`none`)return;let i=document.createElement(`script`);i.src=`https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1`,i.async=!0,i.addEventListener(`error`,()=>t(null)),document.head.append(i)}),n):(n=Promise.resolve(null),n):(n=Promise.resolve(r.cast.framework),n)}function p(e,t){let n=e.CastContext.getInstance(),o=t==null?`CC1AD845`:t;if(r===null){var s,c;let t=(s=(c=u().chrome)==null||(c=c.cast)==null?void 0:c.AutoJoinPolicy.ORIGIN_SCOPED)==null?`origin_scoped`:s;n.setOptions({receiverApplicationId:o,autoJoinPolicy:t}),r=o,n.addEventListener(e.CastContextEventType.CAST_STATE_CHANGED,d),n.addEventListener(e.CastContextEventType.SESSION_STATE_CHANGED,t=>{var r;m(e,n,(r=t.sessionState)==null?``:r)}),i=new e.RemotePlayer,a=new e.RemotePlayerController(i),a.addEventListener(e.RemotePlayerEventType.ANY_CHANGE,()=>{let e=i;(e==null?void 0:e.isConnected)===!0&&e.isMediaLoaded&&(l={loaded:!0,paused:e.isPaused,time:e.currentTime,duration:e.duration>0?e.duration:1/0}),d()})}else t!==null&&t!==r&&console.error(`mattebox-player: the Cast context already uses receiver ${r}`);return n}function m(e,t,n){let r=e.SessionState;if(n===r.SESSION_STARTED&&s!==null&&s.pending)l=c,s.begin(t);else if(n===r.SESSION_RESUMED){var i;let e=(i=t.getCurrentSession())==null||(i=i.getMediaSession())==null||(i=i.media)==null?void 0:i.contentId,n=[...g].find(t=>t.plays(e));n!==void 0&&s===null&&(s=n,n.adopt())}else if(n===r.SESSION_ENDED||n===r.SESSION_START_FAILED){let e=s;s=null,e==null||e.end(n===r.SESSION_ENDED)}d()}let h=/* @__PURE__ */ new WeakMap,g=/* @__PURE__ */ new Set;var _=class{constructor(e){this.player=e,this.target=null,this.ctx=null,this.fw=null,this.pending=!1,this.casting=!1,this.handoff=null}connect(e,t){g.add(this),f(t).then(t=>{t!==null&&(this.fw=t,this.ctx=p(t,e),d())})}disconnect(){g.delete(this)}state(){let e=this.ctx,t=this.fw;if(e===null||t===null)return`unavailable`;if(this.casting)return`casting`;let n=e.getCastState();return n===t.CastState.NO_DEVICES_AVAILABLE?`unavailable`:n===t.CastState.CONNECTING||this.pending?`connecting`:`idle`}device(){var e,t;return this.casting?(e=(t=this.ctx)==null||(t=t.getCurrentSession())==null?void 0:t.getCastDevice().friendlyName)==null?null:e:null}remote(){return l}start(e){let t=this.ctx;if(!(t===null||this.casting)){if(s!==null&&s!==this){t.endCurrentSession(!0);return}this.target=e,this.pending=!0,s=this,d(),t.requestSession().catch(()=>{s===this&&(s=null),this.pending=!1,d()})}}stop(){var e;this.casting&&((e=this.ctx)==null||e.endCurrentSession(!0))}playPause(){this.casting&&(a==null||a.playOrPause())}seek(e){this.casting&&i!==null&&(i.currentTime=e,a==null||a.seek())}watch(e){return o.add(e),()=>{o.delete(e)}}plays(e){var t;return e!==void 0&&((t=this.player.player)==null||(t=t.session)==null?void 0:t.source.url)===e}begin(e){var t,n,r,i;this.pending=!1;let a=(t=(n=this.player.player)==null?void 0:n.session)==null?null:t,o=this.player.video,s=o.currentTime,c=!o.paused;if(this.freeze(),a===null)return;let l=this.request(a.source,s,c);if(l===null)return;let u=new CustomEvent(`castload`,{detail:l,bubbles:!0,composed:!0,cancelable:!0});((r=this.target)==null?void 0:r.dispatchEvent(u))!==!1&&((i=e.getCurrentSession())==null||i.loadMedia(l).catch(()=>{}))}adopt(){this.freeze()}freeze(){let e=this.player.engine;this.handoff={live:t(e)},this.player.video.pause(),e==null||e.suspend(),this.casting=!0,this.player.toggleAttribute(`casting`,!0),d()}end(e){if(this.pending=!1,!this.casting)return;this.casting=!1;let t=this.handoff;this.handoff=null;let n=this.player.video,r=this.player.engine;r==null||r.resume(),this.player.removeAttribute(`casting`),e&&l.loaded&&((t==null?void 0:t.live)!==!0&&Number.isFinite(l.time)&&(n.currentTime=l.time),l.paused||n.play().catch(()=>void 0))}request(e,n,r){var i,a;let o=(i=u().chrome)==null||(i=i.cast)==null?void 0:i.media;if(o===void 0)return null;let s=this.player.engine,c=(a=e.type)==null?``:a,l=new o.MediaInfo(e.url,c);if(l.streamType=t(s)?o.StreamType.LIVE:o.StreamType.BUFFERED,/mpegurl/i.test(c)){let e=v(s);l.hlsSegmentFormat=e?`ts`:`fmp4`,l.hlsVideoSegmentFormat=e?`mpeg2_ts`:`fmp4`}let d=[];for(let e of this.player.video.querySelectorAll(`track[src]`)){let t=e;if(t.kind!==`subtitles`&&t.kind!==`captions`)continue;let n=new o.Track(d.length+1,o.TrackType.TEXT);n.trackContentId=t.src,n.trackContentType=`text/vtt`,n.subtype=t.kind===`captions`?o.TextTrackType.CAPTIONS:o.TextTrackType.SUBTITLES,n.name=t.label,n.language=t.srclang,d.push(n)}l.tracks=d.length>0?d:null;let f=new o.LoadRequest(l);return f.currentTime=n,f.autoplay=r,f}};function v(e){let t=e==null?void 0:e.stats.snapshot().presentation;if(t==null)return!1;for(let e of t.periods)for(let t of e.tracks)for(let e of t.renditions)if(/mp2t/i.test(e.mimeType))return!0;return!1}function y(e){let t=h.get(e);return t===void 0&&(t=new _(e),h.set(e,t)),t}function b(e){let t=e.parentNode;return t===null?e instanceof ShadowRoot?e.host:null:t}function x(e){let t=e;for(;t!==null;){if(t instanceof HTMLElement&&t.localName===`mattebox-player`)return t;t=b(t)}return null}var S=class extends HTMLElement{constructor(){super(),this.player=null,this.offs=[],this.epoch=0}connectedCallback(){let e=x(this);if(e===null)return;this.epoch+=1;let t=this.epoch,n=()=>{t===this.epoch&&this.isConnected&&(customElements.upgrade(e),`video`in e&&(this.player=e,this.attach(this.player)))};`video`in e?n():customElements.whenDefined(`mattebox-player`).then(n)}disconnectedCallback(){this.epoch+=1;for(let e of this.offs)e();this.offs=[];let e=this.player;e!==null&&(this.player=null,this.detach(e))}attributeChangedCallback(){this.player!==null&&this.render()}listen(e,t,n){for(let r of t)e.addEventListener(r,n);this.offs.push(()=>{for(let r of t)e.removeEventListener(r,n)})}keep(e){this.offs.push(e)}follow(e,t){let n,r=()=>{n==null||n(),n=t(e.engine)};this.listen(e,[`sourcechange`],r),this.offs.push(()=>{n==null||n(),n=void 0}),r()}observe(e,t,n,r=!1){let i=new MutationObserver(n);i.observe(e,{attributes:!0,attributeFilter:[...t],subtree:r}),this.offs.push(()=>{i.disconnect()})}detach(e){}render(){}};let C={play:`M10.6667 6.6548C10.6667 6.10764 11.2894 5.79346 11.7295 6.11862L24.377 15.4634C24.7377 15.7298 24.7377 16.2692 24.3771 16.5357L11.7295 25.8813C11.2895 26.2065 10.6667 25.8923 10.6667 25.3451L10.6667 6.6548Z`,pause:`M8.66667 6.66667C8.29848 6.66667 8 6.96514 8 7.33333V24.6667C8 25.0349 8.29848 25.3333 8.66667 25.3333H12.6667C13.0349 25.3333 13.3333 25.0349 13.3333 24.6667V7.33333C13.3333 6.96514 13.0349 6.66667 12.6667 6.66667H8.66667Z M19.3333 6.66667C18.9651 6.66667 18.6667 6.96514 18.6667 7.33333V24.6667C18.6667 25.0349 18.9651 25.3333 19.3333 25.3333H23.3333C23.7015 25.3333 24 25.0349 24 24.6667V7.33333C24 6.96514 23.7015 6.66667 23.3333 6.66667H19.3333Z`,cast:`M4 6h24v18H20v-2h6V8H6v1H4V6zM4 21a3 3 0 0 1 3 3H4zM4 15a9 9 0 0 1 9 9h-2a7 7 0 0 0-7-7zM4 10a14 14 0 0 1 14 14h-2A12 12 0 0 0 4 12z`,"cast-active":`M4 6h24v18H20A16 16 0 0 0 4 8zM4 21a3 3 0 0 1 3 3H4zM4 15a9 9 0 0 1 9 9h-2a7 7 0 0 0-7-7zM4 10a14 14 0 0 1 14 14h-2A12 12 0 0 0 4 12z`},w=`http://www.w3.org/2000/svg`;function T(e){let t=document.createElementNS(w,`svg`);t.setAttribute(`viewBox`,`0 0 32 32`),t.setAttribute(`aria-hidden`,`true`),t.setAttribute(`part`,`icon`);let n=document.createElementNS(w,`path`);return n.setAttribute(`fill-rule`,`evenodd`),n.setAttribute(`d`,C[e]),t.append(n),t}function E(e){let t=document.createElement(`style`);return t.textContent=e,t}function D(e,t){let n={};for(let r of e){let e=document.createElement(`slot`);e.name=`icon-${r}`,e.append(t(r)),e.hidden=!0,n[r]=e}return n}function O(e,t){for(let n of Object.keys(e))e[n].hidden=n!==t}function k(e,t,n){let r=document.createElement(e);return r.setAttribute(`part`,t),n!==void 0&&(r.textContent=n),r}function A(e,t){return e.replace(/\{(\w+)\}/g,(e,n)=>{let r=t[n];return r===void 0?e:String(r)})}function j(e){return e<10?`0${e}`:`${e}`}function M(e){let t=Number.isFinite(e)&&e>0?Math.floor(e):0,n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60;return n>0?`${n}:${j(r)}:${j(i)}`:`${r}:${j(i)}`}function N(e,t){return Number.isFinite(t)?`${M(e)} of ${M(t)}`:M(e)}let P=[`default`,`active`];var F=class extends S{static get observedAttributes(){return[`label-start`,`label-stop`]}constructor(){super(),this.api=null;let e=this.attachShadow({mode:`open`});this.button=document.createElement(`button`),this.button.type=`button`,this.button.setAttribute(`part`,`button`),this.slots=D(P,e=>T(e===`active`?`cast-active`:`cast`));for(let e of P)this.button.append(this.slots[e]);this.button.addEventListener(`click`,()=>{let e=this.api;e!==null&&(e.state()===`casting`?e.stop():e.start(this))}),e.append(E(`:host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:40px;height:40px;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;opacity:.9;background:0 0;border:0;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}[part~=button]:hover{opacity:1}[part~=button]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=button]:focus:not(:focus-visible){outline:none}[part~=icon],::slotted(*){fill:currentColor;width:1.75em;height:1.75em}slot[hidden]{display:none}`),this.button)}attach(e){let t=y(e);this.api=t,t.connect(this.getAttribute(`receiver`),this.getAttribute(`sdk`)),this.keep(t.watch(()=>{this.render()})),this.follow(e,()=>{this.render()})}detach(){var e;(e=this.api)==null||e.disconnect(),this.api=null}render(){var e,t,n;let r=this.player,i=this.api;if(r===null||i===null)return;let a=i.state(),o=a===`casting`;this.hidden=a===`unavailable`,this.button.disabled=!o&&((e=r.player)==null?void 0:e.session)==null,this.button.toggleAttribute(`aria-busy`,a===`connecting`),O(this.slots,o?`active`:`default`),this.button.setAttribute(`aria-label`,o?(t=this.getAttribute(`label-stop`))==null?`Stop casting`:t:(n=this.getAttribute(`label-start`))==null?`Cast`:n)}};function I(e,t,n){return Math.min(n,Math.max(t,e))}function L(e){let{onInput:t}=e,n=k(`div`,`slider`);n.setAttribute(`role`,`slider`),n.tabIndex=0;let r=k(`div`,`rail`),i=k(`div`,`track`),a=k(`div`,`fill`),o=k(`div`,`thumb`);i.append(a),r.append(i,o),n.append(r);let s=0,c=1,l=0,u=!1;function d(){let e=`${(c>s?(l-s)/(c-s):0)*100}%`;a.style.width=e,o.style.left=e}function f(e){let t=r.getBoundingClientRect();return t.width===0?s:s+I((e-t.left)/t.width,0,1)*(c-s)}function p(t){u=t,e.onDrag(t)}function m(e){if(e.button===0){e.preventDefault(),p(!0);try{n.setPointerCapture(e.pointerId)}catch(e){}t(f(e.clientX))}}function h(e){if(u){if(e.buttons===0){g(e);return}t(f(e.clientX))}}function g(e){u&&(p(!1),t(f(e.clientX)))}function _(){u&&p(!1)}function v(n){let r;switch(n.key){case`ArrowRight`:case`ArrowUp`:r=l+e.step();break;case`ArrowLeft`:case`ArrowDown`:r=l-e.step();break;case`PageUp`:r=l+e.page();break;case`PageDown`:r=l-e.page();break;case`Home`:r=s;break;case`End`:r=c;break;default:return}n.preventDefault(),t(I(r,s,c))}return n.addEventListener(`pointerdown`,m),n.addEventListener(`pointermove`,h),n.addEventListener(`pointerup`,g),n.addEventListener(`pointercancel`,_),n.addEventListener(`lostpointercapture`,_),n.addEventListener(`keydown`,v),{root:n,track:i,rail:r,label(e){n.setAttribute(`aria-label`,e)},dragging(){return u},range(e,t){s=e,c=t,n.setAttribute(`aria-valuemin`,String(e)),n.setAttribute(`aria-valuemax`,String(t)),d()},set(e,t){l=I(e,s,c),n.setAttribute(`aria-valuenow`,String(l)),n.setAttribute(`aria-valuetext`,t),d()},dispose(){n.removeEventListener(`pointerdown`,m),n.removeEventListener(`pointermove`,h),n.removeEventListener(`pointerup`,g),n.removeEventListener(`pointercancel`,_),n.removeEventListener(`lostpointercapture`,_),n.removeEventListener(`keydown`,v)}}}let R=[`play`,`pause`];var z=class extends S{static get observedAttributes(){return[`label`,`label-stop`,`label-play`,`label-pause`,`label-seek`]}constructor(){super(),this.api=null,this.held=null;let e=this.attachShadow({mode:`open`}),t=k(`div`,`box`);this.title_=k(`div`,`title`),this.play=document.createElement(`button`),this.play.type=`button`,this.play.setAttribute(`part`,`button play`),this.slots=D(R,T);for(let e of R)this.play.append(this.slots[e]);this.play.addEventListener(`click`,()=>{var e;(e=this.api)==null||e.playPause()}),this.seek=L({step:()=>5,page:()=>30,onInput:e=>{var t;if(this.seek.dragging()){this.held=e,this.paint();return}this.held=null,(t=this.api)==null||t.seek(e)},onDrag:e=>{this.toggleAttribute(`dragging`,e),e||(this.held=null)}}),this.time=k(`span`,`time`),this.row=k(`div`,`row`),this.row.append(this.play,this.seek.root,this.time),this.stop=k(`button`,`stop`),this.stop.type=`button`,this.stop.addEventListener(`click`,()=>{var e;(e=this.api)==null||e.stop()}),t.append(this.title_,this.row,this.stop),e.append(E(`:host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:40px;height:40px;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;opacity:.9;background:0 0;border:0;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}[part~=button]:hover{opacity:1}[part~=button]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=button]:focus:not(:focus-visible){outline:none}[part~=icon],::slotted(*){fill:currentColor;width:1.75em;height:1.75em}slot[hidden]{display:none}:host{display:block}:host([hidden]){display:none}[part~=slider]{border-radius:var(--mbx-radius);cursor:pointer;touch-action:none;height:40px;position:relative}[part~=slider]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=slider]:focus:not(:focus-visible){outline:none}[part~=rail]{position:absolute;top:0;bottom:0;left:8px;right:8px}[part~=track]{background:#ffffff59;border-radius:2px;height:4px;position:absolute;top:50%;left:0;right:0;overflow:hidden;transform:translateY(-50%)}[part~=fill]{background:var(--mbx-accent);position:absolute;top:0;bottom:0;left:0}[part~=thumb]{background:var(--mbx-text);pointer-events:none;border-radius:50%;width:12px;height:12px;margin:-6px 0 0 -6px;position:absolute;top:50%}:host{color:var(--mbx-text);font:400 15px / 1.4 var(--mbx-font);text-align:center;background:#000000d9;justify-content:center;align-items:center;padding:16px;display:flex;position:absolute;top:0;bottom:0;left:0;right:0}:host([hidden]){display:none}[part~=box]{flex-direction:column;align-items:center;width:100%;max-width:420px;display:flex}[part~=box]>:not([hidden])~:not([hidden]){margin-top:12px}[part~=title]{font-size:18px;font-weight:600}[part~=row]{justify-content:center;align-items:center;width:100%;display:flex}[part~=row]>:not([hidden])~:not([hidden]){margin-left:12px}[part~=slider]{flex:1}[part~=time]{font-variant-numeric:tabular-nums;color:var(--mbx-muted);font-size:13px}[part~=stop]{height:36px;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;background:0 0;border:1px solid;padding:0 16px;font-weight:600}[part~=stop]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=stop]:focus:not(:focus-visible){outline:none}[hidden]{display:none}`),t)}connectedCallback(){this.player===null&&(this.hidden=!0),super.connectedCallback()}attach(e){let t=y(e);this.api=t,this.keep(t.watch(()=>{this.render()})),this.render()}detach(){this.api=null,this.hidden=!0}paint(){var e;let t=this.api;if(t===null)return;let n=t.remote(),r=n.loaded&&Number.isFinite(n.duration);if(this.seek.root.hidden=!r,this.time.hidden=!r,!r)return;let i=(e=this.held)==null?n.time:e;this.seek.range(0,n.duration),this.seek.set(i,N(i,n.duration)),this.time.textContent=`${M(i)} / ${M(n.duration)}`}render(){var e,t,n,r,i;let a=this.api;if(a===null)return;let o=a.remote(),s=o.loaded&&!o.paused?`pause`:`play`;O(this.slots,s),this.play.setAttribute(`aria-label`,(e=this.getAttribute(`label-${s}`))==null?s===`play`?`Play`:`Pause`:e),this.seek.label((t=this.getAttribute(`label-seek`))==null?`Seek`:t),this.stop.textContent=(n=this.getAttribute(`label-stop`))==null?`Stop casting`:n;let c=a.state()===`casting`;this.hidden=!c,c&&(this.title_.textContent=A((r=this.getAttribute(`label`))==null?`Casting to {device}`:r,{device:(i=a.device())==null?``:i}),this.play.disabled=!o.loaded,this.paint())}};let B=`mbx-cast-button`,V=`mbx-cast-screen`;return customElements.get(`mbx-cast-button`)===void 0&&customElements.define(B,F),customElements.get(`mbx-cast-screen`)===void 0&&customElements.define(V,z),e.CAST_BUTTON=B,e.CAST_SCREEN=V,e.MbxCastButton=F,e.MbxCastScreen=z,e})({});
|
|
1
|
+
var matteboxPlayerCast=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){"@babel/helpers - typeof";return t=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},t(e)}function n(e,n){if(t(e)!=`object`||!e)return e;var r=e[Symbol.toPrimitive];if(r!==void 0){var i=r.call(e,n||`default`);if(t(i)!=`object`)return i;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(n===`string`?String:Number)(e)}function r(e){var r=n(e,`string`);return t(r)==`symbol`?r:r+``}function i(e,t,n){return(t=r(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?a(Object(n),!0).forEach(function(t){i(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function s(e){let t=e==null?void 0:e.live;return t!==void 0&&t.edge!==null}let c=`urn:x-cast:ch.mattebox.license`,l=null,u=null,d=null,f=null,p=/* @__PURE__ */ new Set,m=null,h={loaded:!1,paused:!0,time:0,duration:NaN},g=h;function _(){return globalThis}function v(){for(let e of[...p])e()}function y(e){var t;if(l!==null)return l;let n=_();return((t=n.cast)==null?void 0:t.framework)===void 0?`chrome`in n?(l=new Promise(t=>{let r=n.__onGCastApiAvailable;if(n.__onGCastApiAvailable=e=>{var n,i;r==null||r(e),t(e?(n=(i=_().cast)==null?void 0:i.framework)==null?null:n:null)},e===`none`)return;let i=document.createElement(`script`);i.src=`https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1`,i.async=!0,i.addEventListener(`error`,()=>t(null)),document.head.append(i)}),l):(l=Promise.resolve(null),l):(l=Promise.resolve(n.cast.framework),l)}function b(e,t){let n=e.CastContext.getInstance(),r=t==null?`CC1AD845`:t;if(u===null){var i,a;let t=(i=(a=_().chrome)==null||(a=a.cast)==null?void 0:a.AutoJoinPolicy.ORIGIN_SCOPED)==null?`origin_scoped`:i;n.setOptions({receiverApplicationId:r,autoJoinPolicy:t}),u=r,n.addEventListener(e.CastContextEventType.CAST_STATE_CHANGED,v),n.addEventListener(e.CastContextEventType.SESSION_STATE_CHANGED,t=>{var r;x(e,n,(r=t.sessionState)==null?``:r)}),d=new e.RemotePlayer,f=new e.RemotePlayerController(d),f.addEventListener(e.RemotePlayerEventType.ANY_CHANGE,()=>{let e=d;(e==null?void 0:e.isConnected)===!0&&e.isMediaLoaded&&(g={loaded:!0,paused:e.isPaused,time:e.currentTime,duration:e.duration>0?e.duration:1/0}),v()})}else t!==null&&t!==u&&console.error(`mattebox-player: the Cast context already uses receiver ${u}`);return n}function x(e,t,n){let r=e.SessionState;if(n===r.SESSION_STARTED&&m!==null&&m.pending)g=h,m.begin(t);else if(n===r.SESSION_RESUMED){var i;let e=(i=t.getCurrentSession())==null||(i=i.getMediaSession())==null||(i=i.media)==null?void 0:i.contentId,n=[...C].find(t=>t.plays(e));n!==void 0&&m===null&&(m=n,n.adopt(t))}else if(n===r.SESSION_ENDED||n===r.SESSION_START_FAILED){let e=m;m=null,e==null||e.end(n===r.SESSION_ENDED)}v()}let S=/* @__PURE__ */ new WeakMap,C=/* @__PURE__ */ new Set;var w=class{constructor(e){this.player=e,this.target=null,this.ctx=null,this.fw=null,this.pending=!1,this.casting=!1,this.handoff=null,this.listening=null}connect(e,t){C.add(this),y(t).then(t=>{t!==null&&(this.fw=t,this.ctx=b(t,e),v())})}disconnect(){C.delete(this)}state(){let e=this.ctx,t=this.fw;if(e===null||t===null)return`unavailable`;if(this.casting)return`casting`;let n=e.getCastState();return n===t.CastState.NO_DEVICES_AVAILABLE?`unavailable`:n===t.CastState.CONNECTING||this.pending?`connecting`:`idle`}device(){var e,t;return this.casting?(e=(t=this.ctx)==null||(t=t.getCurrentSession())==null?void 0:t.getCastDevice().friendlyName)==null?null:e:null}remote(){return g}start(e){let t=this.ctx;t===null||this.casting||(m!==null&&m!==this?t.endCurrentSession(!0):(this.target=e,this.pending=!0,m=this,v(),t.requestSession().catch(()=>{m===this&&(m=null),this.pending=!1,v()})))}stop(){var e;this.casting&&((e=this.ctx)==null||e.endCurrentSession(!0))}playPause(){this.casting&&(f==null||f.playOrPause())}seek(e){this.casting&&d!==null&&(d.currentTime=e,f==null||f.seek())}watch(e){return p.add(e),()=>{p.delete(e)}}plays(e){var t;return e!==void 0&&((t=this.player.player)==null||(t=t.session)==null?void 0:t.source.url)===e}begin(e){var t,n,r,i;this.pending=!1;let a=(t=(n=this.player.player)==null?void 0:n.session)==null?null:t,o=this.player.video,s=o.currentTime,c=!o.paused;if(this.freeze(),a===null)return;let l=this.request(a.source,s,c);if(l===null)return;this.listen(e.getCurrentSession());let u=new CustomEvent(`castload`,{detail:l,bubbles:!0,composed:!0,cancelable:!0});((r=this.target)==null?void 0:r.dispatchEvent(u))!==!1&&((i=e.getCurrentSession())==null||i.loadMedia(l).catch(()=>{}))}adopt(e){this.freeze(),this.listen(e.getCurrentSession())}listen(e){if(this.unlisten(),e===null)return;let t=(t,n)=>{let r;try{r=JSON.parse(n)}catch(e){return}if(r.type!==`unauthorized`)return;let i=r.id,a=!1,s={keySystem:typeof r.keySystem==`string`?r.keySystem:``,status:typeof r.status==`number`?r.status:0,reply(t){a||(a=!0,Promise.resolve(t).then(t=>e.sendMessage(c,o({type:`license`,id:i},t))).catch(()=>{}))}};this.player.dispatchEvent(new CustomEvent(`castunauthorized`,{detail:s,bubbles:!0}))};e.addMessageListener(c,t),this.listening={session:e,fn:t}}unlisten(){let e=this.listening;this.listening=null,e==null||e.session.removeMessageListener(`urn:x-cast:ch.mattebox.license`,e.fn)}freeze(){let e=this.player.engine;this.handoff={live:s(e)},this.player.video.pause(),e==null||e.suspend(),this.casting=!0,this.player.toggleAttribute(`casting`,!0),v()}end(e){if(this.pending=!1,this.unlisten(),!this.casting)return;this.casting=!1;let t=this.handoff;this.handoff=null;let n=this.player.video,r=this.player.engine;r==null||r.resume(),this.player.removeAttribute(`casting`),e&&g.loaded&&((t==null?void 0:t.live)!==!0&&Number.isFinite(g.time)&&(n.currentTime=g.time),g.paused||n.play().catch(()=>void 0))}request(e,t,n){var r,i;let a=(r=_().chrome)==null||(r=r.cast)==null?void 0:r.media;if(a===void 0)return null;let c=this.player.engine,l=(i=e.type)==null?``:i,u=new a.MediaInfo(e.url,l);if(u.streamType=s(c)?a.StreamType.LIVE:a.StreamType.BUFFERED,/mpegurl/i.test(l)){let e=T(c);u.hlsSegmentFormat=e?`ts`:`fmp4`,u.hlsVideoSegmentFormat=e?`mpeg2_ts`:`fmp4`}let d=[];for(let e of this.player.video.querySelectorAll(`track[src]`)){let t=e;if(t.kind!==`subtitles`&&t.kind!==`captions`)continue;let n=new a.Track(d.length+1,a.TrackType.TEXT);n.trackContentId=t.src,n.trackContentType=`text/vtt`,n.subtype=t.kind===`captions`?a.TextTrackType.CAPTIONS:a.TextTrackType.SUBTITLES,n.name=t.label,n.language=t.srclang,d.push(n)}u.tracks=d.length>0?d:null;let f=new a.LoadRequest(u);f.currentTime=t,f.autoplay=n;let p=e.drm;return p!==void 0&&(f.customData={mattebox:o(o(o({},p.licenseUrl===void 0?{}:{licenseUrl:p.licenseUrl}),p.licenseUrls===void 0?{}:{licenseUrls:p.licenseUrls}),p.certificateUrl===void 0?{}:{certificateUrl:p.certificateUrl})}),f}};function T(e){let t=e==null?void 0:e.stats.snapshot().presentation;if(t==null)return!1;for(let e of t.periods)for(let t of e.tracks)for(let e of t.renditions)if(/mp2t/i.test(e.mimeType))return!0;return!1}function E(e){let t=S.get(e);return t===void 0&&(t=new w(e),S.set(e,t)),t}function D(e){let t=e.parentNode;return t===null?e instanceof ShadowRoot?e.host:null:t}function O(e){let t=e;for(;t!==null;){if(t instanceof HTMLElement&&t.localName===`mattebox-player`)return t;t=D(t)}return null}var k=class extends HTMLElement{constructor(){super(),this.player=null,this.offs=[],this.epoch=0}connectedCallback(){let e=O(this);if(e===null)return;this.epoch+=1;let t=this.epoch,n=()=>{t===this.epoch&&this.isConnected&&(customElements.upgrade(e),`video`in e&&(this.player=e,this.attach(this.player)))};`video`in e?n():customElements.whenDefined(`mattebox-player`).then(n)}disconnectedCallback(){this.epoch+=1;for(let e of this.offs)e();this.offs=[];let e=this.player;e!==null&&(this.player=null,this.detach(e))}attributeChangedCallback(){this.player!==null&&this.render()}listen(e,t,n){for(let r of t)e.addEventListener(r,n);this.offs.push(()=>{for(let r of t)e.removeEventListener(r,n)})}keep(e){this.offs.push(e)}follow(e,t){let n,r=()=>{n==null||n(),n=t(e.engine)};this.listen(e,[`sourcechange`],r),this.offs.push(()=>{n==null||n(),n=void 0}),r()}observe(e,t,n,r=!1){let i=new MutationObserver(n);i.observe(e,{attributes:!0,attributeFilter:[...t],subtree:r}),this.offs.push(()=>{i.disconnect()})}detach(e){}render(){}};let A={play:`M9 5L26 16L9 27z`,pause:`M8 6h5.5v20h-5.5zM18.5 6h5.5v20h-5.5z`,cast:`M4 6H28V26H20V23.5H25.5V8.5H6.5V11H4zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z`,"cast-active":`M4 6H28V26H20A16 16 0 0 0 4 10zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z`},j=`http://www.w3.org/2000/svg`;function M(e){let t=document.createElementNS(j,`svg`);t.setAttribute(`viewBox`,`0 0 32 32`),t.setAttribute(`aria-hidden`,`true`),t.setAttribute(`part`,`icon`);let n=document.createElementNS(j,`path`);return n.setAttribute(`fill-rule`,`evenodd`),n.setAttribute(`d`,A[e]),t.append(n),t}function N(e){let t=document.createElement(`style`);return t.textContent=e,t}function P(e,t){let n={};for(let r of e){let e=document.createElement(`slot`);e.name=`icon-${r}`,e.append(t(r)),e.hidden=!0,n[r]=e}return n}function F(e,t){for(let n of Object.keys(e))e[n].hidden=n!==t}function I(e,t,n){let r=document.createElement(e);return r.setAttribute(`part`,t),n!==void 0&&(r.textContent=n),r}function L(e,t){return e.replace(/\{(\w+)\}/g,(e,n)=>{let r=t[n];return r===void 0?e:String(r)})}function R(e){return e<10?`0${e}`:`${e}`}function z(e){let t=Number.isFinite(e)&&e>0?Math.floor(e):0,n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60;return n>0?`${n}:${R(r)}:${R(i)}`:`${r}:${R(i)}`}function B(e,t){return Number.isFinite(t)?`${z(e)} of ${z(t)}`:z(e)}let V=[`default`,`active`];var H=class extends k{static get observedAttributes(){return[`label-start`,`label-stop`]}constructor(){super(),this.api=null;let e=this.attachShadow({mode:`open`});this.button=document.createElement(`button`),this.button.type=`button`,this.button.setAttribute(`part`,`button`),this.slots=P(V,e=>M(e===`active`?`cast-active`:`cast`));for(let e of V)this.button.append(this.slots[e]);this.button.addEventListener(`click`,()=>{let e=this.api;e!==null&&(e.state()===`casting`?e.stop():e.start(this))}),e.append(N(`:host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:2.5em;height:2.5em;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;opacity:.9;background:0 0;border:0;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}[part~=button]:hover{opacity:1}[part~=button]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=button]:focus:not(:focus-visible){outline:none}[part~=icon],::slotted(*){fill:currentColor;width:1.75em;height:1.75em}slot[hidden]{display:none}`),this.button)}attach(e){let t=E(e);this.api=t,t.connect(this.getAttribute(`receiver`),this.getAttribute(`sdk`)),this.keep(t.watch(()=>{this.render()})),this.follow(e,()=>{this.render()})}detach(){var e;(e=this.api)==null||e.disconnect(),this.api=null}render(){var e,t,n;let r=this.player,i=this.api;if(r===null||i===null)return;let a=i.state(),o=a===`casting`;this.hidden=a===`unavailable`,this.button.disabled=!o&&((e=r.player)==null?void 0:e.session)==null,this.button.toggleAttribute(`aria-busy`,a===`connecting`),F(this.slots,o?`active`:`default`),this.button.setAttribute(`aria-label`,o?(t=this.getAttribute(`label-stop`))==null?`Stop casting`:t:(n=this.getAttribute(`label-start`))==null?`Cast`:n)}};function U(e,t,n){return Math.min(n,Math.max(t,e))}function W(e){let{onInput:t}=e,n=I(`div`,`slider`);n.setAttribute(`role`,`slider`),n.tabIndex=0;let r=I(`div`,`rail`),i=I(`div`,`track`),a=I(`div`,`fill`),o=I(`div`,`thumb`);i.append(a),r.append(i,o),n.append(r);let s=0,c=1,l=0,u=!1;function d(){let e=`${(c>s?(l-s)/(c-s):0)*100}%`;a.style.width=e,o.style.left=e}function f(e){let t=r.getBoundingClientRect();return t.width===0?s:s+U((e-t.left)/t.width,0,1)*(c-s)}function p(t){u=t,e.onDrag(t)}function m(e){if(e.button===0){e.preventDefault(),p(!0);try{n.setPointerCapture(e.pointerId)}catch(e){}t(f(e.clientX))}}function h(e){u&&(e.buttons===0?g(e):t(f(e.clientX)))}function g(e){u&&(p(!1),t(f(e.clientX)))}function _(){u&&p(!1)}function v(n){let r;switch(n.key){case`ArrowRight`:case`ArrowUp`:r=l+e.step();break;case`ArrowLeft`:case`ArrowDown`:r=l-e.step();break;case`PageUp`:r=l+e.page();break;case`PageDown`:r=l-e.page();break;case`Home`:r=s;break;case`End`:r=c;break;default:return}n.preventDefault(),t(U(r,s,c))}return n.addEventListener(`pointerdown`,m),n.addEventListener(`pointermove`,h),n.addEventListener(`pointerup`,g),n.addEventListener(`pointercancel`,_),n.addEventListener(`lostpointercapture`,_),n.addEventListener(`keydown`,v),{root:n,track:i,rail:r,label(e){n.setAttribute(`aria-label`,e)},dragging(){return u},range(e,t){s=e,c=t,n.setAttribute(`aria-valuemin`,String(e)),n.setAttribute(`aria-valuemax`,String(t)),d()},set(e,t){l=U(e,s,c),n.setAttribute(`aria-valuenow`,String(l)),n.setAttribute(`aria-valuetext`,t),d()},dispose(){n.removeEventListener(`pointerdown`,m),n.removeEventListener(`pointermove`,h),n.removeEventListener(`pointerup`,g),n.removeEventListener(`pointercancel`,_),n.removeEventListener(`lostpointercapture`,_),n.removeEventListener(`keydown`,v)}}}let G=[`play`,`pause`];var K=class extends k{static get observedAttributes(){return[`label`,`label-stop`,`label-play`,`label-pause`,`label-seek`]}constructor(){super(),this.api=null,this.held=null;let e=this.attachShadow({mode:`open`}),t=I(`div`,`box`);this.title_=I(`div`,`title`),this.play=document.createElement(`button`),this.play.type=`button`,this.play.setAttribute(`part`,`button play`),this.slots=P(G,M);for(let e of G)this.play.append(this.slots[e]);this.play.addEventListener(`click`,()=>{var e;(e=this.api)==null||e.playPause()}),this.seek=W({step:()=>5,page:()=>30,onInput:e=>{var t;this.seek.dragging()?(this.held=e,this.paint()):(this.held=null,(t=this.api)==null||t.seek(e))},onDrag:e=>{this.toggleAttribute(`dragging`,e),e||(this.held=null)}}),this.time=I(`span`,`time`),this.row=I(`div`,`row`),this.row.append(this.play,this.seek.root,this.time),this.stop=I(`button`,`stop`),this.stop.type=`button`,this.stop.addEventListener(`click`,()=>{var e;(e=this.api)==null||e.stop()}),t.append(this.title_,this.row,this.stop),e.append(N(`:host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:2.5em;height:2.5em;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;opacity:.9;background:0 0;border:0;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}[part~=button]:hover{opacity:1}[part~=button]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=button]:focus:not(:focus-visible){outline:none}[part~=icon],::slotted(*){fill:currentColor;width:1.75em;height:1.75em}slot[hidden]{display:none}:host{display:block}:host([hidden]){display:none}[part~=slider]{border-radius:var(--mbx-radius);cursor:pointer;touch-action:none;height:2.6667em;position:relative}[part~=slider]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=slider]:focus:not(:focus-visible){outline:none}[part~=rail]{position:absolute;top:0;bottom:0;left:.5333em;right:.5333em}[part~=track]{background:#ffffff59;border-radius:2px;height:.2667em;position:absolute;top:50%;left:0;right:0;overflow:hidden;transform:translateY(-50%)}[part~=fill]{background:var(--mbx-accent);position:absolute;top:0;bottom:0;left:0}[part~=thumb]{background:var(--mbx-text);pointer-events:none;border-radius:50%;width:.8em;height:.8em;margin:-.4em 0 0 -.4em;position:absolute;top:50%}:host{color:var(--mbx-text);font:400 .9375em / 1.4 var(--mbx-font);text-align:center;background:#000000d9;justify-content:center;align-items:center;padding:1.0667em;display:flex;position:absolute;top:0;bottom:0;left:0;right:0}:host([hidden]){display:none}[part~=box]{flex-direction:column;align-items:center;width:100%;max-width:28em;display:flex}[part~=box]>:not([hidden])~:not([hidden]){margin-top:.8em}[part~=title]{font-size:1.2em;font-weight:600}[part~=row]{justify-content:center;align-items:center;width:100%;display:flex}[part~=row]>:not([hidden])~:not([hidden]){margin-left:.8em}[part~=slider]{flex:1}[part~=time]{font-variant-numeric:tabular-nums;color:var(--mbx-muted);font-size:.8667em}[part~=stop]{height:2.4em;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;background:0 0;border:1px solid;padding:0 1.0667em;font-weight:600}[part~=stop]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=stop]:focus:not(:focus-visible){outline:none}[hidden]{display:none}`),t)}connectedCallback(){this.player===null&&(this.hidden=!0),super.connectedCallback()}attach(e){let t=E(e);this.api=t,this.keep(t.watch(()=>{this.render()})),this.render()}detach(){this.api=null,this.hidden=!0}paint(){var e;let t=this.api;if(t===null)return;let n=t.remote(),r=n.loaded&&Number.isFinite(n.duration);if(this.seek.root.hidden=!r,this.time.hidden=!r,!r)return;let i=(e=this.held)==null?n.time:e;this.seek.range(0,n.duration),this.seek.set(i,B(i,n.duration)),this.time.textContent=`${z(i)} / ${z(n.duration)}`}render(){var e,t,n,r,i;let a=this.api;if(a===null)return;let o=a.remote(),s=o.loaded&&!o.paused?`pause`:`play`;F(this.slots,s),this.play.setAttribute(`aria-label`,(e=this.getAttribute(`label-${s}`))==null?s===`play`?`Play`:`Pause`:e),this.seek.label((t=this.getAttribute(`label-seek`))==null?`Seek`:t),this.stop.textContent=(n=this.getAttribute(`label-stop`))==null?`Stop casting`:n;let c=a.state()===`casting`;this.hidden=!c,c&&(this.title_.textContent=L((r=this.getAttribute(`label`))==null?`Casting to {device}`:r,{device:(i=a.device())==null?``:i}),this.play.disabled=!o.loaded,this.paint())}};let q=`mbx-cast-button`,J=`mbx-cast-screen`;return customElements.get(`mbx-cast-button`)===void 0&&customElements.define(q,H),customElements.get(`mbx-cast-screen`)===void 0&&customElements.define(J,K),e.CAST_BUTTON=q,e.CAST_SCREEN=J,e.LICENSE_NAMESPACE=c,e.MbxCastButton=H,e.MbxCastScreen=K,e})({});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import toPropertyKey from "./toPropertyKey.js";
|
|
2
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/defineProperty.js
|
|
3
|
+
function _defineProperty(e, r, t) {
|
|
4
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
5
|
+
value: t,
|
|
6
|
+
enumerable: !0,
|
|
7
|
+
configurable: !0,
|
|
8
|
+
writable: !0
|
|
9
|
+
}) : e[r] = t, e;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { _defineProperty as default };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import _defineProperty from "./defineProperty.js";
|
|
2
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/objectSpread2.js
|
|
3
|
+
function ownKeys(e, r) {
|
|
4
|
+
var t = Object.keys(e);
|
|
5
|
+
if (Object.getOwnPropertySymbols) {
|
|
6
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
7
|
+
r && (o = o.filter(function(r) {
|
|
8
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
9
|
+
})), t.push.apply(t, o);
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
}
|
|
13
|
+
function _objectSpread2(e) {
|
|
14
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
15
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
16
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
|
|
17
|
+
_defineProperty(e, r, t[r]);
|
|
18
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
|
|
19
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return e;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { _objectSpread2 as default };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import _typeof from "./typeof.js";
|
|
2
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/toPrimitive.js
|
|
3
|
+
function toPrimitive(t, r) {
|
|
4
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
5
|
+
var e = t[Symbol.toPrimitive];
|
|
6
|
+
if (void 0 !== e) {
|
|
7
|
+
var i = e.call(t, r || "default");
|
|
8
|
+
if ("object" != _typeof(i)) return i;
|
|
9
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
10
|
+
}
|
|
11
|
+
return ("string" === r ? String : Number)(t);
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { toPrimitive as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import _typeof from "./typeof.js";
|
|
2
|
+
import toPrimitive from "./toPrimitive.js";
|
|
3
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/toPropertyKey.js
|
|
4
|
+
function toPropertyKey(t) {
|
|
5
|
+
var i = toPrimitive(t, "string");
|
|
6
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { toPropertyKey as default };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region \0@oxc-project+runtime@0.154.0/helpers/esm/typeof.js
|
|
2
|
+
function _typeof(o) {
|
|
3
|
+
"@babel/helpers - typeof";
|
|
4
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
5
|
+
return typeof o;
|
|
6
|
+
} : function(o) {
|
|
7
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
8
|
+
}, _typeof(o);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { _typeof as default };
|
|
@@ -4,7 +4,7 @@ import { icon } from "./icons.js";
|
|
|
4
4
|
import { BUTTON_STYLE, SLIDER_STYLE, describe, el, fill, format, iconSlots, show, style } from "./shared.js";
|
|
5
5
|
import { slider } from "./slider.js";
|
|
6
6
|
//#region src/cast-screen.ts
|
|
7
|
-
const STYLE_CSS = ":host{color:var(--mbx-text);font:400
|
|
7
|
+
const STYLE_CSS = ":host{color:var(--mbx-text);font:400 .9375em / 1.4 var(--mbx-font);text-align:center;background:#000000d9;justify-content:center;align-items:center;padding:1.0667em;display:flex;position:absolute;top:0;bottom:0;left:0;right:0}:host([hidden]){display:none}[part~=box]{flex-direction:column;align-items:center;width:100%;max-width:28em;display:flex}[part~=box]>:not([hidden])~:not([hidden]){margin-top:.8em}[part~=title]{font-size:1.2em;font-weight:600}[part~=row]{justify-content:center;align-items:center;width:100%;display:flex}[part~=row]>:not([hidden])~:not([hidden]){margin-left:.8em}[part~=slider]{flex:1}[part~=time]{font-variant-numeric:tabular-nums;color:var(--mbx-muted);font-size:.8667em}[part~=stop]{height:2.4em;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;background:0 0;border:1px solid;padding:0 1.0667em;font-weight:600}[part~=stop]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=stop]:focus:not(:focus-visible){outline:none}[hidden]{display:none}";
|
|
8
8
|
const STATES = ["play", "pause"];
|
|
9
9
|
const STEP = 5;
|
|
10
10
|
const PAGE = 30;
|
package/dist/es2015/cast.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import _objectSpread2 from "./_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/objectSpread2.js";
|
|
1
2
|
//#region src/cast.ts
|
|
2
3
|
/** Whether the session is live: the engine's `live` namespace, once it has an edge. */
|
|
3
4
|
function live(engine) {
|
|
4
5
|
const api = engine === null || engine === void 0 ? void 0 : engine.live;
|
|
5
6
|
return api !== void 0 && api.edge !== null;
|
|
6
7
|
}
|
|
8
|
+
/** The custom namespace a receiver asks the sender for a new license token on. */
|
|
9
|
+
const LICENSE_NAMESPACE = "urn:x-cast:ch.mattebox.license";
|
|
7
10
|
/** The Default Media Receiver: Google's player, which plays HLS and DASH by itself. */
|
|
8
11
|
const DEFAULT_RECEIVER = "CC1AD845";
|
|
9
12
|
const SDK_URL = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1";
|
|
@@ -104,7 +107,7 @@ function onSession(fw, ctx, state) {
|
|
|
104
107
|
const found = [...connected].find((cast) => cast.plays(playing));
|
|
105
108
|
if (found !== void 0 && owner === null) {
|
|
106
109
|
owner = found;
|
|
107
|
-
found.adopt();
|
|
110
|
+
found.adopt(ctx);
|
|
108
111
|
}
|
|
109
112
|
} else if (state === states.SESSION_ENDED || state === states.SESSION_START_FAILED) {
|
|
110
113
|
const ended = owner;
|
|
@@ -126,6 +129,7 @@ var CastOf = class {
|
|
|
126
129
|
this.pending = false;
|
|
127
130
|
this.casting = false;
|
|
128
131
|
this.handoff = null;
|
|
132
|
+
this.listening = null;
|
|
129
133
|
}
|
|
130
134
|
connect(receiver, sdk) {
|
|
131
135
|
connected.add(this);
|
|
@@ -209,6 +213,7 @@ var CastOf = class {
|
|
|
209
213
|
if (session === null) return;
|
|
210
214
|
const request = this.request(session.source, time, autoplay);
|
|
211
215
|
if (request === null) return;
|
|
216
|
+
this.listen(ctx.getCurrentSession());
|
|
212
217
|
const event = new CustomEvent("castload", {
|
|
213
218
|
detail: request,
|
|
214
219
|
bubbles: true,
|
|
@@ -219,8 +224,54 @@ var CastOf = class {
|
|
|
219
224
|
(_ctx$getCurrentSessio2 = ctx.getCurrentSession()) === null || _ctx$getCurrentSessio2 === void 0 || _ctx$getCurrentSessio2.loadMedia(request).catch(() => {});
|
|
220
225
|
}
|
|
221
226
|
/** A session Chrome rejoined, already playing this player's source. */
|
|
222
|
-
adopt() {
|
|
227
|
+
adopt(ctx) {
|
|
223
228
|
this.freeze();
|
|
229
|
+
this.listen(ctx.getCurrentSession());
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Answers the receiver's token requests for this session: a
|
|
233
|
+
* `castunauthorized` event on the player, and the page's reply sent back.
|
|
234
|
+
*/
|
|
235
|
+
listen(session) {
|
|
236
|
+
this.unlisten();
|
|
237
|
+
if (session === null) return;
|
|
238
|
+
const fn = (_namespace, message) => {
|
|
239
|
+
let data;
|
|
240
|
+
try {
|
|
241
|
+
data = JSON.parse(message);
|
|
242
|
+
} catch (_unused) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (data.type !== "unauthorized") return;
|
|
246
|
+
const id = data.id;
|
|
247
|
+
let replied = false;
|
|
248
|
+
const detail = {
|
|
249
|
+
keySystem: typeof data.keySystem === "string" ? data.keySystem : "",
|
|
250
|
+
status: typeof data.status === "number" ? data.status : 0,
|
|
251
|
+
reply(reply) {
|
|
252
|
+
if (replied) return;
|
|
253
|
+
replied = true;
|
|
254
|
+
Promise.resolve(reply).then((answer) => session.sendMessage(LICENSE_NAMESPACE, _objectSpread2({
|
|
255
|
+
type: "license",
|
|
256
|
+
id
|
|
257
|
+
}, answer))).catch(() => {});
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
this.player.dispatchEvent(new CustomEvent("castunauthorized", {
|
|
261
|
+
detail,
|
|
262
|
+
bubbles: true
|
|
263
|
+
}));
|
|
264
|
+
};
|
|
265
|
+
session.addMessageListener(LICENSE_NAMESPACE, fn);
|
|
266
|
+
this.listening = {
|
|
267
|
+
session,
|
|
268
|
+
fn
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
unlisten() {
|
|
272
|
+
const held = this.listening;
|
|
273
|
+
this.listening = null;
|
|
274
|
+
held === null || held === void 0 || held.session.removeMessageListener("urn:x-cast:ch.mattebox.license", held.fn);
|
|
224
275
|
}
|
|
225
276
|
freeze() {
|
|
226
277
|
const engine = this.player.engine;
|
|
@@ -234,6 +285,7 @@ var CastOf = class {
|
|
|
234
285
|
/** The session ended: give the video back where the receiver left it. */
|
|
235
286
|
end(cleanly) {
|
|
236
287
|
this.pending = false;
|
|
288
|
+
this.unlisten();
|
|
237
289
|
if (!this.casting) return;
|
|
238
290
|
this.casting = false;
|
|
239
291
|
const handoff = this.handoff;
|
|
@@ -276,6 +328,8 @@ var CastOf = class {
|
|
|
276
328
|
const request = new media.LoadRequest(info);
|
|
277
329
|
request.currentTime = time;
|
|
278
330
|
request.autoplay = autoplay;
|
|
331
|
+
const drm = source.drm;
|
|
332
|
+
if (drm !== void 0) request.customData = { mattebox: _objectSpread2(_objectSpread2(_objectSpread2({}, drm.licenseUrl === void 0 ? {} : { licenseUrl: drm.licenseUrl }), drm.licenseUrls === void 0 ? {} : { licenseUrls: drm.licenseUrls }), drm.certificateUrl === void 0 ? {} : { certificateUrl: drm.certificateUrl }) };
|
|
279
333
|
return request;
|
|
280
334
|
}
|
|
281
335
|
};
|
|
@@ -296,4 +350,4 @@ function cast(player) {
|
|
|
296
350
|
return held;
|
|
297
351
|
}
|
|
298
352
|
//#endregion
|
|
299
|
-
export { cast };
|
|
353
|
+
export { LICENSE_NAMESPACE, cast };
|
package/dist/es2015/icons.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
//#region src/icons.ts
|
|
2
2
|
/** Each glyph's subpaths joined into one `d`, drawn even-odd like the player's. */
|
|
3
3
|
const PATHS = {
|
|
4
|
-
play: "
|
|
5
|
-
pause: "M8
|
|
6
|
-
cast: "M4
|
|
7
|
-
"cast-active": "M4
|
|
4
|
+
play: "M9 5L26 16L9 27z",
|
|
5
|
+
pause: "M8 6h5.5v20h-5.5zM18.5 6h5.5v20h-5.5z",
|
|
6
|
+
cast: "M4 6H28V26H20V23.5H25.5V8.5H6.5V11H4zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z",
|
|
7
|
+
"cast-active": "M4 6H28V26H20A16 16 0 0 0 4 10zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z"
|
|
8
8
|
};
|
|
9
9
|
const SVG = "http://www.w3.org/2000/svg";
|
|
10
10
|
/** A glyph, hidden from the accessibility tree: the button it sits in carries the name. */
|
package/dist/es2015/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LICENSE_NAMESPACE } from "./cast.js";
|
|
1
2
|
import { MbxCastButton } from "./cast-button.js";
|
|
2
3
|
import { MbxCastScreen } from "./cast-screen.js";
|
|
3
4
|
//#region src/index.ts
|
|
@@ -14,4 +15,4 @@ const CAST_SCREEN = "mbx-cast-screen";
|
|
|
14
15
|
if (customElements.get("mbx-cast-button") === void 0) customElements.define(CAST_BUTTON, MbxCastButton);
|
|
15
16
|
if (customElements.get("mbx-cast-screen") === void 0) customElements.define(CAST_SCREEN, MbxCastScreen);
|
|
16
17
|
//#endregion
|
|
17
|
-
export { CAST_BUTTON, CAST_SCREEN, MbxCastButton, MbxCastScreen };
|
|
18
|
+
export { CAST_BUTTON, CAST_SCREEN, LICENSE_NAMESPACE, MbxCastButton, MbxCastScreen };
|
package/dist/es2015/shared.js
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* package. The tokens come through the `--mbx-*` custom properties the
|
|
8
8
|
* player sets, which inherit into every control.
|
|
9
9
|
*/
|
|
10
|
-
const BUTTON_STYLE_CSS = ":host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:
|
|
11
|
-
const SLIDER_STYLE_CSS = ":host{display:block}:host([hidden]){display:none}[part~=slider]{border-radius:var(--mbx-radius);cursor:pointer;touch-action:none;height:
|
|
10
|
+
const BUTTON_STYLE_CSS = ":host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:2.5em;height:2.5em;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;opacity:.9;background:0 0;border:0;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}[part~=button]:hover{opacity:1}[part~=button]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=button]:focus:not(:focus-visible){outline:none}[part~=icon],::slotted(*){fill:currentColor;width:1.75em;height:1.75em}slot[hidden]{display:none}";
|
|
11
|
+
const SLIDER_STYLE_CSS = ":host{display:block}:host([hidden]){display:none}[part~=slider]{border-radius:var(--mbx-radius);cursor:pointer;touch-action:none;height:2.6667em;position:relative}[part~=slider]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=slider]:focus:not(:focus-visible){outline:none}[part~=rail]{position:absolute;top:0;bottom:0;left:.5333em;right:.5333em}[part~=track]{background:#ffffff59;border-radius:2px;height:.2667em;position:absolute;top:50%;left:0;right:0;overflow:hidden;transform:translateY(-50%)}[part~=fill]{background:var(--mbx-accent);position:absolute;top:0;bottom:0;left:0}[part~=thumb]{background:var(--mbx-text);pointer-events:none;border-radius:50%;width:.8em;height:.8em;margin:-.4em 0 0 -.4em;position:absolute;top:50%}";
|
|
12
12
|
const BUTTON_STYLE = BUTTON_STYLE_CSS;
|
|
13
13
|
/** The style of a slider: the rail, the track with its fill, and the thumb. */
|
|
14
14
|
/** The style of a slider: the rail, the track with its fill, and the thumb. */
|
package/dist/icons.d.ts
CHANGED
|
@@ -1,31 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The play and
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Copied, not depended on. The notice below is the license's one condition,
|
|
6
|
-
* and packages/player/NOTICE repeats it for the published tarball.
|
|
7
|
-
*
|
|
8
|
-
* MIT License
|
|
9
|
-
*
|
|
10
|
-
* Copyright (c) 2023 Rahim Alwer
|
|
11
|
-
*
|
|
12
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
14
|
-
* in the Software without restriction, including without limitation the rights
|
|
15
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
17
|
-
* furnished to do so, subject to the following conditions:
|
|
18
|
-
*
|
|
19
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
20
|
-
* copies or substantial portions of the Software.
|
|
21
|
-
*
|
|
22
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
-
* SOFTWARE.
|
|
2
|
+
* The play, pause and cast glyphs, Mattebox's own drawings and the same
|
|
3
|
+
* ones the player draws: filled paths on a 32-unit viewBox. The cast glyph
|
|
4
|
+
* is a screen with a corner open for three arcs, filled while casting.
|
|
29
5
|
*/
|
|
30
6
|
export type IconName = 'play' | 'pause' | 'cast' | 'cast-active';
|
|
31
7
|
/** A glyph, hidden from the accessibility tree: the button it sits in carries the name. */
|
package/dist/icons.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC;AAajE,2FAA2F;AAC3F,wBAAgB,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa,CAUlD"}
|
package/dist/icons.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
//#region src/icons.ts
|
|
2
2
|
/** Each glyph's subpaths joined into one `d`, drawn even-odd like the player's. */
|
|
3
3
|
const PATHS = {
|
|
4
|
-
play: "
|
|
5
|
-
pause: "M8
|
|
6
|
-
cast: "M4
|
|
7
|
-
"cast-active": "M4
|
|
4
|
+
play: "M9 5L26 16L9 27z",
|
|
5
|
+
pause: "M8 6h5.5v20h-5.5zM18.5 6h5.5v20h-5.5z",
|
|
6
|
+
cast: "M4 6H28V26H20V23.5H25.5V8.5H6.5V11H4zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z",
|
|
7
|
+
"cast-active": "M4 6H28V26H20A16 16 0 0 0 4 10zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z"
|
|
8
8
|
};
|
|
9
9
|
const SVG = "http://www.w3.org/2000/svg";
|
|
10
10
|
/** A glyph, hidden from the accessibility tree: the button it sits in carries the name. */
|
package/dist/icons.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.js","names":[],"sources":["../src/icons.ts"],"sourcesContent":["/**\n * The play and
|
|
1
|
+
{"version":3,"file":"icons.js","names":[],"sources":["../src/icons.ts"],"sourcesContent":["/**\n * The play, pause and cast glyphs, Mattebox's own drawings and the same\n * ones the player draws: filled paths on a 32-unit viewBox. The cast glyph\n * is a screen with a corner open for three arcs, filled while casting.\n */\n\nexport type IconName = 'play' | 'pause' | 'cast' | 'cast-active';\n\n/** Each glyph's subpaths joined into one `d`, drawn even-odd like the player's. */\nconst PATHS: Readonly<Record<IconName, string>> = {\n play: 'M9 5L26 16L9 27z',\n pause: 'M8 6h5.5v20h-5.5zM18.5 6h5.5v20h-5.5z',\n cast: 'M4 6H28V26H20V23.5H25.5V8.5H6.5V11H4zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z',\n 'cast-active':\n 'M4 6H28V26H20A16 16 0 0 0 4 10zM4 23h3v3h-3zM4 17.5A8.5 8.5 0 0 1 12.5 26L10 26A6 6 0 0 0 4 20zM4 12A14 14 0 0 1 18 26L15.5 26A11.5 11.5 0 0 0 4 14.5z',\n};\n\nconst SVG = 'http://www.w3.org/2000/svg';\n\n/** A glyph, hidden from the accessibility tree: the button it sits in carries the name. */\nexport function icon(name: IconName): SVGSVGElement {\n const svg = document.createElementNS(SVG, 'svg');\n svg.setAttribute('viewBox', '0 0 32 32');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('part', 'icon');\n const path = document.createElementNS(SVG, 'path');\n path.setAttribute('fill-rule', 'evenodd');\n path.setAttribute('d', PATHS[name]);\n svg.append(path);\n return svg;\n}\n"],"mappings":";;AASA,MAAM,QAA4C;CAChD,MAAM;CACN,OAAO;CACP,MAAM;CACN,eACE;AACJ;AAEA,MAAM,MAAM;;AAGZ,SAAgB,KAAK,MAA+B;CAClD,MAAM,MAAM,SAAS,gBAAgB,KAAK,KAAK;CAC/C,IAAI,aAAa,WAAW,WAAW;CACvC,IAAI,aAAa,eAAe,MAAM;CACtC,IAAI,aAAa,QAAQ,MAAM;CAC/B,MAAM,OAAO,SAAS,gBAAgB,KAAK,MAAM;CACjD,KAAK,aAAa,aAAa,SAAS;CACxC,KAAK,aAAa,KAAK,MAAM,KAAK;CAClC,IAAI,OAAO,IAAI;CACf,OAAO;AACT"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { MbxCastButton } from './cast-button.js';
|
|
10
10
|
import { MbxCastScreen } from './cast-screen.js';
|
|
11
|
-
export type { CastState, LoadRequest as CastLoadRequest, MediaInfo, Track } from './cast.js';
|
|
11
|
+
export type { CastState, LicenseReply, LoadRequest as CastLoadRequest, MatteboxCustomData, MediaInfo, Track, UnauthorizedDetail, } from './cast.js';
|
|
12
|
+
export { LICENSE_NAMESPACE } from './cast.js';
|
|
12
13
|
export { MbxCastButton } from './cast-button.js';
|
|
13
14
|
export { MbxCastScreen } from './cast-screen.js';
|
|
14
15
|
export declare const CAST_BUTTON = "mbx-cast-button";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,IAAI,eAAe,EAC9B,kBAAkB,EAClB,SAAS,EACT,KAAK,EACL,kBAAkB,GACnB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAC7C,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAS7C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;QACjC,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LICENSE_NAMESPACE } from "./cast.js";
|
|
1
2
|
import { MbxCastButton } from "./cast-button.js";
|
|
2
3
|
import { MbxCastScreen } from "./cast-screen.js";
|
|
3
4
|
//#region src/index.ts
|
|
@@ -14,6 +15,6 @@ const CAST_SCREEN = "mbx-cast-screen";
|
|
|
14
15
|
if (customElements.get("mbx-cast-button") === void 0) customElements.define(CAST_BUTTON, MbxCastButton);
|
|
15
16
|
if (customElements.get("mbx-cast-screen") === void 0) customElements.define(CAST_SCREEN, MbxCastScreen);
|
|
16
17
|
//#endregion
|
|
17
|
-
export { CAST_BUTTON, CAST_SCREEN, MbxCastButton, MbxCastScreen };
|
|
18
|
+
export { CAST_BUTTON, CAST_SCREEN, LICENSE_NAMESPACE, MbxCastButton, MbxCastScreen };
|
|
18
19
|
|
|
19
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @mattebox/player-cast: <mbx-cast-button> and <mbx-cast-screen>, Chromecast\n * from the player over Google's sender SDK. Importing this module registers\n * both elements; that is the package's one side effect. It is a package of\n * its own because the button loads Google's script onto the page, which the\n * player never does on an integrator's behalf: the AirPlay button, over\n * Safari's own API, ships with the player.\n */\nimport { MbxCastButton } from './cast-button.js';\nimport { MbxCastScreen } from './cast-screen.js';\n\nexport type {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @mattebox/player-cast: <mbx-cast-button> and <mbx-cast-screen>, Chromecast\n * from the player over Google's sender SDK. Importing this module registers\n * both elements; that is the package's one side effect. It is a package of\n * its own because the button loads Google's script onto the page, which the\n * player never does on an integrator's behalf: the AirPlay button, over\n * Safari's own API, ships with the player.\n */\nimport { MbxCastButton } from './cast-button.js';\nimport { MbxCastScreen } from './cast-screen.js';\n\nexport type {\n CastState,\n LicenseReply,\n LoadRequest as CastLoadRequest,\n MatteboxCustomData,\n MediaInfo,\n Track,\n UnauthorizedDetail,\n} from './cast.js';\nexport { LICENSE_NAMESPACE } from './cast.js';\nexport { MbxCastButton } from './cast-button.js';\nexport { MbxCastScreen } from './cast-screen.js';\n\nexport const CAST_BUTTON = 'mbx-cast-button';\nexport const CAST_SCREEN = 'mbx-cast-screen';\n\nif (customElements.get(CAST_BUTTON) === undefined) {\n customElements.define(CAST_BUTTON, MbxCastButton);\n}\nif (customElements.get(CAST_SCREEN) === undefined) {\n customElements.define(CAST_SCREEN, MbxCastScreen);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mbx-cast-button': MbxCastButton;\n 'mbx-cast-screen': MbxCastScreen;\n }\n}\n"],"mappings":";;;;;;;;;;;;AAwBA,MAAa,cAAc;AAC3B,MAAa,cAAc;AAE3B,IAAI,eAAe,IAAA,iBAAe,MAAM,KAAA,GACtC,eAAe,OAAO,aAAa,aAAa;AAElD,IAAI,eAAe,IAAA,iBAAe,MAAM,KAAA,GACtC,eAAe,OAAO,aAAa,aAAa"}
|
package/dist/shared.js
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* package. The tokens come through the `--mbx-*` custom properties the
|
|
8
8
|
* player sets, which inherit into every control.
|
|
9
9
|
*/
|
|
10
|
-
const BUTTON_STYLE_CSS = ":host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:
|
|
11
|
-
const SLIDER_STYLE_CSS = ":host{display:block}:host([hidden]){display:none}[part~=slider]{border-radius:var(--mbx-radius);cursor:pointer;touch-action:none;height:
|
|
10
|
+
const BUTTON_STYLE_CSS = ":host{display:inline-flex}:host([hidden]){display:none}[part~=button]{width:2.5em;height:2.5em;font:inherit;color:inherit;border-radius:var(--mbx-radius);cursor:pointer;opacity:.9;background:0 0;border:0;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}[part~=button]:hover{opacity:1}[part~=button]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=button]:focus:not(:focus-visible){outline:none}[part~=icon],::slotted(*){fill:currentColor;width:1.75em;height:1.75em}slot[hidden]{display:none}";
|
|
11
|
+
const SLIDER_STYLE_CSS = ":host{display:block}:host([hidden]){display:none}[part~=slider]{border-radius:var(--mbx-radius);cursor:pointer;touch-action:none;height:2.6667em;position:relative}[part~=slider]:focus{outline:2px solid var(--mbx-accent);outline-offset:-2px}[part~=slider]:focus:not(:focus-visible){outline:none}[part~=rail]{position:absolute;top:0;bottom:0;left:.5333em;right:.5333em}[part~=track]{background:#ffffff59;border-radius:2px;height:.2667em;position:absolute;top:50%;left:0;right:0;overflow:hidden;transform:translateY(-50%)}[part~=fill]{background:var(--mbx-accent);position:absolute;top:0;bottom:0;left:0}[part~=thumb]{background:var(--mbx-text);pointer-events:none;border-radius:50%;width:.8em;height:.8em;margin:-.4em 0 0 -.4em;position:absolute;top:50%}";
|
|
12
12
|
const BUTTON_STYLE = BUTTON_STYLE_CSS;
|
|
13
13
|
/** The style of a slider: the rail, the track with its fill, and the thumb. */
|
|
14
14
|
/** The style of a slider: the rail, the track with its fill, and the thumb. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mattebox/player-cast",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "<mbx-cast-button> and <mbx-cast-screen>: Chromecast from <mattebox-player>, over Google's sender SDK.",
|
|
5
5
|
"author": "Josep Boix Requesens",
|
|
6
6
|
"repository": {
|
|
@@ -37,8 +37,7 @@
|
|
|
37
37
|
"./package.json": "./package.json"
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
|
-
"dist"
|
|
41
|
-
"NOTICE"
|
|
40
|
+
"dist"
|
|
42
41
|
],
|
|
43
42
|
"scripts": {
|
|
44
43
|
"clean": "rm -rf dist",
|
|
@@ -50,10 +49,10 @@
|
|
|
50
49
|
"release:ci": "semantic-release"
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
53
|
-
"@mattebox/player-core": "^0.
|
|
52
|
+
"@mattebox/player-core": "^0.6.1"
|
|
54
53
|
},
|
|
55
54
|
"peerDependencies": {
|
|
56
|
-
"@mattebox/player": ">=0.
|
|
57
|
-
"mattebox": "^0.
|
|
55
|
+
"@mattebox/player": ">=0.10.0",
|
|
56
|
+
"mattebox": "^0.15.0"
|
|
58
57
|
}
|
|
59
58
|
}
|
package/NOTICE
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
@mattebox/player-cast carries two glyphs copied from media-icons
|
|
2
|
-
(https://github.com/vidstack/media-icons), used under the MIT License:
|
|
3
|
-
|
|
4
|
-
MIT License
|
|
5
|
-
|
|
6
|
-
Copyright (c) 2023 Rahim Alwer
|
|
7
|
-
|
|
8
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
-
in the Software without restriction, including without limitation the rights
|
|
11
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
-
furnished to do so, subject to the following conditions:
|
|
14
|
-
|
|
15
|
-
The above copyright notice and this permission notice shall be included in all
|
|
16
|
-
copies or substantial portions of the Software.
|
|
17
|
-
|
|
18
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
-
SOFTWARE.
|