feat: add custom rendered secondary tracks
This commit is contained in:
parent
145aea184f
commit
ab993886c1
2 changed files with 88 additions and 31 deletions
|
@ -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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue