Release v2.14.1
This commit is contained in:
1 parent
635e1a9942
commit
c3299abaac
174 files changed
+4483
-1687
No files matched your search
@@ -1,5 +1,15 @@
|
||||
// Slide media startup and teardown helpers.
|
||||
|
||||
var renderedVideoPlaybackCleanup = new WeakMap();
|
||||
|
||||
function cancelRenderedVideoPlayback(video) {
|
||||
var cleanup = renderedVideoPlaybackCleanup.get(video);
|
||||
if (cleanup) {
|
||||
cleanup();
|
||||
renderedVideoPlaybackCleanup.delete(video);
|
||||
}
|
||||
}
|
||||
|
||||
function initializeRenderedVideoPlayback(root, delayMs) {
|
||||
if (!root) {
|
||||
return;
|
||||
@@ -12,14 +22,37 @@ function initializeRenderedVideoPlayback(root, delayMs) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancelRenderedVideoPlayback(video);
|
||||
var playbackScheduled = false;
|
||||
var playbackCancelled = false;
|
||||
var playbackTimer = null;
|
||||
|
||||
function removeReadinessListeners() {
|
||||
video.removeEventListener('canplay', schedulePlaybackStart);
|
||||
video.removeEventListener('loadedmetadata', onLoadedMetadata);
|
||||
}
|
||||
|
||||
// A cancelled callback can already be queued for dispatch, so it also checks this flag.
|
||||
renderedVideoPlaybackCleanup.set(video, function () {
|
||||
playbackCancelled = true;
|
||||
if (playbackTimer !== null) {
|
||||
window.clearTimeout(playbackTimer);
|
||||
playbackTimer = null;
|
||||
}
|
||||
removeReadinessListeners();
|
||||
});
|
||||
|
||||
// Script-controlled startup aligns playback with the incoming slide's fade timing.
|
||||
video.autoplay = false;
|
||||
video.loop = !(video.dataset && video.dataset.loop === '0');
|
||||
video.muted = !(video.dataset && video.dataset.disableAudio === '0');
|
||||
video.playsInline = true;
|
||||
|
||||
function startPlayback() {
|
||||
playbackTimer = null;
|
||||
if (playbackCancelled || video.isConnected === false || root.isConnected === false) {
|
||||
return;
|
||||
}
|
||||
var playPromise = video.play && video.play();
|
||||
if (playPromise && typeof playPromise.catch === 'function') {
|
||||
playPromise.catch(function () {
|
||||
@@ -29,28 +62,33 @@ function initializeRenderedVideoPlayback(root, delayMs) {
|
||||
}
|
||||
|
||||
function schedulePlaybackStart() {
|
||||
if (playbackScheduled) {
|
||||
// Metadata and canplay can both fire; schedule only one start for this video.
|
||||
if (playbackCancelled || playbackScheduled) {
|
||||
return;
|
||||
}
|
||||
playbackScheduled = true;
|
||||
removeReadinessListeners();
|
||||
if (startDelayMs > 0) {
|
||||
window.setTimeout(startPlayback, startDelayMs);
|
||||
playbackTimer = window.setTimeout(startPlayback, startDelayMs);
|
||||
return;
|
||||
}
|
||||
startPlayback();
|
||||
}
|
||||
|
||||
function onLoadedMetadata() {
|
||||
if (video.readyState >= 2) {
|
||||
schedulePlaybackStart();
|
||||
}
|
||||
}
|
||||
|
||||
// HAVE_CURRENT_DATA means a frame is available, not just the video's metadata.
|
||||
if (video.readyState >= 2) {
|
||||
schedulePlaybackStart();
|
||||
return;
|
||||
}
|
||||
|
||||
video.addEventListener('canplay', schedulePlaybackStart, { once: true });
|
||||
video.addEventListener('loadedmetadata', function () {
|
||||
if (video.readyState >= 2) {
|
||||
schedulePlaybackStart();
|
||||
}
|
||||
}, { once: true });
|
||||
video.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -87,7 +125,28 @@ function initializeSlideMedia(root, delayMs) {
|
||||
initializeRenderedVideoPlayback(root, delayMs);
|
||||
}
|
||||
|
||||
function destroySlideMedia(root) {
|
||||
function destroySlideMedia(root, options) {
|
||||
if (!root) {
|
||||
return;
|
||||
}
|
||||
|
||||
var preserveVideoFrame = Boolean(options && options.preserveVideoFrame);
|
||||
var videos = root.querySelectorAll('.template-region.video video, .slide-media video');
|
||||
Array.prototype.forEach.call(videos, function (video) {
|
||||
cancelRenderedVideoPlayback(video);
|
||||
if (typeof video.pause === 'function') {
|
||||
video.pause();
|
||||
}
|
||||
// Keep the paused frame through a crossfade; release decoder/network resources at removal.
|
||||
if (!preserveVideoFrame) {
|
||||
video.removeAttribute('src');
|
||||
if (typeof video.load === 'function') {
|
||||
video.load();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// RTMP players hold independent HLS resources beyond the lifetime of their DOM nodes.
|
||||
if (typeof destroyRtmpRegions === 'function') {
|
||||
destroyRtmpRegions(root);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user