feat: add custom rendered secondary tracks

This commit is contained in:
Ivan Schurawel 2022-09-15 14:25:34 -04:00 committed by Ivan Schurawel
parent 145aea184f
commit ab993886c1
2 changed files with 88 additions and 31 deletions

View file

@ -222,10 +222,18 @@ function tryRemoveElement(elem) {
* @type {HTMLElement | null | undefined} * @type {HTMLElement | null | undefined}
*/ */
#videoSubtitlesElem; #videoSubtitlesElem;
/**
* @type {HTMLElement | null | undefined}
*/
#videoSecondarySubtitlesElem;
/** /**
* @type {any | null | undefined} * @type {any | null | undefined}
*/ */
#currentTrackEvents; #currentTrackEvents;
/**
* @type {any | null | undefined}
*/
#currentSecondaryTrackEvents;
/** /**
* @type {string[] | undefined} * @type {string[] | undefined}
*/ */
@ -977,17 +985,30 @@ function tryRemoveElement(elem) {
*/ */
destroyCustomTrack(videoElement, targetTrackIndex) { destroyCustomTrack(videoElement, targetTrackIndex) {
const destroySingleTrack = typeof targetTrackIndex === 'number'; const destroySingleTrack = typeof targetTrackIndex === 'number';
const destroyPrimaryTrack = targetTrackIndex === this._PRIMARY_TEXT_TRACK_INDEX;
const destroySecondaryTrack = targetTrackIndex === this._SECONDARY_TEXT_TRACK_INDEX;
if (this.#videoSubtitlesElem) { if (destroyPrimaryTrack) {
const subtitlesContainer = this.#videoSubtitlesElem.parentNode; if (this.#videoSubtitlesElem) {
if (subtitlesContainer) { tryRemoveElement(this.#videoSubtitlesElem);
tryRemoveElement(subtitlesContainer); this.#videoSubtitlesElem = null;
}
} else if (destroySecondaryTrack) {
if (this.#videoSecondarySubtitlesElem) {
tryRemoveElement(this.#videoSecondarySubtitlesElem);
this.#videoSecondarySubtitlesElem = null;
}
} else {
if (this.#videoSubtitlesElem) {
const subtitlesContainer = this.#videoSubtitlesElem.parentNode;
if (subtitlesContainer) {
tryRemoveElement(subtitlesContainer);
}
this.#videoSubtitlesElem = null;
this.#videoSecondarySubtitlesElem = null;
} }
this.#videoSubtitlesElem = null;
} }
this.#currentTrackEvents = null;
if (videoElement) { if (videoElement) {
const allTracks = videoElement.textTracks || []; // get list of tracks const allTracks = videoElement.textTracks || []; // get list of tracks
for (let index = 0; index < allTracks.length; index++) { for (let index = 0; index < allTracks.length; index++) {
@ -1001,7 +1022,19 @@ function tryRemoveElement(elem) {
} }
} }
this.#customTrackIndex = -1; if (destroyPrimaryTrack) {
this.#customTrackIndex = -1;
this.#currentTrackEvents = null;
} else if (destroySecondaryTrack) {
this.#customSecondaryTrackIndex = -1;
this.#currentSecondaryTrackEvents = null;
} else {
this.#customTrackIndex = -1;
this.#customSecondaryTrackIndex = -1;
this.#currentTrackEvents = null;
this.#currentSecondaryTrackEvents = null;
}
this.#currentClock = null; this.#currentClock = null;
this._currentAspectRatio = null; this._currentAspectRatio = null;
@ -1191,16 +1224,27 @@ function tryRemoveElement(elem) {
/** /**
* @private * @private
*/ */
renderSubtitlesWithCustomElement(videoElement, track, item) { renderSubtitlesWithCustomElement(videoElement, track, item, targetTextTrackIndex) {
this.fetchSubtitles(track, item).then((data) => { this.fetchSubtitles(track, item).then((data) => {
if (!this.#videoSubtitlesElem) { if (!this.#videoSubtitlesElem) {
const subtitlesContainer = document.createElement('div'); if (!this.isSecondaryTrack(targetTextTrackIndex)) {
subtitlesContainer.classList.add('videoSubtitles'); const subtitlesContainer = document.createElement('div');
subtitlesContainer.innerHTML = '<div class="videoSubtitlesInner"></div>'; subtitlesContainer.classList.add('videoSubtitles');
this.#videoSubtitlesElem = subtitlesContainer.querySelector('.videoSubtitlesInner'); subtitlesContainer.innerHTML = '<div class="videoSubtitlesInner"></div>';
this.setSubtitleAppearance(subtitlesContainer, this.#videoSubtitlesElem); this.#videoSubtitlesElem = subtitlesContainer.querySelector('.videoSubtitlesInner');
videoElement.parentNode.appendChild(subtitlesContainer); this.setSubtitleAppearance(subtitlesContainer, this.#videoSubtitlesElem);
this.#currentTrackEvents = data.TrackEvents; videoElement.parentNode.appendChild(subtitlesContainer);
this.#currentTrackEvents = data.TrackEvents;
}
} else if (this.isSecondaryTrack(targetTextTrackIndex)) {
const subtitlesContainer = document.querySelector('.videoSubtitles');
if (!subtitlesContainer) return;
const secondarySubtitlesElement = document.createElement('div');
secondarySubtitlesElement.classList.add('videoSecondarySubtitlesInner');
subtitlesContainer.prepend(secondarySubtitlesElement);
this.#videoSecondarySubtitlesElem = secondarySubtitlesElement;
this.setSubtitleAppearance(subtitlesContainer, this.#videoSecondarySubtitlesElem);
this.#currentSecondaryTrackEvents = data.TrackEvents;
} }
}); });
} }
@ -1324,24 +1368,29 @@ function tryRemoveElement(elem) {
return; return;
} }
const trackEvents = this.#currentTrackEvents; const allTrackEvents = [this.#currentTrackEvents, this.#currentSecondaryTrackEvents];
const subtitleTextElement = this.#videoSubtitlesElem; const subtitleTextElements = [this.#videoSubtitlesElem, this.#videoSecondarySubtitlesElem];
if (trackEvents && subtitleTextElement) { for (let i = 0; i < allTrackEvents.length; i++) {
const ticks = timeMs * 10000; const trackEvents = allTrackEvents[i];
let selectedTrackEvent; const subtitleTextElement = subtitleTextElements[i];
for (const trackEvent of trackEvents) {
if (trackEvent.StartPositionTicks <= ticks && trackEvent.EndPositionTicks >= ticks) { if (trackEvents && subtitleTextElement) {
selectedTrackEvent = trackEvent; const ticks = timeMs * 10000;
break; let selectedTrackEvent;
for (const trackEvent of trackEvents) {
if (trackEvent.StartPositionTicks <= ticks && trackEvent.EndPositionTicks >= ticks) {
selectedTrackEvent = trackEvent;
break;
}
} }
}
if (selectedTrackEvent && selectedTrackEvent.Text) { if (selectedTrackEvent && selectedTrackEvent.Text) {
subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text, true); subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text, true);
subtitleTextElement.classList.remove('hide'); subtitleTextElement.classList.remove('hide');
} else { } else {
subtitleTextElement.classList.add('hide'); subtitleTextElement.classList.add('hide');
}
} }
} }
} }

View file

@ -74,6 +74,14 @@ video[controls]::-webkit-media-controls {
display: inline-block; display: inline-block;
} }
.videoSecondarySubtitlesInner {
max-width: 70%;
background-color: rgba(0, 0, 0, 0.8);
margin: auto;
display: block;
margin-bottom: 0 !important;
}
@keyframes htmlvideoplayer-zoomin { @keyframes htmlvideoplayer-zoomin {
from { from {
transform: scale3d(0.2, 0.2, 0.2); transform: scale3d(0.2, 0.2, 0.2);