@mux/mux-player
Advanced tools
Comparing version 0.1.0-canary.10-2039108 to 0.1.0-canary.10-77d0386
@@ -6,2 +6,6 @@ # Change Log | ||
# [0.1.0-beta.23](https://github.com/muxinc/elements/compare/@mux/mux-player@0.1.0-beta.22...@mux/mux-player@0.1.0-beta.23) (2022-07-11) | ||
**Note:** Version bump only for package @mux/mux-player | ||
# [0.1.0-beta.22](https://github.com/muxinc/elements/compare/@mux/mux-player@0.1.0-beta.21...@mux/mux-player@0.1.0-beta.22) (2022-07-05) | ||
@@ -8,0 +12,0 @@ |
@@ -16,6 +16,4 @@ import MuxPlayerElement from '.'; | ||
}) => string; | ||
export declare function castThemeName(themeName?: string): string | undefined; | ||
export declare function toPropName(attrName: string): string; | ||
export declare const getTestMediaEl: (nodeName?: string) => HTMLMediaElement | undefined; | ||
export declare const hasVolumeSupportAsync: (mediaEl?: HTMLMediaElement | undefined) => Promise<boolean>; | ||
export declare function getCcSubTracks(el: MuxPlayerElement): TextTrack[]; | ||
export declare const getLiveTime: (el: MuxPlayerElement) => number | undefined; | ||
@@ -22,0 +20,0 @@ export declare const seekToLive: (el: MuxPlayerElement) => void; |
@@ -19,1 +19,6 @@ import { TemplateInstance, NodeTemplatePart } from '@github/template-parts'; | ||
export declare function createTemplateInstance(content: string, props?: any): TemplateInstance; | ||
export declare const unsafeStatic: (...values: any[]) => { | ||
$static$: (TemplateResult | { | ||
strings: any[]; | ||
})[]; | ||
}; |
@@ -12,5 +12,2 @@ import '@mux/playback-core'; | ||
}; | ||
declare type MediaController = Element & { | ||
media: HTMLVideoElement; | ||
}; | ||
declare class MuxPlayerElement extends VideoApiElement { | ||
@@ -17,0 +14,0 @@ private "MuxPlayerElement.#private"; |
@@ -1,15 +0,19 @@ | ||
import 'media-chrome'; | ||
import { MediaTheme } from 'media-chrome'; | ||
import '../media-chrome/time-display'; | ||
declare type ThemeMuxTemplateProps = { | ||
streamType: string; | ||
streamType: string | null; | ||
audio: boolean; | ||
playerSize: string; | ||
playerSize: string | null; | ||
defaultHiddenCaptions: boolean; | ||
hasCaptions: boolean; | ||
forwardSeekOffset: number; | ||
backwardSeekOffset: number; | ||
forwardSeekOffset: string | null; | ||
backwardSeekOffset: string | null; | ||
}; | ||
export default class MediaThemeMux extends MediaTheme { | ||
static readonly observedAttributes: string[]; | ||
attributeChangedCallback(): void; | ||
render(): void; | ||
} | ||
export declare const AudioVodChrome: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
export declare const AudioDvrChrome: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
export declare const AudioLiveChrome: (_props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
export declare const AudioLiveChrome: () => import("../html").TemplateResult; | ||
export declare const VodChromeExtraSmall: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
@@ -24,7 +28,2 @@ export declare const VodChromeSmall: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
export declare const DvrChromeLarge: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
declare class MediaThemeMux extends HTMLElement { | ||
static readonly observedAttributes: string[]; | ||
constructor(); | ||
attributeChangedCallback(): void; | ||
} | ||
export default MediaThemeMux; | ||
export {}; |
@@ -16,6 +16,4 @@ import type MuxPlayerElement from '.'; | ||
}) => string; | ||
export declare function castThemeName(themeName?: string): string | undefined; | ||
export declare function toPropName(attrName: string): string; | ||
export declare const getTestMediaEl: (nodeName?: string) => HTMLMediaElement | undefined; | ||
export declare const hasVolumeSupportAsync: (mediaEl?: HTMLMediaElement | undefined) => Promise<boolean>; | ||
export declare function getCcSubTracks(el: MuxPlayerElement): TextTrack[]; | ||
export declare const getLiveTime: (el: MuxPlayerElement) => number | undefined; | ||
@@ -22,0 +20,0 @@ export declare const seekToLive: (el: MuxPlayerElement) => void; |
@@ -19,1 +19,6 @@ import { TemplateInstance, NodeTemplatePart } from '@github/template-parts'; | ||
export declare function createTemplateInstance(content: string, props?: any): TemplateInstance; | ||
export declare const unsafeStatic: (...values: any[]) => { | ||
$static$: (TemplateResult | { | ||
strings: any[]; | ||
})[]; | ||
}; |
@@ -12,5 +12,2 @@ import '@mux/playback-core'; | ||
}; | ||
declare type MediaController = Element & { | ||
media: HTMLVideoElement; | ||
}; | ||
declare class MuxPlayerElement extends VideoApiElement { | ||
@@ -17,0 +14,0 @@ #private; |
@@ -1,15 +0,19 @@ | ||
import 'media-chrome'; | ||
import { MediaTheme } from 'media-chrome'; | ||
import '../media-chrome/time-display'; | ||
declare type ThemeMuxTemplateProps = { | ||
streamType: string; | ||
streamType: string | null; | ||
audio: boolean; | ||
playerSize: string; | ||
playerSize: string | null; | ||
defaultHiddenCaptions: boolean; | ||
hasCaptions: boolean; | ||
forwardSeekOffset: number; | ||
backwardSeekOffset: number; | ||
forwardSeekOffset: string | null; | ||
backwardSeekOffset: string | null; | ||
}; | ||
export default class MediaThemeMux extends MediaTheme { | ||
static get observedAttributes(): string[]; | ||
attributeChangedCallback(): void; | ||
render(): void; | ||
} | ||
export declare const AudioVodChrome: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
export declare const AudioDvrChrome: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
export declare const AudioLiveChrome: (_props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
export declare const AudioLiveChrome: () => import("../html").TemplateResult; | ||
export declare const VodChromeExtraSmall: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
@@ -24,7 +28,2 @@ export declare const VodChromeSmall: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
export declare const DvrChromeLarge: (props: ThemeMuxTemplateProps) => import("../html").TemplateResult; | ||
declare class MediaThemeMux extends HTMLElement { | ||
static get observedAttributes(): string[]; | ||
constructor(); | ||
attributeChangedCallback(): void; | ||
} | ||
export default MediaThemeMux; | ||
export {}; |
{ | ||
"name": "@mux/mux-player", | ||
"version": "0.1.0-canary.10-2039108", | ||
"version": "0.1.0-canary.10-77d0386", | ||
"description": "An open source Mux player web component that Just Works™", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.cjs.js", |
@@ -59,2 +59,9 @@ import { toQuery, camelCase } from './utils'; | ||
export function castThemeName(themeName?: string): string | undefined { | ||
if (themeName && /^media-theme-[\w-]+$/.test(themeName)) { | ||
return themeName; | ||
} | ||
return undefined; | ||
} | ||
const attrToPropNameMap: Record<string, string> = { | ||
@@ -69,26 +76,2 @@ crossorigin: 'crossOrigin', | ||
let testMediaEl: HTMLMediaElement | undefined; | ||
export const getTestMediaEl = (nodeName = 'video') => { | ||
if (testMediaEl) return testMediaEl; | ||
if (typeof window !== 'undefined') { | ||
testMediaEl = document.createElement(nodeName as 'video' | 'audio'); | ||
} | ||
return testMediaEl; | ||
}; | ||
export const hasVolumeSupportAsync = async (mediaEl: HTMLMediaElement | undefined = getTestMediaEl()) => { | ||
if (!mediaEl) return false; | ||
const prevVolume = mediaEl.volume; | ||
mediaEl.volume = prevVolume / 2 + 0.1; | ||
return new Promise<boolean>((resolve, reject) => { | ||
setTimeout(() => { | ||
resolve(mediaEl.volume !== prevVolume); | ||
}, 0); | ||
}); | ||
}; | ||
export function getCcSubTracks(el: MuxPlayerElement) { | ||
return Array.from(el.media?.textTracks ?? []).filter(({ kind }) => kind === 'subtitles' || kind === 'captions'); | ||
} | ||
export const getLiveTime = (el: MuxPlayerElement) => { | ||
@@ -95,0 +78,0 @@ const { media } = el; |
@@ -152,4 +152,45 @@ import { TemplateInstance, NodeTemplatePart, createProcessor, AttributeTemplatePart } from '@github/template-parts'; | ||
const stringsCache = new Map(); | ||
const defaultProcessor = createProcessor(processPart); | ||
export function html(strings: TemplateStringsArray, ...values: unknown[]): TemplateResult { | ||
const staticStrings: any = ['']; | ||
const dynamicValues: any[] = []; | ||
let staticValues; | ||
let hasStatics = false; | ||
// Here the unsafe static values are moved from the string expressions | ||
// to the static strings so they can be used in the cache key and later | ||
// be used to generate the HTML via the <template> element. | ||
const join = (strs: TemplateStringsArray, vals: any[] = []) => { | ||
staticStrings[staticStrings.length - 1] = staticStrings[staticStrings.length - 1] + strs[0]; | ||
vals.forEach((dynamicValue, i) => { | ||
if ((staticValues = dynamicValue?.$static$) !== undefined) { | ||
staticValues.forEach((staticValue: TemplateResult) => { | ||
join(staticValue.strings, staticValue.values); | ||
}); | ||
staticStrings[staticStrings.length - 1] = staticStrings[staticStrings.length - 1] + strs[i + 1]; | ||
hasStatics = true; | ||
} else { | ||
dynamicValues.push(dynamicValue); | ||
staticStrings.push(strs[i + 1]); | ||
} | ||
}); | ||
}; | ||
join(strings, values); | ||
if (hasStatics) { | ||
// Tagged template literals with the same static strings return the same | ||
// TemplateStringsArray, aka they are cached. emulate this behavior w/ a Map. | ||
const key = staticStrings.join('$$html$$'); | ||
strings = stringsCache.get(key); | ||
if (strings === undefined) { | ||
(staticStrings as any).raw = staticStrings; | ||
stringsCache.set(key, (strings = staticStrings)); | ||
} | ||
values = dynamicValues; | ||
} | ||
return new TemplateResult(strings, values, defaultProcessor); | ||
@@ -167,1 +208,10 @@ } | ||
} | ||
export const unsafeStatic = (...values: any[]) => ({ | ||
['$static$']: values.map((value) => { | ||
if (value instanceof TemplateResult) return value; | ||
// Only allow word characters and dashes for security. | ||
if (!/\w-/.test(value)) return { strings: [] }; | ||
return { strings: [value] }; | ||
}), | ||
}); |
@@ -5,14 +5,6 @@ // import playback-core here to make sure that the polyfill is loaded | ||
import { MediaController } from 'media-chrome'; | ||
import MediaThemeMux from './media-theme-mux/media-theme-mux'; | ||
import MuxVideoElement, { MediaError } from '@mux/mux-video'; | ||
import { Metadata, StreamTypes } from '@mux/playback-core'; | ||
import VideoApiElement, { initVideoApi } from './video-api'; | ||
import { | ||
getCcSubTracks, | ||
getPlayerVersion, | ||
hasVolumeSupportAsync, | ||
isInLiveWindow, | ||
seekToLive, | ||
toPropName, | ||
} from './helpers'; | ||
import { getPlayerVersion, isInLiveWindow, seekToLive, toPropName } from './helpers'; | ||
import { template } from './template'; | ||
@@ -32,4 +24,2 @@ import { render } from './html'; | ||
type MediaController = Element & { media: HTMLVideoElement }; | ||
const streamTypeValues = Object.values(StreamTypes); | ||
@@ -97,2 +87,3 @@ | ||
poster: el.getAttribute('poster'), | ||
theme: el.getAttribute('theme'), | ||
thumbnailTime: !el.tokens.thumbnail && el.thumbnailTime, | ||
@@ -125,3 +116,2 @@ autoplay: el.autoplay, | ||
playerSize: getPlayerSize(el.mediaController ?? el), | ||
hasCaptions: !!getCcSubTracks(el).length, | ||
// NOTE: In order to guarantee all expected metadata props are set "from the outside" when used | ||
@@ -154,4 +144,2 @@ // and to guarantee they'll all be set *before* the playback id is set, using attr values here (CJP) | ||
...initialState, | ||
supportsAirPlay: false, | ||
supportsVolume: false, | ||
onCloseErrorDialog: () => this.#setState({ dialog: undefined, isDialogOpen: false }), | ||
@@ -193,15 +181,21 @@ onInitFocusDialog: (e) => { | ||
// even before they are connected to the main document. | ||
customElements.upgrade(this.theme as Node); | ||
if (!(this.theme instanceof MediaThemeMux)) { | ||
logger.error('<media-theme-mux> failed to upgrade!'); | ||
try { | ||
customElements.upgrade(this.theme as Node); | ||
if (!(this.theme instanceof HTMLElement)) throw ''; | ||
} catch (error) { | ||
logger.error(`<${this.theme?.localName}> failed to upgrade!`); | ||
} | ||
customElements.upgrade(this.media as Node); | ||
if (!(this.media instanceof MuxVideoElement)) { | ||
try { | ||
customElements.upgrade(this.media as Node); | ||
if (!(this.media instanceof MuxVideoElement)) throw ''; | ||
} catch (error) { | ||
logger.error('<mux-video> failed to upgrade!'); | ||
} | ||
customElements.upgrade(this.mediaController as Node); | ||
if (!(this.mediaController instanceof MediaController)) { | ||
logger.error('<media-controller> failed to upgrade!'); | ||
try { | ||
customElements.upgrade(this.mediaController as Node); | ||
if (!(this.mediaController instanceof MediaController)) throw ''; | ||
} catch (error) { | ||
logger.error(`<media-controller> failed to upgrade!`); | ||
} | ||
@@ -222,4 +216,2 @@ | ||
this.#setUpCaptionsButton(); | ||
this.#setUpAirplayButton(); | ||
this.#setUpVolumeRange(); | ||
this.#monitorLiveWindow(); | ||
@@ -502,18 +494,2 @@ this.#userInactive = this.mediaController?.hasAttribute('user-inactive') ?? true; | ||
#setUpAirplayButton() { | ||
if (!!(globalThis as any).WebKitPlaybackTargetAvailabilityEvent) { | ||
const onPlaybackTargetAvailability = (evt: any) => { | ||
const supportsAirPlay = evt.availability === 'available'; | ||
this.#setState({ supportsAirPlay }); | ||
}; | ||
this.media?.addEventListener('webkitplaybacktargetavailabilitychanged', onPlaybackTargetAvailability); | ||
} | ||
} | ||
async #setUpVolumeRange() { | ||
const supportsVolume = await hasVolumeSupportAsync(); | ||
this.#setState({ supportsVolume }); | ||
} | ||
attributeChangedCallback(attrName: string, oldValue: string | null, newValue: string) { | ||
@@ -520,0 +496,0 @@ if (!this.#isInit) { |
@@ -1,2 +0,2 @@ | ||
import 'media-chrome'; | ||
import { MediaTheme } from 'media-chrome'; | ||
import { html, render } from '../html'; | ||
@@ -17,24 +17,57 @@ import '../media-chrome/time-display'; | ||
type ThemeMuxTemplateProps = { | ||
streamType: string; | ||
streamType: string | null; | ||
audio: boolean; | ||
playerSize: string; | ||
playerSize: string | null; | ||
defaultHiddenCaptions: boolean; | ||
hasCaptions: boolean; | ||
forwardSeekOffset: number; | ||
backwardSeekOffset: number; | ||
forwardSeekOffset: string | null; | ||
backwardSeekOffset: string | null; | ||
}; | ||
const template = (props: ThemeMuxTemplateProps) => html` | ||
<style> | ||
${cssStr} | ||
</style> | ||
export default class MediaThemeMux extends MediaTheme { | ||
static get observedAttributes() { | ||
return [ | ||
'audio', | ||
'stream-type', | ||
'player-size', | ||
'default-hidden-captions', | ||
'forward-seek-offset', | ||
'backward-seek-offset', | ||
]; | ||
} | ||
<media-controller audio="${props.audio || false}" class="size-${props.playerSize}"> | ||
<slot name="media" slot="media"></slot> | ||
<media-loading-indicator slot="centered-chrome" no-auto-hide></media-loading-indicator> | ||
${ChromeRenderer(props)} | ||
<slot></slot> | ||
</media-controller> | ||
`; | ||
attributeChangedCallback() { | ||
this.render(); | ||
} | ||
render() { | ||
const props = { | ||
audio: this.hasAttribute('audio'), | ||
streamType: this.getAttribute('stream-type'), | ||
playerSize: this.getAttribute('player-size'), | ||
defaultHiddenCaptions: this.hasAttribute('default-hidden-captions'), | ||
forwardSeekOffset: this.getAttribute('forward-seek-offset'), | ||
backwardSeekOffset: this.getAttribute('backward-seek-offset'), | ||
}; | ||
render( | ||
html` | ||
<style> | ||
${cssStr} | ||
</style> | ||
<media-controller audio="${props.audio || false}" class="size-${props.playerSize}"> | ||
<slot name="media" slot="media"></slot> | ||
<media-loading-indicator slot="centered-chrome" no-auto-hide></media-loading-indicator> | ||
${ChromeRenderer(props)} | ||
<slot></slot> | ||
</media-controller> | ||
`, | ||
this.shadowRoot as Node | ||
); | ||
} | ||
} | ||
if (!customElements.get('media-theme-mux')) { | ||
customElements.define('media-theme-mux', MediaThemeMux); | ||
} | ||
const ChromeRenderer = (props: ThemeMuxTemplateProps) => { | ||
@@ -46,3 +79,3 @@ const { streamType, playerSize, audio } = props; | ||
case StreamTypes.LL_LIVE: { | ||
return AudioLiveChrome(props); | ||
return AudioLiveChrome(); | ||
} | ||
@@ -185,3 +218,3 @@ case StreamTypes.DVR: | ||
export const AudioLiveChrome = (_props: ThemeMuxTemplateProps) => html` | ||
export const AudioLiveChrome = () => html` | ||
<media-control-bar> | ||
@@ -200,3 +233,3 @@ ${MediaPlayButton()} | ||
<media-control-bar slot="top-chrome"> | ||
${props.hasCaptions ? MediaCaptionsButton(props) : html``} | ||
${MediaCaptionsButton(props)} | ||
<div class="mxp-spacer"></div> | ||
@@ -220,3 +253,3 @@ ${MediaAirplayButton()} | ||
<media-control-bar slot="top-chrome" style="justify-content: flex-end;"> | ||
${props.hasCaptions ? MediaCaptionsButton(props) : html``} | ||
${MediaCaptionsButton(props)} | ||
${MediaAirplayButton()} | ||
@@ -258,3 +291,3 @@ <media-cast-button></media-cast-button> | ||
<media-playback-rate-button></media-playback-rate-button> | ||
${props.hasCaptions ? MediaCaptionsButton(props) : html``} | ||
${MediaCaptionsButton(props)} | ||
${MediaAirplayButton()} | ||
@@ -276,3 +309,3 @@ <media-cast-button></media-cast-button> | ||
<div class="mxp-spacer"></div> | ||
${props.hasCaptions ? MediaCaptionsButton(props) : html``} | ||
${MediaCaptionsButton(props)} | ||
${MediaAirplayButton()} | ||
@@ -305,3 +338,3 @@ <media-cast-button></media-cast-button> | ||
<div class="mxp-spacer"></div> | ||
${props.hasCaptions ? MediaCaptionsButton(props) : html``} | ||
${MediaCaptionsButton(props)} | ||
${MediaAirplayButton()} | ||
@@ -320,3 +353,3 @@ <media-cast-button></media-cast-button> | ||
<media-control-bar slot="top-chrome" style="justify-content: flex-end;"> | ||
${props.hasCaptions ? MediaCaptionsButton(props) : html``} | ||
${MediaCaptionsButton(props)} | ||
${MediaAirplayButton()} | ||
@@ -356,3 +389,3 @@ <media-cast-button></media-cast-button> | ||
<div class="mxp-spacer"></div> | ||
${props.hasCaptions ? MediaCaptionsButton(props) : html``} | ||
${MediaCaptionsButton(props)} | ||
${MediaAirplayButton()} | ||
@@ -365,45 +398,1 @@ <media-cast-button></media-cast-button> | ||
`; | ||
function getProps(el: MediaThemeMux, state?: any): ThemeMuxTemplateProps { | ||
return { | ||
audio: el.hasAttribute('audio'), | ||
streamType: el.getAttribute('stream-type'), | ||
playerSize: el.getAttribute('player-size'), | ||
defaultHiddenCaptions: el.hasAttribute('default-hidden-captions'), | ||
hasCaptions: el.hasAttribute('has-captions'), | ||
forwardSeekOffset: el.getAttribute('forward-seek-offset'), | ||
backwardSeekOffset: el.getAttribute('backward-seek-offset'), | ||
...state, | ||
}; | ||
} | ||
class MediaThemeMux extends HTMLElement { | ||
static get observedAttributes() { | ||
return [ | ||
'audio', | ||
'stream-type', | ||
'player-size', | ||
'default-hidden-captions', | ||
'has-captions', | ||
'forward-seek-offset', | ||
'backward-seek-offset', | ||
]; | ||
} | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: 'open' }); | ||
render(template(getProps(this)), this.shadowRoot as Node); | ||
} | ||
attributeChangedCallback() { | ||
render(template(getProps(this)), this.shadowRoot as Node); | ||
} | ||
} | ||
if (!customElements.get('media-theme-mux')) { | ||
customElements.define('media-theme-mux', MediaThemeMux); | ||
} | ||
export default MediaThemeMux; |
import './media-theme-mux/media-theme-mux'; | ||
import './dialog'; | ||
import { getSrcFromPlaybackId, getPosterURLFromPlaybackId, getStoryboardURLFromPlaybackId } from './helpers'; | ||
import { html } from './html'; | ||
import { | ||
castThemeName, | ||
getSrcFromPlaybackId, | ||
getPosterURLFromPlaybackId, | ||
getStoryboardURLFromPlaybackId, | ||
} from './helpers'; | ||
import { html, unsafeStatic } from './html'; | ||
// @ts-ignore | ||
@@ -20,14 +25,15 @@ import cssStr from './styles.css'; | ||
export const content = (props: MuxTemplateProps) => html` | ||
<media-theme-mux | ||
<${unsafeStatic(castThemeName(props.theme) ?? 'media-theme-mux')} | ||
audio="${props.audio || false}" | ||
style="${stylePropsToString({ | ||
'--primary-color': props.primaryColor, | ||
'--secondary-color': props.secondaryColor, | ||
'--mux-time-range-padding': props.secondaryColor ? '0' : null, | ||
'--media-range-track-border-radius': props.secondaryColor ? '0' : null, | ||
}) ?? false}" | ||
style="${ | ||
stylePropsToString({ | ||
'--primary-color': props.primaryColor, | ||
'--secondary-color': props.secondaryColor, | ||
'--mux-time-range-padding': props.secondaryColor ? '0' : null, | ||
'--media-range-track-border-radius': props.secondaryColor ? '0' : null, | ||
}) ?? false | ||
}" | ||
class="size-${props.playerSize}" | ||
stream-type="${props.streamType}" | ||
player-size="${props.playerSize}" | ||
has-captions="${props.hasCaptions}" | ||
default-hidden-captions="${props.defaultHiddenCaptions}" | ||
@@ -57,36 +63,44 @@ forward-seek-offset="${props.forwardSeekOffset}" | ||
custom-domain="${props.customDomain ?? false}" | ||
src="${!!props.src | ||
? props.src | ||
: props.playbackId | ||
? getSrcFromPlaybackId(props.playbackId, { domain: props.customDomain, token: props.tokens.playback }) | ||
: false}" | ||
poster="${!!props.poster | ||
? props.poster | ||
: props.playbackId && !props.audio | ||
? getPosterURLFromPlaybackId(props.playbackId, { | ||
domain: props.customDomain, | ||
thumbnailTime: props.thumbnailTime ?? props.startTime, | ||
token: props.tokens.thumbnail, | ||
}) | ||
: false}" | ||
cast-src="${!!props.src | ||
? props.src | ||
: props.playbackId | ||
? getSrcFromPlaybackId(props.playbackId, { domain: props.customDomain, token: props.tokens.playback }) | ||
: false}" | ||
src="${ | ||
!!props.src | ||
? props.src | ||
: props.playbackId | ||
? getSrcFromPlaybackId(props.playbackId, { domain: props.customDomain, token: props.tokens.playback }) | ||
: false | ||
}" | ||
poster="${ | ||
!!props.poster | ||
? props.poster | ||
: props.playbackId && !props.audio | ||
? getPosterURLFromPlaybackId(props.playbackId, { | ||
domain: props.customDomain, | ||
thumbnailTime: props.thumbnailTime ?? props.startTime, | ||
token: props.tokens.thumbnail, | ||
}) | ||
: false | ||
}" | ||
cast-src="${ | ||
!!props.src | ||
? props.src | ||
: props.playbackId | ||
? getSrcFromPlaybackId(props.playbackId, { domain: props.customDomain, token: props.tokens.playback }) | ||
: false | ||
}" | ||
cast-stream-type="${[StreamTypes.LIVE, StreamTypes.LL_LIVE].includes(props.streamType as any) ? 'live' : false}" | ||
> | ||
${props.playbackId && | ||
!props.audio && | ||
![StreamTypes.LIVE, StreamTypes.LL_LIVE, StreamTypes.DVR, StreamTypes.LL_DVR].includes(props.streamType as any) | ||
? html`<track | ||
label="thumbnails" | ||
default | ||
kind="metadata" | ||
src="${getStoryboardURLFromPlaybackId(props.playbackId, { | ||
domain: props.customDomain, | ||
token: props.tokens.storyboard, | ||
})}" | ||
/>` | ||
: html``} | ||
${ | ||
props.playbackId && | ||
!props.audio && | ||
![StreamTypes.LIVE, StreamTypes.LL_LIVE, StreamTypes.DVR, StreamTypes.LL_DVR].includes(props.streamType as any) | ||
? html`<track | ||
label="thumbnails" | ||
default | ||
kind="metadata" | ||
src="${getStoryboardURLFromPlaybackId(props.playbackId, { | ||
domain: props.customDomain, | ||
token: props.tokens.storyboard, | ||
})}" | ||
/>` | ||
: html`` | ||
} | ||
</mux-video> | ||
@@ -116,14 +130,16 @@ <button | ||
${props.dialog?.message} | ||
${props.dialog?.linkUrl | ||
? html`<a | ||
href="${props.dialog.linkUrl}" | ||
target="_blank" | ||
rel="external noopener" | ||
aria-label="${props.dialog.linkText ?? ''} ${i18n(`(opens in a new window)`)}" | ||
>${props.dialog.linkText ?? props.dialog.linkUrl}</a | ||
>` | ||
: html``} | ||
${ | ||
props.dialog?.linkUrl | ||
? html`<a | ||
href="${props.dialog.linkUrl}" | ||
target="_blank" | ||
rel="external noopener" | ||
aria-label="${props.dialog.linkText ?? ''} ${i18n(`(opens in a new window)`)}" | ||
>${props.dialog.linkText ?? props.dialog.linkUrl}</a | ||
>` | ||
: html`` | ||
} | ||
</p> | ||
</mxp-dialog> | ||
</media-theme-mux> | ||
</${unsafeStatic(castThemeName(props.theme) ?? 'media-theme-mux')}> | ||
`; |
@@ -9,7 +9,5 @@ import type MuxVideoElement, { MediaError } from '@mux/mux-video'; | ||
audio: boolean; | ||
theme?: string; | ||
playerSize: string; | ||
showLoading: boolean; | ||
hasCaptions: boolean; | ||
supportsAirPlay: boolean; | ||
supportsVolume: boolean; | ||
thumbnailTime: number; | ||
@@ -16,0 +14,0 @@ primaryColor: string; |
@@ -14,3 +14,3 @@ import { assert } from '@open-wc/testing'; | ||
minify(div.innerHTML), | ||
'<media-theme-mux class="size-" stream-type="" player-size="" has-captions="" default-hidden-captions="" forward-seek-offset="" backward-seek-offset=""><mux-video slot="media" crossorigin="" playsinline="" player-software-name="" player-software-version=""></mux-video><button slot="seek-to-live-button" aria-disabled="" class="mxp-seek-to-live-button">\n Live\n </button><mxp-dialog no-auto-hide="" open=""><p></p></mxp-dialog></media-theme-mux>' | ||
'<media-theme-mux class="size-" stream-type="" player-size="" default-hidden-captions="" forward-seek-offset="" backward-seek-offset=""><mux-video slot="media" crossorigin="" playsinline="" player-software-name="" player-software-version=""></mux-video><button slot="seek-to-live-button" aria-disabled="" class="mxp-seek-to-live-button">\n Live\n </button><mxp-dialog no-auto-hide="" open=""><p></p></mxp-dialog></media-theme-mux>' | ||
); | ||
@@ -33,3 +33,3 @@ }); | ||
minify(div.innerHTML), | ||
'<media-theme-mux class="size-extra-small" stream-type="on-demand" player-size="extra-small" has-captions="" default-hidden-captions="" forward-seek-offset="" backward-seek-offset=""><mux-video slot="media" crossorigin="" playsinline="" player-software-name="" player-software-version="" stream-type="on-demand"></mux-video><button slot="seek-to-live-button" aria-disabled="" class="mxp-seek-to-live-button">\n Live\n </button><mxp-dialog no-auto-hide="" open=""><h3>Errr</h3><p></p></mxp-dialog></media-theme-mux>' | ||
'<media-theme-mux class="size-extra-small" stream-type="on-demand" player-size="extra-small" default-hidden-captions="" forward-seek-offset="" backward-seek-offset=""><mux-video slot="media" crossorigin="" playsinline="" player-software-name="" player-software-version="" stream-type="on-demand"></mux-video><button slot="seek-to-live-button" aria-disabled="" class="mxp-seek-to-live-button">\n Live\n </button><mxp-dialog no-auto-hide="" open=""><h3>Errr</h3><p></p></mxp-dialog></media-theme-mux>' | ||
); | ||
@@ -50,3 +50,3 @@ }); | ||
minify(div.innerHTML), | ||
'<media-theme-mux class="size-large" stream-type="on-demand" player-size="large" has-captions="" default-hidden-captions="" forward-seek-offset="" backward-seek-offset=""><mux-video slot="media" crossorigin="" playsinline="" player-software-name="" player-software-version="" stream-type="on-demand"></mux-video><button slot="seek-to-live-button" aria-disabled="" class="mxp-seek-to-live-button">\n Live\n </button><mxp-dialog no-auto-hide="" open=""><p></p></mxp-dialog></media-theme-mux>' | ||
'<media-theme-mux class="size-large" stream-type="on-demand" player-size="large" default-hidden-captions="" forward-seek-offset="" backward-seek-offset=""><mux-video slot="media" crossorigin="" playsinline="" player-software-name="" player-software-version="" stream-type="on-demand"></mux-video><button slot="seek-to-live-button" aria-disabled="" class="mxp-seek-to-live-button">\n Live\n </button><mxp-dialog no-auto-hide="" open=""><p></p></mxp-dialog></media-theme-mux>' | ||
); | ||
@@ -53,0 +53,0 @@ }); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
13973
1708718