> = {
'hls-video': 'hls-video',
'mux-video': 'mux-video',
'mux-audio': 'mux-audio',
'native-hls-video': 'native-hls-video',
'simple-hls-video': 'simple-hls-video',
'simple-hls-audio-only': 'simple-hls-audio-only',
'dash-video': 'dash-video',
audio: 'audio',
'background-video': 'background-video',
};
return tags[preset] ?? 'video';
}
function loadStylesheets(preset: Preset, skin: Skin) {
if (isAudioPreset(preset)) loadAudioStylesheets(skin);
else if (preset !== 'background-video') loadVideoStylesheets(skin);
// Background CSS is loaded via dynamic import in loadCdnPreset.
}
function isVideoPreset(preset: Preset): boolean {
return (
preset === 'video' ||
preset === 'hls-video' ||
preset === 'mux-video' ||
preset === 'native-hls-video' ||
preset === 'simple-hls-video' ||
preset === 'dash-video'
);
}
function canPlayLive(preset: Preset): boolean {
return (
preset === 'hls-video' || preset === 'mux-video' || preset === 'native-hls-video' || preset === 'simple-hls-video'
);
}
async function render() {
const live = canPlayLive(preset) && isLiveSource(state.source);
await loadLatest(async () => {
await loadCdnPreset(preset, state.skin, live);
await loadCdnMedia(preset);
});
loadStylesheets(preset, state.skin);
const root = document.getElementById('root')!;
const playerTag = getPlayerTag(preset, live);
const skinTag = getSkinTag(preset, state.skin, live);
const mediaTag = getMediaTag(preset);
const source = SOURCES[state.source];
const storyboard = isVideoPreset(preset) ? getStoryboardSrc(state.source) : undefined;
const poster = isVideoPreset(preset) ? getPosterSrc(state.source) : undefined;
const sourceAttr = preset === 'background-video' ? `src="${BACKGROUND_VIDEO_SRC}"` : `src="${source.url}"`;
const mediaAttrs = renderMediaAttrs(state);
// Background video needs viewport dimensions instead of flex centering.
if (preset === 'background-video') {
root.className = '';
root.style.cssText = 'width: 100vw; height: 100vh;';
}
if (preset === 'background-video') {
root.innerHTML = html`
<${playerTag}>
<${skinTag}>
<${mediaTag} ${sourceAttr}>${mediaTag}>
${skinTag}>
${playerTag}>
`;
return;
}
if (isAudioPreset(preset)) {
root.innerHTML = html`
<${playerTag}>
<${skinTag}>
<${mediaTag} ${sourceAttr} ${mediaAttrs}>${mediaTag}>
${skinTag}>
${playerTag}>
`;
return;
}
root.innerHTML = html`
<${playerTag}>
<${skinTag} class="aspect-video max-w-4xl mx-auto">
<${mediaTag} ${sourceAttr} ${mediaAttrs} playsinline crossorigin="anonymous">
${renderStoryboard(storyboard)}
${mediaTag}>
${poster ? html`
` : ''}
${skinTag}>
${playerTag}>
`;
}
render();
onSkinChange((skin) => {
state.skin = skin;
render();
});
onSourceChange((source) => {
state.source = source;
render();
});
onAutoplayChange((autoplay) => {
state.autoplay = autoplay;
render();
});
onMutedChange((muted) => {
state.muted = muted;
render();
});
onLoopChange((loop) => {
state.loop = loop;
render();
});
onPreloadChange((preload) => {
state.preload = preload;
render();
});