diff --git a/apps/sandbox/app/shared/sources.ts b/apps/sandbox/app/shared/sources.ts
index 9781eed3..ad85b66a 100644
--- a/apps/sandbox/app/shared/sources.ts
+++ b/apps/sandbox/app/shared/sources.ts
@@ -4,54 +4,46 @@ export const SOURCES = {
'hls-1': {
label: 'HLS - Big Buck Bunny',
url: 'https://stream.mux.com/VcmKA6aqzIzlg3MayLJDnbF55kX00mds028Z65QxvBYaA.m3u8',
- playbackId: 'VcmKA6aqzIzlg3MayLJDnbF55kX00mds028Z65QxvBYaA',
type: 'hls',
subType: 'ts',
},
'hls-2': {
label: 'HLS - Elephants Dream',
url: 'https://stream.mux.com/Sc89iWAyNkhJ3P1rQ02nrEdCFTnfT01CZ2KmaEcxXfB008.m3u8',
- playbackId: 'Sc89iWAyNkhJ3P1rQ02nrEdCFTnfT01CZ2KmaEcxXfB008',
type: 'hls',
subType: 'ts',
},
'hls-3': {
label: 'HLS - Dancing Dude',
url: 'https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4.m3u8',
- playbackId: 'lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4',
type: 'hls',
subType: 'mp4',
},
'hls-4': {
label: 'HLS - View From A Blue Moon Trailer',
url: 'https://stream.mux.com/lyrKpPcGfqyzeI00jZAfW6MvP6GNPrkML.m3u8',
- playbackId: 'lyrKpPcGfqyzeI00jZAfW6MvP6GNPrkML',
type: 'hls',
subType: 'mp4',
},
'hls-5': {
label: 'HLS - Mad Max Fury Road Trailer',
url: 'https://stream.mux.com/JX01bG8eB4uaoV3OpDuK602rBfvdSgrMObjwuUOBn4JrQ.m3u8',
- playbackId: 'JX01bG8eB4uaoV3OpDuK602rBfvdSgrMObjwuUOBn4JrQ',
type: 'hls',
subType: 'mp4',
},
'mp4-1': {
label: 'MP4 - Dancing Dude',
url: 'https://stream.mux.com/lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4/highest.mp4',
- playbackId: 'lhnU49l1VGi3zrTAZhDm9LUUxSjpaPW9BL4jY25Kwo4',
type: 'mp4',
},
'dash-1': {
label: 'DASH - Big Buck Bunny',
url: 'https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd',
- playbackId: null,
type: 'dash',
},
'dash-2': {
label: 'DASH - Envivio Test Stream',
url: 'https://dash.akamaized.net/envivio/EnvivioDash3/manifest.mpd',
- playbackId: null,
type: 'dash',
},
} as const;
@@ -62,7 +54,6 @@ export const SOURCE_IDS = Object.keys(SOURCES) as SourceId[];
export const NON_DASH_SOURCE_IDS = SOURCE_IDS.filter((id) => SOURCES[id].type !== 'dash');
export const MP4_SOURCE_IDS = SOURCE_IDS.filter((id) => SOURCES[id].type === 'mp4');
export const DASH_SOURCE_IDS = SOURCE_IDS.filter((id) => SOURCES[id].type === 'dash');
-export const MUX_SOURCE_IDS = SOURCE_IDS.filter((id) => !!SOURCES[id].playbackId);
export const DEFAULT_SOURCE: SourceId = 'hls-1';
export const DEFAULT_AUDIO_SOURCE: SourceId = 'mp4-1';
export const DEFAULT_DASH_SOURCE: SourceId = 'dash-1';
diff --git a/apps/sandbox/app/shell/app.tsx b/apps/sandbox/app/shell/app.tsx
index 6de7c756..e25fb184 100644
--- a/apps/sandbox/app/shell/app.tsx
+++ b/apps/sandbox/app/shell/app.tsx
@@ -6,7 +6,6 @@ import {
DEFAULT_DASH_SOURCE,
DEFAULT_SOURCE,
MP4_SOURCE_IDS,
- MUX_SOURCE_IDS,
NON_DASH_SOURCE_IDS,
SOURCES,
} from '@app/shared/sources';
@@ -78,13 +77,6 @@ export function App() {
}
}, [preset, source, setSource]);
- // Constrain source to Mux playbackId sources when switching to mux-video / mux-audio
- useEffect(() => {
- if ((preset === 'mux-video' || preset === 'mux-audio') && !SOURCES[source].playbackId) {
- setSource(DEFAULT_SOURCE);
- }
- }, [preset, source, setSource]);
-
// CDN and background video do not have a Tailwind skin variant.
useEffect(() => {
if ((platform === 'cdn' || preset === 'background-video') && styling === 'tailwind') {
@@ -93,13 +85,7 @@ export function App() {
}, [platform, preset, styling]);
const availableSources =
- preset === 'audio'
- ? MP4_SOURCE_IDS
- : preset === 'dash-video'
- ? DASH_SOURCE_IDS
- : preset === 'mux-video' || preset === 'mux-audio'
- ? MUX_SOURCE_IDS
- : NON_DASH_SOURCE_IDS;
+ preset === 'audio' ? MP4_SOURCE_IDS : preset === 'dash-video' ? DASH_SOURCE_IDS : NON_DASH_SOURCE_IDS;
const handleSourceChange = useCallback((value: string) => setSource(value as SourceId), [setSource]);
diff --git a/apps/sandbox/templates/cdn/main.ts b/apps/sandbox/templates/cdn/main.ts
index acb37faf..464543ee 100644
--- a/apps/sandbox/templates/cdn/main.ts
+++ b/apps/sandbox/templates/cdn/main.ts
@@ -128,12 +128,7 @@ async function render() {
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}"`
- : (preset === 'mux-video' || preset === 'mux-audio') && source.type !== 'mp4'
- ? `playback-id="${source.playbackId}"`
- : `src="${source.url}"`;
+ const sourceAttr = preset === 'background-video' ? `src="${BACKGROUND_VIDEO_SRC}"` : `src="${source.url}"`;
// Background video needs viewport dimensions instead of flex centering.
if (preset === 'background-video') {
diff --git a/apps/sandbox/templates/html-mux-audio/main.ts b/apps/sandbox/templates/html-mux-audio/main.ts
index d95d5e6b..3a2e45bf 100644
--- a/apps/sandbox/templates/html-mux-audio/main.ts
+++ b/apps/sandbox/templates/html-mux-audio/main.ts
@@ -15,16 +15,11 @@ async function render() {
const tag = await loadLatest(() => loadAudioSkinTag(state.skin, state.styling));
if (!tag) return;
- const sourceAttr =
- SOURCES[state.source].type === 'mp4'
- ? `src="${SOURCES[state.source].url}"`
- : `playback-id="${SOURCES[state.source].playbackId}"`;
-
document.getElementById('root')!.innerHTML = html`
diff --git a/apps/sandbox/templates/html-mux-video/main.ts b/apps/sandbox/templates/html-mux-video/main.ts
index edcd096f..d1ead60a 100644
--- a/apps/sandbox/templates/html-mux-video/main.ts
+++ b/apps/sandbox/templates/html-mux-video/main.ts
@@ -19,15 +19,10 @@ async function render() {
const storyboard = getStoryboardSrc(state.source);
const poster = getPosterSrc(state.source);
- const sourceAttr =
- SOURCES[state.source].type === 'mp4'
- ? `src="${SOURCES[state.source].url}"`
- : `playback-id="${SOURCES[state.source].playbackId}"`;
-
document.getElementById('root')!.innerHTML = html`
<${tag} class="aspect-video max-w-4xl mx-auto">
-
+
${renderStoryboard(storyboard)}
${poster ? html`
` : ''}
diff --git a/apps/sandbox/templates/react-mux-audio/main.tsx b/apps/sandbox/templates/react-mux-audio/main.tsx
index 097e366d..40716fe5 100644
--- a/apps/sandbox/templates/react-mux-audio/main.tsx
+++ b/apps/sandbox/templates/react-mux-audio/main.tsx
@@ -18,13 +18,10 @@ function App() {
const source = useSource();
const styling = useMemo(readStyling, []);
- const sourceAttr =
- SOURCES[source].type === 'mp4' ? { src: SOURCES[source].url } : { playbackId: SOURCES[source].playbackId };
-
return (
-
+
);
diff --git a/apps/sandbox/templates/react-mux-video/main.tsx b/apps/sandbox/templates/react-mux-video/main.tsx
index f093ddea..945123f8 100644
--- a/apps/sandbox/templates/react-mux-video/main.tsx
+++ b/apps/sandbox/templates/react-mux-video/main.tsx
@@ -23,13 +23,10 @@ function App() {
const poster = usePoster();
const storyboard = useStoryboard();
- const sourceAttr =
- SOURCES[source].type === 'mp4' ? { src: SOURCES[source].url } : { playbackId: SOURCES[source].playbackId };
-
return (
-
+
diff --git a/packages/core/src/core/index.ts b/packages/core/src/core/index.ts
index 648e1551..7ba45be9 100644
--- a/packages/core/src/core/index.ts
+++ b/packages/core/src/core/index.ts
@@ -1,5 +1,3 @@
-export * from './media/delegate';
-export * from './media/proxy';
export * from './media/state';
export * from './media/types';
export * from './ui/alert-dialog/alert-dialog-core';
diff --git a/packages/core/src/core/media/delegate.ts b/packages/core/src/core/media/delegate.ts
deleted file mode 100644
index 8b0610fb..00000000
--- a/packages/core/src/core/media/delegate.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import type { Constructor } from '@videojs/utils/types';
-import { bridgeEvents } from '../utils/bridge-events';
-import { defineClassPropHooks } from '../utils/define-class-prop-hooks';
-
-export interface Delegate {
- attach?(target: EventTarget): void;
- detach?(): void;
-}
-
-export interface BaseType extends EventTarget {
- attach?(target: EventTarget): void;
- detach?(): void;
- get?(prop: string): any;
- set?(prop: string, val: any): void;
- call?(prop: string, ...args: any[]): any;
-}
-
-/**
- * Mixin that intercepts `get`, `set`, and `call` to delegate property access
- * and method calls to an instance of `DelegateClass` before falling through
- * to the base class implementation.
- *
- * Works with both `CustomMediaMixin` and `ProxyMixin`.
- */
-export function DelegateMixin, D extends Constructor>(
- BaseClass: Base,
- DelegateClass: D
-) {
- class DelegateImpl extends BaseClass {
- #delegate = new DelegateClass();
-
- constructor(...args: any[]) {
- super(...args);
-
- if (this.#delegate instanceof EventTarget) {
- bridgeEvents(this.#delegate, this);
- }
- }
-
- get(prop: string): any {
- if (prop in this.#delegate) {
- return (this.#delegate as any)[prop];
- }
- return super.get?.(prop);
- }
-
- set(prop: string, val: any): void {
- if (prop in this.#delegate) {
- (this.#delegate as any)[prop] = val;
- return;
- }
- super.set?.(prop, val);
- }
-
- call(prop: string, ...args: any[]): any {
- if (prop in this.#delegate) {
- return (this.#delegate as any)[prop](...args);
- }
- return super.call?.(prop, ...args);
- }
-
- attach(target: EventTarget): void {
- this.#delegate.attach?.(target);
- super.attach?.(target);
- }
-
- detach(): void {
- this.#delegate.detach?.();
- super.detach?.();
- }
- }
-
- for (let proto = DelegateClass.prototype; proto && proto !== Object.prototype; proto = Object.getPrototypeOf(proto)) {
- defineClassPropHooks(DelegateImpl, proto);
- }
-
- return DelegateImpl as unknown as Constructor & InstanceType> & Omit;
-}
diff --git a/packages/core/src/core/media/proxy.ts b/packages/core/src/core/media/proxy.ts
deleted file mode 100644
index 042f2279..00000000
--- a/packages/core/src/core/media/proxy.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import type { AnyConstructor, Constructor } from '@videojs/utils/types';
-import { defineClassPropHooks } from '../utils/define-class-prop-hooks';
-
-export interface MediaProxy {
- readonly target: EventTarget | null;
- get(prop: keyof EventTarget): any;
- set(prop: keyof EventTarget, val: any): void;
- call(prop: keyof EventTarget, ...args: any[]): any;
- attach(target: EventTarget): void;
- detach(): void;
-}
-
-/**
- * This mixin creates an API from the passed classes and proxies the methods and properties to the attached target.
- *
- * Many methods and properties will need no translation and are proxied directly to the attached target.
- * For example, the `play` and `pause` methods are proxied directly to the attached target.
- *
- * Child classes can override the proxied methods and properties to provide custom behavior.
- * For example, the `src` property for HLS media is proxied to the HLS engine, not the target itself.
- *
- * The `get`, `set`, and `call` methods can be overridden to provide catch-all custom behavior.
- */
-export const ProxyMixin = (BaseClass: AnyConstructor) => {
- class MediaProxyImpl extends EventTarget {
- #target: EventTarget | null = null;
- #types = new Set();
-
- get target() {
- return this.#target;
- }
-
- get(prop: keyof EventTarget): any {
- return this.target?.[prop];
- }
-
- set(prop: keyof EventTarget, val: any): void {
- if (this.target) {
- this.target[prop] = val;
- }
- }
-
- call(prop: keyof EventTarget, ...args: any[]): any {
- const nativeFn = this.target?.[prop] as ((...args: any[]) => any) | undefined;
- return nativeFn?.apply(this.target, args);
- }
-
- attach(target: EventTarget): void {
- if (!target || this.#target === target) return;
- this.#target = target;
- for (const type of this.#types) {
- target.addEventListener(type, this.#forwardEvent);
- }
- }
-
- detach(): void {
- if (!this.#target) return;
- for (const type of this.#types) {
- this.#target.removeEventListener(type, this.#forwardEvent);
- }
- this.#target = null;
- }
-
- addEventListener(
- type: string,
- listener: EventListenerOrEventListenerObject,
- options?: boolean | AddEventListenerOptions
- ): void {
- if (!this.#types.has(type)) {
- this.#types.add(type);
- this.#target?.addEventListener(type, this.#forwardEvent);
- }
- super.addEventListener(type, listener, options);
- }
-
- #forwardEvent = (event: Event) => {
- this.dispatchEvent(new (event.constructor as typeof Event)(event.type, event));
- };
- }
-
- for (
- let proto = BaseClass.prototype;
- proto && !Object.prototype.isPrototypeOf.call(proto, MediaProxyImpl.prototype);
- proto = Object.getPrototypeOf(proto)
- ) {
- defineClassPropHooks(MediaProxyImpl, proto);
- }
-
- return MediaProxyImpl as unknown as Constructor;
-};
diff --git a/packages/core/src/core/media/state.ts b/packages/core/src/core/media/state.ts
index 443c3eab..f01be4af 100644
--- a/packages/core/src/core/media/state.ts
+++ b/packages/core/src/core/media/state.ts
@@ -37,8 +37,7 @@ export interface MediaPlaybackState {
togglePaused(): boolean;
}
-/** Indicates whether a feature can be programmatically controlled on this platform. */
-export type MediaFeatureAvailability = 'available' | 'unavailable' | 'unsupported';
+import type { MediaFeatureAvailability } from './types';
export interface MediaVolumeState {
/**
@@ -227,7 +226,7 @@ export type TextTrackMode = 'showing' | 'disabled' | 'hidden';
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/TextTrack
*/
-export interface MediaTextTrack {
+export interface MediaTextTrack {
kind: Kind;
label: string;
language: string;
@@ -242,7 +241,7 @@ export interface MediaTextTrackState {
/** The `