2 Commits

Author SHA1 Message Date
eb0ee7c672 wip: Add text track handling 2025-10-20 06:46:05 +02:00
f7e08291f5 Handle text track change event 2025-10-20 02:15:44 +02:00
2 changed files with 36 additions and 1 deletions

View File

@@ -68,7 +68,12 @@ class VideoPlayer extends VideoPlayerEvents implements VideoPlayerBase {
constructor(source: VideoSource | VideoConfig | VideoPlayerSource) {
const video = document.createElement("video");
const player = videojs(video, { qualityLevels: true });
const player = videojs(video, {
qualityLevels: true,
html5: {
preloadTextTracks: false,
},
});
super(new WebEventEmiter(player));
@@ -286,6 +291,16 @@ class VideoPlayer extends VideoPlayerEvents implements VideoPlayerBase {
});
if (this.mediaSession.enabled)
this.mediaSession.updateMediaSession(source.metadata);
for (const sub of source.externalSubtitles ?? []) {
this.player.addRemoteTextTrack({
kind: "subtitles",
label: sub.label,
src: sub.uri,
srclang: sub.language,
});
}
if (source.initializeOnCreation) await this.preload();
}

View File

@@ -80,6 +80,9 @@ export class WebEventEmiter implements PlayerEvents {
this._onError = this._onError.bind(this);
this.player.on("error", this._onError);
this._onTextTrackChange = this._onTextTrackChange.bind(this);
this.player.textTracks().on("change", this._onTextTrackChange);
this._onAudioTrackChange = this._onAudioTrackChange.bind(this);
this.player.audioTracks().on("change", this._onAudioTrackChange);
@@ -114,6 +117,8 @@ export class WebEventEmiter implements PlayerEvents {
this.player.off("error", this._onError);
this.player.textTracks().off("change", this._onTextTrackChange);
this.player.audioTracks().off("change", this._onAudioTrackChange);
this.player.videoTracks().off("change", this._onVideoTrackChange);
@@ -238,6 +243,21 @@ export class WebEventEmiter implements PlayerEvents {
this.onError(new VideoError(codeMap[err.code]!, err.message));
}
_onTextTrackChange() {
// @ts-expect-error they define length & index properties via prototype
const tracks: VideoJsTextTracks = this.player.textTracks();
const selected = [...Array(tracks.length)]
.map((_, i) => ({
id: tracks[i]!.id,
label: tracks[i]!.label,
language: tracks[i]!.language,
selected: tracks[i]!.mode === "showing",
}))
.find((x) => x.selected);
this.onTrackChange(selected ?? null);
}
_onAudioTrackChange() {
// @ts-expect-error they define length & index properties via prototype
const tracks: VideoJsTracks = this.player.audioTracks();