vidply 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vidply.esm.js +683 -6
- package/dist/vidply.esm.js.map +3 -3
- package/dist/vidply.esm.min.js +6 -6
- package/dist/vidply.esm.min.meta.json +3 -3
- package/dist/vidply.js +683 -6
- package/dist/vidply.js.map +3 -3
- package/dist/vidply.min.js +6 -6
- package/dist/vidply.min.meta.json +3 -3
- package/package.json +2 -2
- package/src/core/Player.js +988 -9
package/dist/vidply.js
CHANGED
|
@@ -5489,6 +5489,9 @@ var VidPly = (() => {
|
|
|
5489
5489
|
this.audioDescriptionSrc = this.options.audioDescriptionSrc;
|
|
5490
5490
|
this.signLanguageSrc = this.options.signLanguageSrc;
|
|
5491
5491
|
this.signLanguageVideo = null;
|
|
5492
|
+
this.audioDescriptionSourceElement = null;
|
|
5493
|
+
this.originalAudioDescriptionSource = null;
|
|
5494
|
+
this.audioDescriptionCaptionTracks = [];
|
|
5492
5495
|
this.container = null;
|
|
5493
5496
|
this.renderer = null;
|
|
5494
5497
|
this.controlBar = null;
|
|
@@ -5643,6 +5646,53 @@ var VidPly = (() => {
|
|
|
5643
5646
|
if (!src) {
|
|
5644
5647
|
throw new Error("No media source found");
|
|
5645
5648
|
}
|
|
5649
|
+
const sourceElements = this.element.querySelectorAll("source");
|
|
5650
|
+
for (const sourceEl of sourceElements) {
|
|
5651
|
+
const descSrc = sourceEl.getAttribute("data-desc-src");
|
|
5652
|
+
const origSrc = sourceEl.getAttribute("data-orig-src");
|
|
5653
|
+
if (descSrc || origSrc) {
|
|
5654
|
+
if (!this.audioDescriptionSourceElement) {
|
|
5655
|
+
this.audioDescriptionSourceElement = sourceEl;
|
|
5656
|
+
}
|
|
5657
|
+
if (origSrc) {
|
|
5658
|
+
if (!this.originalAudioDescriptionSource) {
|
|
5659
|
+
this.originalAudioDescriptionSource = origSrc;
|
|
5660
|
+
}
|
|
5661
|
+
if (!this.originalSrc) {
|
|
5662
|
+
this.originalSrc = origSrc;
|
|
5663
|
+
}
|
|
5664
|
+
} else {
|
|
5665
|
+
const currentSrcAttr = sourceEl.getAttribute("src");
|
|
5666
|
+
if (!this.originalAudioDescriptionSource && currentSrcAttr) {
|
|
5667
|
+
this.originalAudioDescriptionSource = currentSrcAttr;
|
|
5668
|
+
}
|
|
5669
|
+
if (!this.originalSrc && currentSrcAttr) {
|
|
5670
|
+
this.originalSrc = currentSrcAttr;
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
if (descSrc && !this.audioDescriptionSrc) {
|
|
5674
|
+
this.audioDescriptionSrc = descSrc;
|
|
5675
|
+
}
|
|
5676
|
+
}
|
|
5677
|
+
}
|
|
5678
|
+
const trackElements = this.element.querySelectorAll("track");
|
|
5679
|
+
trackElements.forEach((trackEl) => {
|
|
5680
|
+
const trackKind = trackEl.getAttribute("kind");
|
|
5681
|
+
const trackDescSrc = trackEl.getAttribute("data-desc-src");
|
|
5682
|
+
if (trackKind === "captions" || trackKind === "subtitles" || trackKind === "chapters") {
|
|
5683
|
+
if (trackDescSrc) {
|
|
5684
|
+
this.audioDescriptionCaptionTracks.push({
|
|
5685
|
+
trackElement: trackEl,
|
|
5686
|
+
originalSrc: trackEl.getAttribute("src"),
|
|
5687
|
+
describedSrc: trackDescSrc,
|
|
5688
|
+
originalTrackSrc: trackEl.getAttribute("data-orig-src") || trackEl.getAttribute("src"),
|
|
5689
|
+
explicit: true
|
|
5690
|
+
// Explicitly defined, so we should validate it
|
|
5691
|
+
});
|
|
5692
|
+
this.log(`Found explicit described ${trackKind} track: ${trackEl.getAttribute("src")} -> ${trackDescSrc}`);
|
|
5693
|
+
}
|
|
5694
|
+
}
|
|
5695
|
+
});
|
|
5646
5696
|
if (!this.originalSrc) {
|
|
5647
5697
|
this.originalSrc = src;
|
|
5648
5698
|
}
|
|
@@ -5927,15 +5977,396 @@ var VidPly = (() => {
|
|
|
5927
5977
|
this.enableCaptions();
|
|
5928
5978
|
}
|
|
5929
5979
|
}
|
|
5980
|
+
/**
|
|
5981
|
+
* Check if a track file exists
|
|
5982
|
+
* @param {string} url - Track file URL
|
|
5983
|
+
* @returns {Promise<boolean>} - True if file exists
|
|
5984
|
+
*/
|
|
5985
|
+
async validateTrackExists(url) {
|
|
5986
|
+
try {
|
|
5987
|
+
const response = await fetch(url, { method: "HEAD", cache: "no-cache" });
|
|
5988
|
+
return response.ok;
|
|
5989
|
+
} catch (error) {
|
|
5990
|
+
return false;
|
|
5991
|
+
}
|
|
5992
|
+
}
|
|
5930
5993
|
// Audio Description
|
|
5931
5994
|
async enableAudioDescription() {
|
|
5932
|
-
|
|
5933
|
-
|
|
5995
|
+
const hasSourceElementsWithDesc = Array.from(this.element.querySelectorAll("source")).some((el) => el.getAttribute("data-desc-src"));
|
|
5996
|
+
const hasTracksWithDesc = this.audioDescriptionCaptionTracks.length > 0;
|
|
5997
|
+
if (!this.audioDescriptionSrc && !hasSourceElementsWithDesc && !hasTracksWithDesc) {
|
|
5998
|
+
console.warn("VidPly: No audio description source, source elements, or tracks provided");
|
|
5934
5999
|
return;
|
|
5935
6000
|
}
|
|
5936
6001
|
const currentTime = this.state.currentTime;
|
|
5937
6002
|
const wasPlaying = this.state.playing;
|
|
5938
|
-
|
|
6003
|
+
let swappedTracksForTranscript = [];
|
|
6004
|
+
if (this.audioDescriptionSourceElement) {
|
|
6005
|
+
const currentSrc = this.element.currentSrc || this.element.src;
|
|
6006
|
+
const sourceElements = Array.from(this.element.querySelectorAll("source"));
|
|
6007
|
+
let sourceElementToUpdate = null;
|
|
6008
|
+
let descSrc = this.audioDescriptionSrc;
|
|
6009
|
+
for (const sourceEl of sourceElements) {
|
|
6010
|
+
const sourceSrc = sourceEl.getAttribute("src");
|
|
6011
|
+
const descSrcAttr = sourceEl.getAttribute("data-desc-src");
|
|
6012
|
+
const sourceFilename = sourceSrc ? sourceSrc.split("/").pop() : "";
|
|
6013
|
+
const currentFilename = currentSrc ? currentSrc.split("/").pop() : "";
|
|
6014
|
+
if (currentSrc && (currentSrc === sourceSrc || currentSrc.includes(sourceSrc) || currentSrc.includes(sourceFilename) || sourceFilename && currentFilename === sourceFilename)) {
|
|
6015
|
+
sourceElementToUpdate = sourceEl;
|
|
6016
|
+
if (descSrcAttr) {
|
|
6017
|
+
descSrc = descSrcAttr;
|
|
6018
|
+
} else if (sourceSrc) {
|
|
6019
|
+
descSrc = this.audioDescriptionSrc || descSrc;
|
|
6020
|
+
}
|
|
6021
|
+
break;
|
|
6022
|
+
}
|
|
6023
|
+
}
|
|
6024
|
+
if (!sourceElementToUpdate) {
|
|
6025
|
+
sourceElementToUpdate = this.audioDescriptionSourceElement;
|
|
6026
|
+
const storedDescSrc = sourceElementToUpdate.getAttribute("data-desc-src");
|
|
6027
|
+
if (storedDescSrc) {
|
|
6028
|
+
descSrc = storedDescSrc;
|
|
6029
|
+
}
|
|
6030
|
+
}
|
|
6031
|
+
if (this.audioDescriptionCaptionTracks.length > 0) {
|
|
6032
|
+
const validationPromises = this.audioDescriptionCaptionTracks.map(async (trackInfo) => {
|
|
6033
|
+
if (trackInfo.trackElement && trackInfo.describedSrc) {
|
|
6034
|
+
if (trackInfo.explicit === true) {
|
|
6035
|
+
try {
|
|
6036
|
+
const exists = await this.validateTrackExists(trackInfo.describedSrc);
|
|
6037
|
+
return { trackInfo, exists };
|
|
6038
|
+
} catch (error) {
|
|
6039
|
+
return { trackInfo, exists: false };
|
|
6040
|
+
}
|
|
6041
|
+
} else {
|
|
6042
|
+
return { trackInfo, exists: false };
|
|
6043
|
+
}
|
|
6044
|
+
}
|
|
6045
|
+
return { trackInfo, exists: false };
|
|
6046
|
+
});
|
|
6047
|
+
const validationResults = await Promise.all(validationPromises);
|
|
6048
|
+
const tracksToSwap = validationResults.filter((result) => result.exists);
|
|
6049
|
+
if (tracksToSwap.length > 0) {
|
|
6050
|
+
const trackModes = /* @__PURE__ */ new Map();
|
|
6051
|
+
tracksToSwap.forEach(({ trackInfo }) => {
|
|
6052
|
+
const textTrack = trackInfo.trackElement.track;
|
|
6053
|
+
if (textTrack) {
|
|
6054
|
+
trackModes.set(trackInfo, {
|
|
6055
|
+
wasShowing: textTrack.mode === "showing",
|
|
6056
|
+
wasHidden: textTrack.mode === "hidden"
|
|
6057
|
+
});
|
|
6058
|
+
} else {
|
|
6059
|
+
trackModes.set(trackInfo, {
|
|
6060
|
+
wasShowing: false,
|
|
6061
|
+
wasHidden: false
|
|
6062
|
+
});
|
|
6063
|
+
}
|
|
6064
|
+
});
|
|
6065
|
+
const tracksToReadd = tracksToSwap.map(({ trackInfo }) => {
|
|
6066
|
+
const oldSrc = trackInfo.trackElement.getAttribute("src");
|
|
6067
|
+
const parent = trackInfo.trackElement.parentNode;
|
|
6068
|
+
const nextSibling = trackInfo.trackElement.nextSibling;
|
|
6069
|
+
const attributes = {};
|
|
6070
|
+
Array.from(trackInfo.trackElement.attributes).forEach((attr) => {
|
|
6071
|
+
attributes[attr.name] = attr.value;
|
|
6072
|
+
});
|
|
6073
|
+
return {
|
|
6074
|
+
trackInfo,
|
|
6075
|
+
oldSrc,
|
|
6076
|
+
parent,
|
|
6077
|
+
nextSibling,
|
|
6078
|
+
attributes
|
|
6079
|
+
};
|
|
6080
|
+
});
|
|
6081
|
+
tracksToReadd.forEach(({ trackInfo }) => {
|
|
6082
|
+
trackInfo.trackElement.remove();
|
|
6083
|
+
});
|
|
6084
|
+
this.element.load();
|
|
6085
|
+
setTimeout(() => {
|
|
6086
|
+
tracksToReadd.forEach(({ trackInfo, oldSrc, parent, nextSibling, attributes }) => {
|
|
6087
|
+
swappedTracksForTranscript.push(trackInfo);
|
|
6088
|
+
const newTrackElement = document.createElement("track");
|
|
6089
|
+
newTrackElement.setAttribute("src", trackInfo.describedSrc);
|
|
6090
|
+
Object.keys(attributes).forEach((attrName) => {
|
|
6091
|
+
if (attrName !== "src" && attrName !== "data-desc-src") {
|
|
6092
|
+
newTrackElement.setAttribute(attrName, attributes[attrName]);
|
|
6093
|
+
}
|
|
6094
|
+
});
|
|
6095
|
+
if (nextSibling && nextSibling.parentNode) {
|
|
6096
|
+
parent.insertBefore(newTrackElement, nextSibling);
|
|
6097
|
+
} else {
|
|
6098
|
+
parent.appendChild(newTrackElement);
|
|
6099
|
+
}
|
|
6100
|
+
trackInfo.trackElement = newTrackElement;
|
|
6101
|
+
});
|
|
6102
|
+
this.element.load();
|
|
6103
|
+
const setupNewTracks = () => {
|
|
6104
|
+
setTimeout(() => {
|
|
6105
|
+
swappedTracksForTranscript.forEach((trackInfo) => {
|
|
6106
|
+
const trackElement = trackInfo.trackElement;
|
|
6107
|
+
const newTextTrack = trackElement.track;
|
|
6108
|
+
if (newTextTrack) {
|
|
6109
|
+
const modeInfo = trackModes.get(trackInfo) || { wasShowing: false, wasHidden: false };
|
|
6110
|
+
newTextTrack.mode = "hidden";
|
|
6111
|
+
const restoreMode = () => {
|
|
6112
|
+
if (modeInfo.wasShowing) {
|
|
6113
|
+
newTextTrack.mode = "hidden";
|
|
6114
|
+
} else if (modeInfo.wasHidden) {
|
|
6115
|
+
newTextTrack.mode = "hidden";
|
|
6116
|
+
} else {
|
|
6117
|
+
newTextTrack.mode = "disabled";
|
|
6118
|
+
}
|
|
6119
|
+
};
|
|
6120
|
+
if (newTextTrack.readyState >= 2) {
|
|
6121
|
+
restoreMode();
|
|
6122
|
+
} else {
|
|
6123
|
+
newTextTrack.addEventListener("load", restoreMode, { once: true });
|
|
6124
|
+
newTextTrack.addEventListener("error", restoreMode, { once: true });
|
|
6125
|
+
}
|
|
6126
|
+
}
|
|
6127
|
+
});
|
|
6128
|
+
}, 300);
|
|
6129
|
+
};
|
|
6130
|
+
if (this.element.readyState >= 1) {
|
|
6131
|
+
setTimeout(setupNewTracks, 200);
|
|
6132
|
+
} else {
|
|
6133
|
+
this.element.addEventListener("loadedmetadata", setupNewTracks, { once: true });
|
|
6134
|
+
setTimeout(setupNewTracks, 2e3);
|
|
6135
|
+
}
|
|
6136
|
+
}, 100);
|
|
6137
|
+
const skippedCount = validationResults.length - tracksToSwap.length;
|
|
6138
|
+
}
|
|
6139
|
+
}
|
|
6140
|
+
const allSourceElements = Array.from(this.element.querySelectorAll("source"));
|
|
6141
|
+
const sourcesToUpdate = [];
|
|
6142
|
+
allSourceElements.forEach((sourceEl) => {
|
|
6143
|
+
const descSrcAttr = sourceEl.getAttribute("data-desc-src");
|
|
6144
|
+
const currentSrc2 = sourceEl.getAttribute("src");
|
|
6145
|
+
if (descSrcAttr) {
|
|
6146
|
+
const type = sourceEl.getAttribute("type");
|
|
6147
|
+
let origSrc = sourceEl.getAttribute("data-orig-src");
|
|
6148
|
+
if (!origSrc) {
|
|
6149
|
+
origSrc = currentSrc2;
|
|
6150
|
+
}
|
|
6151
|
+
sourcesToUpdate.push({
|
|
6152
|
+
src: descSrcAttr,
|
|
6153
|
+
// Use described version
|
|
6154
|
+
type,
|
|
6155
|
+
origSrc,
|
|
6156
|
+
descSrc: descSrcAttr
|
|
6157
|
+
});
|
|
6158
|
+
} else {
|
|
6159
|
+
const type = sourceEl.getAttribute("type");
|
|
6160
|
+
const src = sourceEl.getAttribute("src");
|
|
6161
|
+
sourcesToUpdate.push({
|
|
6162
|
+
src,
|
|
6163
|
+
type,
|
|
6164
|
+
origSrc: null,
|
|
6165
|
+
descSrc: null
|
|
6166
|
+
});
|
|
6167
|
+
}
|
|
6168
|
+
});
|
|
6169
|
+
allSourceElements.forEach((sourceEl) => {
|
|
6170
|
+
sourceEl.remove();
|
|
6171
|
+
});
|
|
6172
|
+
sourcesToUpdate.forEach((sourceInfo) => {
|
|
6173
|
+
const newSource = document.createElement("source");
|
|
6174
|
+
newSource.setAttribute("src", sourceInfo.src);
|
|
6175
|
+
if (sourceInfo.type) {
|
|
6176
|
+
newSource.setAttribute("type", sourceInfo.type);
|
|
6177
|
+
}
|
|
6178
|
+
if (sourceInfo.origSrc) {
|
|
6179
|
+
newSource.setAttribute("data-orig-src", sourceInfo.origSrc);
|
|
6180
|
+
}
|
|
6181
|
+
if (sourceInfo.descSrc) {
|
|
6182
|
+
newSource.setAttribute("data-desc-src", sourceInfo.descSrc);
|
|
6183
|
+
}
|
|
6184
|
+
this.element.appendChild(newSource);
|
|
6185
|
+
});
|
|
6186
|
+
this.element.load();
|
|
6187
|
+
await new Promise((resolve) => {
|
|
6188
|
+
const onLoadedMetadata = () => {
|
|
6189
|
+
this.element.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
6190
|
+
resolve();
|
|
6191
|
+
};
|
|
6192
|
+
this.element.addEventListener("loadedmetadata", onLoadedMetadata);
|
|
6193
|
+
});
|
|
6194
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
6195
|
+
if (this.element.tagName === "VIDEO" && currentTime === 0 && !wasPlaying) {
|
|
6196
|
+
if (this.element.readyState >= 1) {
|
|
6197
|
+
this.element.currentTime = 1e-3;
|
|
6198
|
+
setTimeout(() => {
|
|
6199
|
+
this.element.currentTime = 0;
|
|
6200
|
+
}, 10);
|
|
6201
|
+
}
|
|
6202
|
+
}
|
|
6203
|
+
this.seek(currentTime);
|
|
6204
|
+
if (wasPlaying) {
|
|
6205
|
+
this.play();
|
|
6206
|
+
}
|
|
6207
|
+
this.state.audioDescriptionEnabled = true;
|
|
6208
|
+
this.emit("audiodescriptionenabled");
|
|
6209
|
+
} else {
|
|
6210
|
+
if (this.audioDescriptionCaptionTracks.length > 0) {
|
|
6211
|
+
const validationPromises = this.audioDescriptionCaptionTracks.map(async (trackInfo) => {
|
|
6212
|
+
if (trackInfo.trackElement && trackInfo.describedSrc) {
|
|
6213
|
+
if (trackInfo.explicit === true) {
|
|
6214
|
+
try {
|
|
6215
|
+
const exists = await this.validateTrackExists(trackInfo.describedSrc);
|
|
6216
|
+
return { trackInfo, exists };
|
|
6217
|
+
} catch (error) {
|
|
6218
|
+
return { trackInfo, exists: false };
|
|
6219
|
+
}
|
|
6220
|
+
} else {
|
|
6221
|
+
return { trackInfo, exists: false };
|
|
6222
|
+
}
|
|
6223
|
+
}
|
|
6224
|
+
return { trackInfo, exists: false };
|
|
6225
|
+
});
|
|
6226
|
+
const validationResults = await Promise.all(validationPromises);
|
|
6227
|
+
const tracksToSwap = validationResults.filter((result) => result.exists);
|
|
6228
|
+
if (tracksToSwap.length > 0) {
|
|
6229
|
+
const trackModes = /* @__PURE__ */ new Map();
|
|
6230
|
+
tracksToSwap.forEach(({ trackInfo }) => {
|
|
6231
|
+
const textTrack = trackInfo.trackElement.track;
|
|
6232
|
+
if (textTrack) {
|
|
6233
|
+
trackModes.set(trackInfo, {
|
|
6234
|
+
wasShowing: textTrack.mode === "showing",
|
|
6235
|
+
wasHidden: textTrack.mode === "hidden"
|
|
6236
|
+
});
|
|
6237
|
+
} else {
|
|
6238
|
+
trackModes.set(trackInfo, {
|
|
6239
|
+
wasShowing: false,
|
|
6240
|
+
wasHidden: false
|
|
6241
|
+
});
|
|
6242
|
+
}
|
|
6243
|
+
});
|
|
6244
|
+
const tracksToReadd = tracksToSwap.map(({ trackInfo }) => {
|
|
6245
|
+
const oldSrc = trackInfo.trackElement.getAttribute("src");
|
|
6246
|
+
const parent = trackInfo.trackElement.parentNode;
|
|
6247
|
+
const nextSibling = trackInfo.trackElement.nextSibling;
|
|
6248
|
+
const attributes = {};
|
|
6249
|
+
Array.from(trackInfo.trackElement.attributes).forEach((attr) => {
|
|
6250
|
+
attributes[attr.name] = attr.value;
|
|
6251
|
+
});
|
|
6252
|
+
return {
|
|
6253
|
+
trackInfo,
|
|
6254
|
+
oldSrc,
|
|
6255
|
+
parent,
|
|
6256
|
+
nextSibling,
|
|
6257
|
+
attributes
|
|
6258
|
+
};
|
|
6259
|
+
});
|
|
6260
|
+
tracksToReadd.forEach(({ trackInfo }) => {
|
|
6261
|
+
trackInfo.trackElement.remove();
|
|
6262
|
+
});
|
|
6263
|
+
this.element.load();
|
|
6264
|
+
setTimeout(() => {
|
|
6265
|
+
tracksToReadd.forEach(({ trackInfo, oldSrc, parent, nextSibling, attributes }) => {
|
|
6266
|
+
swappedTracksForTranscript.push(trackInfo);
|
|
6267
|
+
const newTrackElement = document.createElement("track");
|
|
6268
|
+
newTrackElement.setAttribute("src", trackInfo.describedSrc);
|
|
6269
|
+
Object.keys(attributes).forEach((attrName) => {
|
|
6270
|
+
if (attrName !== "src" && attrName !== "data-desc-src") {
|
|
6271
|
+
newTrackElement.setAttribute(attrName, attributes[attrName]);
|
|
6272
|
+
}
|
|
6273
|
+
});
|
|
6274
|
+
if (nextSibling && nextSibling.parentNode) {
|
|
6275
|
+
parent.insertBefore(newTrackElement, nextSibling);
|
|
6276
|
+
} else {
|
|
6277
|
+
parent.appendChild(newTrackElement);
|
|
6278
|
+
}
|
|
6279
|
+
trackInfo.trackElement = newTrackElement;
|
|
6280
|
+
});
|
|
6281
|
+
this.element.load();
|
|
6282
|
+
const setupNewTracks = () => {
|
|
6283
|
+
setTimeout(() => {
|
|
6284
|
+
swappedTracksForTranscript.forEach((trackInfo) => {
|
|
6285
|
+
const trackElement = trackInfo.trackElement;
|
|
6286
|
+
const newTextTrack = trackElement.track;
|
|
6287
|
+
if (newTextTrack) {
|
|
6288
|
+
const modeInfo = trackModes.get(trackInfo) || { wasShowing: false, wasHidden: false };
|
|
6289
|
+
newTextTrack.mode = "hidden";
|
|
6290
|
+
const restoreMode = () => {
|
|
6291
|
+
if (modeInfo.wasShowing) {
|
|
6292
|
+
newTextTrack.mode = "hidden";
|
|
6293
|
+
} else if (modeInfo.wasHidden) {
|
|
6294
|
+
newTextTrack.mode = "hidden";
|
|
6295
|
+
} else {
|
|
6296
|
+
newTextTrack.mode = "disabled";
|
|
6297
|
+
}
|
|
6298
|
+
};
|
|
6299
|
+
if (newTextTrack.readyState >= 2) {
|
|
6300
|
+
restoreMode();
|
|
6301
|
+
} else {
|
|
6302
|
+
newTextTrack.addEventListener("load", restoreMode, { once: true });
|
|
6303
|
+
newTextTrack.addEventListener("error", restoreMode, { once: true });
|
|
6304
|
+
}
|
|
6305
|
+
}
|
|
6306
|
+
});
|
|
6307
|
+
}, 300);
|
|
6308
|
+
};
|
|
6309
|
+
if (this.element.readyState >= 1) {
|
|
6310
|
+
setTimeout(setupNewTracks, 200);
|
|
6311
|
+
} else {
|
|
6312
|
+
this.element.addEventListener("loadedmetadata", setupNewTracks, { once: true });
|
|
6313
|
+
setTimeout(setupNewTracks, 2e3);
|
|
6314
|
+
}
|
|
6315
|
+
}, 100);
|
|
6316
|
+
}
|
|
6317
|
+
}
|
|
6318
|
+
const fallbackSourceElements = Array.from(this.element.querySelectorAll("source"));
|
|
6319
|
+
const hasSourceElementsWithDesc2 = fallbackSourceElements.some((el) => el.getAttribute("data-desc-src"));
|
|
6320
|
+
if (hasSourceElementsWithDesc2) {
|
|
6321
|
+
const fallbackSourcesToUpdate = [];
|
|
6322
|
+
fallbackSourceElements.forEach((sourceEl) => {
|
|
6323
|
+
const descSrcAttr = sourceEl.getAttribute("data-desc-src");
|
|
6324
|
+
const currentSrc = sourceEl.getAttribute("src");
|
|
6325
|
+
if (descSrcAttr) {
|
|
6326
|
+
const type = sourceEl.getAttribute("type");
|
|
6327
|
+
let origSrc = sourceEl.getAttribute("data-orig-src");
|
|
6328
|
+
if (!origSrc) {
|
|
6329
|
+
origSrc = currentSrc;
|
|
6330
|
+
}
|
|
6331
|
+
fallbackSourcesToUpdate.push({
|
|
6332
|
+
src: descSrcAttr,
|
|
6333
|
+
type,
|
|
6334
|
+
origSrc,
|
|
6335
|
+
descSrc: descSrcAttr
|
|
6336
|
+
});
|
|
6337
|
+
} else {
|
|
6338
|
+
const type = sourceEl.getAttribute("type");
|
|
6339
|
+
const src = sourceEl.getAttribute("src");
|
|
6340
|
+
fallbackSourcesToUpdate.push({
|
|
6341
|
+
src,
|
|
6342
|
+
type,
|
|
6343
|
+
origSrc: null,
|
|
6344
|
+
descSrc: null
|
|
6345
|
+
});
|
|
6346
|
+
}
|
|
6347
|
+
});
|
|
6348
|
+
fallbackSourceElements.forEach((sourceEl) => {
|
|
6349
|
+
sourceEl.remove();
|
|
6350
|
+
});
|
|
6351
|
+
fallbackSourcesToUpdate.forEach((sourceInfo) => {
|
|
6352
|
+
const newSource = document.createElement("source");
|
|
6353
|
+
newSource.setAttribute("src", sourceInfo.src);
|
|
6354
|
+
if (sourceInfo.type) {
|
|
6355
|
+
newSource.setAttribute("type", sourceInfo.type);
|
|
6356
|
+
}
|
|
6357
|
+
if (sourceInfo.origSrc) {
|
|
6358
|
+
newSource.setAttribute("data-orig-src", sourceInfo.origSrc);
|
|
6359
|
+
}
|
|
6360
|
+
if (sourceInfo.descSrc) {
|
|
6361
|
+
newSource.setAttribute("data-desc-src", sourceInfo.descSrc);
|
|
6362
|
+
}
|
|
6363
|
+
this.element.appendChild(newSource);
|
|
6364
|
+
});
|
|
6365
|
+
this.element.load();
|
|
6366
|
+
} else {
|
|
6367
|
+
this.element.src = this.audioDescriptionSrc;
|
|
6368
|
+
}
|
|
6369
|
+
}
|
|
5939
6370
|
await new Promise((resolve) => {
|
|
5940
6371
|
const onLoadedMetadata = () => {
|
|
5941
6372
|
this.element.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
@@ -5943,10 +6374,183 @@ var VidPly = (() => {
|
|
|
5943
6374
|
};
|
|
5944
6375
|
this.element.addEventListener("loadedmetadata", onLoadedMetadata);
|
|
5945
6376
|
});
|
|
6377
|
+
if (this.element.tagName === "VIDEO" && currentTime === 0 && !wasPlaying) {
|
|
6378
|
+
if (this.element.readyState >= 1) {
|
|
6379
|
+
this.element.currentTime = 1e-3;
|
|
6380
|
+
setTimeout(() => {
|
|
6381
|
+
this.element.currentTime = 0;
|
|
6382
|
+
}, 10);
|
|
6383
|
+
}
|
|
6384
|
+
}
|
|
5946
6385
|
this.seek(currentTime);
|
|
5947
6386
|
if (wasPlaying) {
|
|
5948
6387
|
this.play();
|
|
5949
6388
|
}
|
|
6389
|
+
if (swappedTracksForTranscript.length > 0 && this.captionManager) {
|
|
6390
|
+
const wasCaptionsEnabled = this.state.captionsEnabled;
|
|
6391
|
+
let currentTrackInfo = null;
|
|
6392
|
+
if (this.captionManager.currentTrack) {
|
|
6393
|
+
const currentTrackIndex = this.captionManager.tracks.findIndex((t) => t.track === this.captionManager.currentTrack.track);
|
|
6394
|
+
if (currentTrackIndex >= 0) {
|
|
6395
|
+
currentTrackInfo = {
|
|
6396
|
+
language: this.captionManager.tracks[currentTrackIndex].language,
|
|
6397
|
+
kind: this.captionManager.tracks[currentTrackIndex].kind
|
|
6398
|
+
};
|
|
6399
|
+
}
|
|
6400
|
+
}
|
|
6401
|
+
setTimeout(() => {
|
|
6402
|
+
this.captionManager.tracks = [];
|
|
6403
|
+
this.captionManager.loadTracks();
|
|
6404
|
+
if (wasCaptionsEnabled && currentTrackInfo && this.captionManager.tracks.length > 0) {
|
|
6405
|
+
const matchingTrackIndex = this.captionManager.tracks.findIndex(
|
|
6406
|
+
(t) => t.language === currentTrackInfo.language && t.kind === currentTrackInfo.kind
|
|
6407
|
+
);
|
|
6408
|
+
if (matchingTrackIndex >= 0) {
|
|
6409
|
+
this.captionManager.enable(matchingTrackIndex);
|
|
6410
|
+
} else if (this.captionManager.tracks.length > 0) {
|
|
6411
|
+
this.captionManager.enable(0);
|
|
6412
|
+
}
|
|
6413
|
+
}
|
|
6414
|
+
}, 600);
|
|
6415
|
+
}
|
|
6416
|
+
if (this.transcriptManager && this.transcriptManager.isVisible) {
|
|
6417
|
+
const swappedTracks = typeof swappedTracksForTranscript !== "undefined" ? swappedTracksForTranscript : [];
|
|
6418
|
+
if (swappedTracks.length > 0) {
|
|
6419
|
+
const onMetadataLoaded = () => {
|
|
6420
|
+
const allTextTracks = Array.from(this.element.textTracks);
|
|
6421
|
+
const freshTracks = swappedTracks.map((trackInfo) => {
|
|
6422
|
+
const trackEl = trackInfo.trackElement;
|
|
6423
|
+
const expectedSrc = trackEl.getAttribute("src");
|
|
6424
|
+
const srclang = trackEl.getAttribute("srclang");
|
|
6425
|
+
const kind = trackEl.getAttribute("kind");
|
|
6426
|
+
let foundTrack = allTextTracks.find((track) => trackEl.track === track);
|
|
6427
|
+
if (!foundTrack) {
|
|
6428
|
+
foundTrack = allTextTracks.find((track) => {
|
|
6429
|
+
if (track.language === srclang && (track.kind === kind || kind === "captions" && track.kind === "subtitles")) {
|
|
6430
|
+
const trackElementForTrack = Array.from(this.element.querySelectorAll("track")).find(
|
|
6431
|
+
(el) => el.track === track
|
|
6432
|
+
);
|
|
6433
|
+
if (trackElementForTrack) {
|
|
6434
|
+
const actualSrc = trackElementForTrack.getAttribute("src");
|
|
6435
|
+
if (actualSrc === expectedSrc) {
|
|
6436
|
+
return true;
|
|
6437
|
+
}
|
|
6438
|
+
}
|
|
6439
|
+
}
|
|
6440
|
+
return false;
|
|
6441
|
+
});
|
|
6442
|
+
}
|
|
6443
|
+
if (foundTrack) {
|
|
6444
|
+
const trackElement = Array.from(this.element.querySelectorAll("track")).find(
|
|
6445
|
+
(el) => el.track === foundTrack
|
|
6446
|
+
);
|
|
6447
|
+
if (trackElement && trackElement.getAttribute("src") !== expectedSrc) {
|
|
6448
|
+
return null;
|
|
6449
|
+
}
|
|
6450
|
+
}
|
|
6451
|
+
return foundTrack;
|
|
6452
|
+
}).filter(Boolean);
|
|
6453
|
+
if (freshTracks.length === 0) {
|
|
6454
|
+
setTimeout(() => {
|
|
6455
|
+
if (this.transcriptManager && this.transcriptManager.loadTranscriptData) {
|
|
6456
|
+
this.transcriptManager.loadTranscriptData();
|
|
6457
|
+
}
|
|
6458
|
+
}, 1e3);
|
|
6459
|
+
return;
|
|
6460
|
+
}
|
|
6461
|
+
freshTracks.forEach((track) => {
|
|
6462
|
+
if (track.mode === "disabled") {
|
|
6463
|
+
track.mode = "hidden";
|
|
6464
|
+
}
|
|
6465
|
+
});
|
|
6466
|
+
let loadedCount = 0;
|
|
6467
|
+
const checkLoaded = () => {
|
|
6468
|
+
loadedCount++;
|
|
6469
|
+
if (loadedCount >= freshTracks.length) {
|
|
6470
|
+
setTimeout(() => {
|
|
6471
|
+
if (this.transcriptManager && this.transcriptManager.loadTranscriptData) {
|
|
6472
|
+
const allTextTracks2 = Array.from(this.element.textTracks);
|
|
6473
|
+
const swappedTrackSrcs = swappedTracks.map((t) => t.describedSrc);
|
|
6474
|
+
const hasCorrectTracks = freshTracks.some((track) => {
|
|
6475
|
+
const trackEl = Array.from(this.element.querySelectorAll("track")).find(
|
|
6476
|
+
(el) => el.track === track
|
|
6477
|
+
);
|
|
6478
|
+
return trackEl && swappedTrackSrcs.includes(trackEl.getAttribute("src"));
|
|
6479
|
+
});
|
|
6480
|
+
if (hasCorrectTracks || freshTracks.length > 0) {
|
|
6481
|
+
this.transcriptManager.loadTranscriptData();
|
|
6482
|
+
}
|
|
6483
|
+
}
|
|
6484
|
+
}, 800);
|
|
6485
|
+
}
|
|
6486
|
+
};
|
|
6487
|
+
freshTracks.forEach((track) => {
|
|
6488
|
+
if (track.mode === "disabled") {
|
|
6489
|
+
track.mode = "hidden";
|
|
6490
|
+
}
|
|
6491
|
+
const trackElementForTrack = Array.from(this.element.querySelectorAll("track")).find(
|
|
6492
|
+
(el) => el.track === track
|
|
6493
|
+
);
|
|
6494
|
+
const actualSrc = trackElementForTrack ? trackElementForTrack.getAttribute("src") : null;
|
|
6495
|
+
const expectedTrackInfo = swappedTracks.find((t) => {
|
|
6496
|
+
const tEl = t.trackElement;
|
|
6497
|
+
return tEl && (tEl.track === track || tEl.getAttribute("srclang") === track.language && tEl.getAttribute("kind") === track.kind);
|
|
6498
|
+
});
|
|
6499
|
+
const expectedSrc = expectedTrackInfo ? expectedTrackInfo.describedSrc : null;
|
|
6500
|
+
if (expectedSrc && actualSrc && actualSrc !== expectedSrc) {
|
|
6501
|
+
checkLoaded();
|
|
6502
|
+
return;
|
|
6503
|
+
}
|
|
6504
|
+
if (track.readyState >= 2 && track.cues && track.cues.length > 0) {
|
|
6505
|
+
checkLoaded();
|
|
6506
|
+
} else {
|
|
6507
|
+
if (track.mode === "disabled") {
|
|
6508
|
+
track.mode = "hidden";
|
|
6509
|
+
}
|
|
6510
|
+
const onTrackLoad = () => {
|
|
6511
|
+
setTimeout(checkLoaded, 300);
|
|
6512
|
+
};
|
|
6513
|
+
if (track.readyState >= 2) {
|
|
6514
|
+
setTimeout(() => {
|
|
6515
|
+
if (track.cues && track.cues.length > 0) {
|
|
6516
|
+
checkLoaded();
|
|
6517
|
+
} else {
|
|
6518
|
+
track.addEventListener("load", onTrackLoad, { once: true });
|
|
6519
|
+
}
|
|
6520
|
+
}, 100);
|
|
6521
|
+
} else {
|
|
6522
|
+
track.addEventListener("load", onTrackLoad, { once: true });
|
|
6523
|
+
track.addEventListener("error", () => {
|
|
6524
|
+
checkLoaded();
|
|
6525
|
+
}, { once: true });
|
|
6526
|
+
}
|
|
6527
|
+
}
|
|
6528
|
+
});
|
|
6529
|
+
};
|
|
6530
|
+
const waitForTracks = () => {
|
|
6531
|
+
setTimeout(() => {
|
|
6532
|
+
if (this.element.readyState >= 1) {
|
|
6533
|
+
onMetadataLoaded();
|
|
6534
|
+
} else {
|
|
6535
|
+
this.element.addEventListener("loadedmetadata", onMetadataLoaded, { once: true });
|
|
6536
|
+
setTimeout(onMetadataLoaded, 2e3);
|
|
6537
|
+
}
|
|
6538
|
+
}, 500);
|
|
6539
|
+
};
|
|
6540
|
+
waitForTracks();
|
|
6541
|
+
setTimeout(() => {
|
|
6542
|
+
if (this.transcriptManager && this.transcriptManager.loadTranscriptData) {
|
|
6543
|
+
this.transcriptManager.loadTranscriptData();
|
|
6544
|
+
}
|
|
6545
|
+
}, 5e3);
|
|
6546
|
+
} else {
|
|
6547
|
+
setTimeout(() => {
|
|
6548
|
+
if (this.transcriptManager && this.transcriptManager.loadTranscriptData) {
|
|
6549
|
+
this.transcriptManager.loadTranscriptData();
|
|
6550
|
+
}
|
|
6551
|
+
}, 800);
|
|
6552
|
+
}
|
|
6553
|
+
}
|
|
5950
6554
|
this.state.audioDescriptionEnabled = true;
|
|
5951
6555
|
this.emit("audiodescriptionenabled");
|
|
5952
6556
|
}
|
|
@@ -5956,7 +6560,64 @@ var VidPly = (() => {
|
|
|
5956
6560
|
}
|
|
5957
6561
|
const currentTime = this.state.currentTime;
|
|
5958
6562
|
const wasPlaying = this.state.playing;
|
|
5959
|
-
this.
|
|
6563
|
+
if (this.audioDescriptionCaptionTracks.length > 0) {
|
|
6564
|
+
this.audioDescriptionCaptionTracks.forEach((trackInfo) => {
|
|
6565
|
+
if (trackInfo.trackElement && trackInfo.originalTrackSrc) {
|
|
6566
|
+
trackInfo.trackElement.setAttribute("src", trackInfo.originalTrackSrc);
|
|
6567
|
+
}
|
|
6568
|
+
});
|
|
6569
|
+
}
|
|
6570
|
+
const allSourceElements = Array.from(this.element.querySelectorAll("source"));
|
|
6571
|
+
const hasSourceElementsToSwap = allSourceElements.some((el) => el.getAttribute("data-orig-src"));
|
|
6572
|
+
if (hasSourceElementsToSwap) {
|
|
6573
|
+
const sourcesToRestore = [];
|
|
6574
|
+
allSourceElements.forEach((sourceEl) => {
|
|
6575
|
+
const origSrcAttr = sourceEl.getAttribute("data-orig-src");
|
|
6576
|
+
const descSrcAttr = sourceEl.getAttribute("data-desc-src");
|
|
6577
|
+
if (origSrcAttr) {
|
|
6578
|
+
const type = sourceEl.getAttribute("type");
|
|
6579
|
+
sourcesToRestore.push({
|
|
6580
|
+
src: origSrcAttr,
|
|
6581
|
+
// Use original version
|
|
6582
|
+
type,
|
|
6583
|
+
origSrc: origSrcAttr,
|
|
6584
|
+
descSrc: descSrcAttr
|
|
6585
|
+
// Keep data-desc-src for future swaps
|
|
6586
|
+
});
|
|
6587
|
+
} else {
|
|
6588
|
+
const type = sourceEl.getAttribute("type");
|
|
6589
|
+
const src = sourceEl.getAttribute("src");
|
|
6590
|
+
sourcesToRestore.push({
|
|
6591
|
+
src,
|
|
6592
|
+
type,
|
|
6593
|
+
origSrc: null,
|
|
6594
|
+
descSrc: descSrcAttr
|
|
6595
|
+
});
|
|
6596
|
+
}
|
|
6597
|
+
});
|
|
6598
|
+
allSourceElements.forEach((sourceEl) => {
|
|
6599
|
+
sourceEl.remove();
|
|
6600
|
+
});
|
|
6601
|
+
sourcesToRestore.forEach((sourceInfo) => {
|
|
6602
|
+
const newSource = document.createElement("source");
|
|
6603
|
+
newSource.setAttribute("src", sourceInfo.src);
|
|
6604
|
+
if (sourceInfo.type) {
|
|
6605
|
+
newSource.setAttribute("type", sourceInfo.type);
|
|
6606
|
+
}
|
|
6607
|
+
if (sourceInfo.origSrc) {
|
|
6608
|
+
newSource.setAttribute("data-orig-src", sourceInfo.origSrc);
|
|
6609
|
+
}
|
|
6610
|
+
if (sourceInfo.descSrc) {
|
|
6611
|
+
newSource.setAttribute("data-desc-src", sourceInfo.descSrc);
|
|
6612
|
+
}
|
|
6613
|
+
this.element.appendChild(newSource);
|
|
6614
|
+
});
|
|
6615
|
+
this.element.load();
|
|
6616
|
+
} else {
|
|
6617
|
+
const originalSrcToUse = this.originalAudioDescriptionSource || this.originalSrc;
|
|
6618
|
+
this.element.src = originalSrcToUse;
|
|
6619
|
+
this.element.load();
|
|
6620
|
+
}
|
|
5960
6621
|
await new Promise((resolve) => {
|
|
5961
6622
|
const onLoadedMetadata = () => {
|
|
5962
6623
|
this.element.removeEventListener("loadedmetadata", onLoadedMetadata);
|
|
@@ -5968,13 +6629,29 @@ var VidPly = (() => {
|
|
|
5968
6629
|
if (wasPlaying) {
|
|
5969
6630
|
this.play();
|
|
5970
6631
|
}
|
|
6632
|
+
if (this.transcriptManager && this.transcriptManager.isVisible) {
|
|
6633
|
+
setTimeout(() => {
|
|
6634
|
+
if (this.transcriptManager && this.transcriptManager.loadTranscriptData) {
|
|
6635
|
+
this.transcriptManager.loadTranscriptData();
|
|
6636
|
+
}
|
|
6637
|
+
}, 500);
|
|
6638
|
+
}
|
|
5971
6639
|
this.state.audioDescriptionEnabled = false;
|
|
5972
6640
|
this.emit("audiodescriptiondisabled");
|
|
5973
6641
|
}
|
|
5974
6642
|
async toggleAudioDescription() {
|
|
5975
6643
|
const textTracks = Array.from(this.element.textTracks || []);
|
|
5976
6644
|
const descriptionTrack = textTracks.find((track) => track.kind === "descriptions");
|
|
5977
|
-
|
|
6645
|
+
const hasAudioDescriptionSrc = this.audioDescriptionSrc || Array.from(this.element.querySelectorAll("source")).some((el) => el.getAttribute("data-desc-src"));
|
|
6646
|
+
if (descriptionTrack && hasAudioDescriptionSrc) {
|
|
6647
|
+
if (this.state.audioDescriptionEnabled) {
|
|
6648
|
+
descriptionTrack.mode = "hidden";
|
|
6649
|
+
await this.disableAudioDescription();
|
|
6650
|
+
} else {
|
|
6651
|
+
await this.enableAudioDescription();
|
|
6652
|
+
descriptionTrack.mode = "showing";
|
|
6653
|
+
}
|
|
6654
|
+
} else if (descriptionTrack) {
|
|
5978
6655
|
if (descriptionTrack.mode === "showing") {
|
|
5979
6656
|
descriptionTrack.mode = "hidden";
|
|
5980
6657
|
this.state.audioDescriptionEnabled = false;
|
|
@@ -5984,7 +6661,7 @@ var VidPly = (() => {
|
|
|
5984
6661
|
this.state.audioDescriptionEnabled = true;
|
|
5985
6662
|
this.emit("audiodescriptionenabled");
|
|
5986
6663
|
}
|
|
5987
|
-
} else if (
|
|
6664
|
+
} else if (hasAudioDescriptionSrc) {
|
|
5988
6665
|
if (this.state.audioDescriptionEnabled) {
|
|
5989
6666
|
await this.disableAudioDescription();
|
|
5990
6667
|
} else {
|