diff --git a/apps/sandbox/app/shared/html/storyboard.ts b/apps/sandbox/app/shared/html/storyboard.ts
index 12f32b2d..e0debf8a 100644
--- a/apps/sandbox/app/shared/html/storyboard.ts
+++ b/apps/sandbox/app/shared/html/storyboard.ts
@@ -1,3 +1,3 @@
export function renderStoryboard(src?: string | undefined): string {
- return src ? `` : '';
+ return src ? `` : '';
}
diff --git a/apps/sandbox/app/shared/react/storyboard.tsx b/apps/sandbox/app/shared/react/storyboard.tsx
index c6ead425..2cb024ff 100644
--- a/apps/sandbox/app/shared/react/storyboard.tsx
+++ b/apps/sandbox/app/shared/react/storyboard.tsx
@@ -4,5 +4,5 @@ type StoryboardProps = {
export function Storyboard({ src }: StoryboardProps) {
if (!src) return null;
- return ;
+ return ;
}
diff --git a/packages/core/src/dom/media/custom-media-element/index.ts b/packages/core/src/dom/media/custom-media-element/index.ts
index 7a73b080..7c61037a 100644
--- a/packages/core/src/dom/media/custom-media-element/index.ts
+++ b/packages/core/src/dom/media/custom-media-element/index.ts
@@ -372,6 +372,7 @@ export function CustomMediaMixin>(
this.#childObserver?.observe(el, { attributes: true });
}
this.target?.append(clone);
+ this.#enableDefaultTrack(clone as HTMLTrackElement);
});
removeNativeChildren.forEach((clone, el) => {
@@ -387,11 +388,26 @@ export function CustomMediaMixin>(
const clone = this.#childMap.get(target as MediaChild);
if (clone && attributeName) {
clone.setAttribute(attributeName, (target as MediaChild).getAttribute(attributeName) ?? '');
+ this.#enableDefaultTrack(clone as HTMLTrackElement);
}
}
}
}
+ #enableDefaultTrack(trackEl: HTMLTrackElement): void {
+ // Browsers don't honor the `default` attribute if a track is added via JS.
+ // Enable default tracks for chapters or metadata.
+ if (
+ trackEl &&
+ trackEl.localName === 'track' &&
+ trackEl.default &&
+ (trackEl.kind === 'chapters' || trackEl.kind === 'metadata') &&
+ trackEl.track.mode === 'disabled'
+ ) {
+ trackEl.track.mode = 'hidden';
+ }
+ }
+
#upgradeProperty(this: typeof nativeElTest, prop: keyof typeof nativeElTest) {
// Sets properties that are set before the custom element is upgraded.
// https://web.dev/custom-elements-best-practices/#make-properties-lazy
diff --git a/packages/core/src/dom/media/hls/hlsjs.ts b/packages/core/src/dom/media/hls/hlsjs.ts
index 70cae2d7..fc485e53 100644
--- a/packages/core/src/dom/media/hls/hlsjs.ts
+++ b/packages/core/src/dom/media/hls/hlsjs.ts
@@ -1,6 +1,7 @@
import Hls, { type HlsConfig } from 'hls.js';
import type { Delegate } from '../../../core/media/delegate';
import { HlsJsMediaErrorsMixin } from './errors';
+import { HlsJsMediaMetadataTracksMixin } from './metadata-tracks';
import { HlsJsMediaPreloadMixin } from './preload';
import { HlsJsMediaTextTracksMixin } from './text-tracks';
@@ -55,5 +56,5 @@ class HlsJsMediaDelegateBase extends EventTarget implements Delegate {
}
export class HlsJsMediaDelegate extends HlsJsMediaPreloadMixin(
- HlsJsMediaTextTracksMixin(HlsJsMediaErrorsMixin(HlsJsMediaDelegateBase))
+ HlsJsMediaMetadataTracksMixin(HlsJsMediaTextTracksMixin(HlsJsMediaErrorsMixin(HlsJsMediaDelegateBase)))
) {}
diff --git a/packages/core/src/dom/media/hls/metadata-tracks.ts b/packages/core/src/dom/media/hls/metadata-tracks.ts
new file mode 100644
index 00000000..2c79060f
--- /dev/null
+++ b/packages/core/src/dom/media/hls/metadata-tracks.ts
@@ -0,0 +1,56 @@
+import type { Constructor } from '@videojs/utils/types';
+import Hls from 'hls.js';
+import type { HlsEngineHost } from './preload';
+
+/**
+ * Ensures user-authored metadata and chapters `