当观察者切换浏览器选项卡或最小化浏览器窗口时播放/暂停Vimeo视频



我正在使用Vimeo Pro在Wordpress网站上上传视频课程,然后使用H5P为视频添加交互。

为了在H5P交互式视频中插入这些vimeo视频,我需要使用Vimeo Pro(而不是Vimeo Iframe(的.mp4发行版。这是一个示例:

https://player.vimeo.com/external/376040732.sd.mp4?s=a88abddb83ad31962643b6c4dd8270323d80874e&profile_id=165


在网站上

如果我检查我的网站,这是代码:

<div class="h5p-video-wrapper h5p-video hardware-accelerated">
<video src="https://player.vimeo.com/external/376040732.sd.mp4?s=a88abddb83ad31962643b6c4dd8270323d80874e&amp;profile_id=165" webkit-playsinline="" playsinline="" preload="metadata" disableremoteplayback="" class="h5p-video" style="display: block;">
</video>
<div class="h5p-overlay h5p-ie-transparent-background"></div>
</div>

我的请求

当学生切换浏览器选项卡或最小化浏览器窗口时,暂停视频的最简单方法是什么?感谢您的帮助!

编辑 - 解决方案

Matt Oestreich和Oliver Tacke的脚本都可以在网页中只插入一个H5P交互式视频

注意:如果您需要在网页中插入多个H5P交互式视频,请使用Matt Oestreich的脚本。

  • 您可以在此处找到现场演示站点
  • 您可以在此处找到使用的所有必要代码。
  • OP的实时网站正在使用它


答:

由于这些答案中的字符限制,我不得不清除很多以前的更新。

我设法让它与多个 iframe 一起工作。

唯一的问题是,如果有人播放 2 个不同的视频,然后单击不同的选项卡(暂停所有视频(然后他们回来,它将播放所有视频......我可以尝试找出一些方法来解决这个问题,但现在这应该可以了。

请务必查看上面更新的演示站点。

只需将此脚本放在任何包含您希望使用页面可见 API 暂停/播放的视频的页面上,其余的应该自行处理。

您将需要使用以下内容:

const THE_IFRAME_SELECTOR = 'iframe[id^="h5p-iframe-"]'; // matches all iframes with an id that starts with h5p-iframe-
const THE_VIDEO_SELECTOR = 'video.h5p-video'; // since all videos appear to have the same class you don't need to change this

因此,新脚本应如下所示:

// ====================================================================================================================
// ~~~ SECOND SCRIPT ~~~ 
// THIS WAITS FOR THE IFRAME AND THE VIDEO INSIDE OF THE IFRAME TO BE CREATED BEFORE INITIALIZING THE PAGE VISIBLE API
// ====================================================================================================================
// "Global" variables.
const THE_IFRAME_SELECTOR = 'iframe[id^="h5p-iframe-"]'; // matches all iframes with an id that starts with h5p-iframe-
const THE_VIDEO_SELECTOR = 'video.h5p-video'; // since all videos appear to have the same class you don't need to change this
waitForMultipleElements(document, THE_IFRAME_SELECTOR, () => {
let ALL_IFRAMES = document.querySelectorAll(THE_IFRAME_SELECTOR);
ALL_IFRAMES.forEach(FOUND_IFRAME => {
let FOUND_IFRAME_SELECTOR = `#${FOUND_IFRAME.id}`;
console.log("FOUND_IFRAME_SELECTOR:", FOUND_IFRAME_SELECTOR)
waitForElement(document, FOUND_IFRAME_SELECTOR, () => {
waitForVideoElement(FOUND_IFRAME_SELECTOR, THE_VIDEO_SELECTOR, () => {
initPageVisibleApi(FOUND_IFRAME_SELECTOR, THE_VIDEO_SELECTOR);
});
});
});
});
function waitForMultipleElements(parentEl, selector, callback) {
let theInterval = setInterval(() => {
console.log('still waiting for all elements: ' + selector);
let elements = parentEl.querySelectorAll(selector);
if (elements.length) {
console.log("elements: " + selector + " exist!");
clearInterval(theInterval);
callback();
}
}, 1000);
}
function waitForVideoElement(iframeSelector, videoElementSelector, callback) {
let theIframeElement = document.querySelector(iframeSelector);
let iframeEl = theIframeElement.contentWindow.document;
waitForElement(iframeEl, videoElementSelector, () => {
callback()
});
}
function waitForElement(parentEl, selectorOfElementToWaitFor, callback) {
let theInterval = setInterval(() => {
console.log("still waiting for " + selectorOfElementToWaitFor);
let element = parentEl.querySelector(selectorOfElementToWaitFor);
if (element) {
console.log(selectorOfElementToWaitFor + " exists!");
clearInterval(theInterval);
callback();
}
}, 100);
}
function initPageVisibleApi(iframeSelector, videoSelector) {
// This is the same code that builds out the Page Visible API
// event listeners. 
// The only difference is I wrapped it in a function and added 
// parameters to make it flexible.
const iframe = document.querySelector(iframeSelector);
const innerDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;
const videoElement = innerDoc.querySelector(videoSelector);
// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support 
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
// To tell if video has been played yet or not
let VIDEO_HAS_BEEN_PLAYED = false;
// If the page is hidden, pause the video;
// if the page is shown, play the video
function handleVisibilityChange() {
if (VIDEO_HAS_BEEN_PLAYED) {
if (document[hidden]) {
videoElement.pause();
} else {
videoElement.play();
}
}
}
// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" || hidden === undefined) {
alert("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
// Handle page visibility change   
document.addEventListener(visibilityChange, handleVisibilityChange, false);
// When the video pauses, set the title.
// This shows the paused
const defaultTitle = document.title;
videoElement.addEventListener("pause", function () {
document.title = 'Paused - ' + defaultTitle;
}, false);
// When the video plays, set the title.
videoElement.addEventListener("play", function () {
VIDEO_HAS_BEEN_PLAYED = true;
document.title = 'Playing - ' + defaultTitle;
}, false);
}
}
// ====================================================================================================================
// ---------- END SECOND SCRIPT ------------
// ====================================================================================================================

如果你想修改H5P的功能,而不是"黑客",你可能应该使用自定义它的常用方法。它通常会让事情变得容易得多。有关详细信息,请参阅 https://h5p.org/wordpress-customization。

无论如何,如果您想在WordPress主题中添加一些脚本,这应该可以:

// This will only work for the first H5P IV found on the page!
// Since I don't know your environment, let's stick with ES5
var hidden, visibilityChange;
var interactiveVideo;
var currentState = -1;
var restartVideo = false;
/**
* Handle change of page visibility.
*/
function handleVisibilityChange() {
if ( ! interactiveVideo ) {
return;
}
if ( document[hidden] ) {
// There's nothing to do if the video isn't playing at all
if ( 1 !== currentState ) {
return;
}
restartVideo = true;
interactiveVideo.pause();
}
else {
// Restart if video was playing before
if ( ! restartVideo ) {
return;
}
restartVideo = false;
interactiveVideo.play();
}
}
/**
* Add the stop/resume feature to video.
* @param {Window} contentWindow Content Window containing H5P.
*/
function addVideoStopResume( contentWindow ) {
// Set the name of the hidden property and the change event for visibility
if ( 'undefined' !== typeof document.hidden ) { // Opera 12.10 and Firefox 18 and later support
hidden = 'hidden';
visibilityChange = 'visibilitychange';
}
else if ( 'undefined' !== typeof document.msHidden ) {
hidden = 'msHidden';
visibilityChange = "msvisibilitychange";
}
else if ( 'undefined' !== typeof document.webkitHidden ) {
hidden = 'webkitHidden';
visibilityChange = 'webkitvisibilitychange';
}
// Get first instance of H5P.interactiveVideo -- will not work properly if there are more instances of IV!
interactiveVideo = interactiveVideo || contentWindow.H5P.instances.filter( function ( instance ) {
return instance.libraryInfo && 'H5P.InteractiveVideo' === instance.libraryInfo.machineName;
})[0];
if ( ! interactiveVideo ) {
return;
}
// Remember current video state
interactiveVideo.video.on('stateChange', function (state) {
currentState = state.data;
});
if ( 'undefined' === typeof document.addEventListener || undefined === hidden ) {
console.warn( 'The video stop/resume feature requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.' );
}
else {
// Handle page visibility change
document.addEventListener( visibilityChange, handleVisibilityChange, false );
}
}
/**
* Initialize stop/resume feature.
*/
function initVideoStopResume() {
var iframes = document.getElementsByTagName( 'iframe' );
var i;
var contentWindow;
// Add EventListener if H5P content is present
if ( 'complete' === document.readyState ) {
for ( i = 0; i < iframes.length; i++ ) {
// Skip non H5P iframes and remote iframes
if ( ! iframes[i].classList.contains( 'h5p-iframe' ) &&
(
0 !== iframes[i].src.indexOf( window.location.origin ) ||
-1 === iframes[i].src.indexOf( 'action=h5p_embed' )
)
) {
continue;
}
// Edge needs to wait for iframe to be loaded, others don't
contentWindow = iframes[i].contentWindow;
if ( contentWindow.H5P ) {
addVideoStopResume( contentWindow );
}
else {
iframes[i].addEventListener( 'load', function () {
contentWindow = this.contentWindow;
addVideoStopResume( contentWindow );
});
}
}
}
}
// Amend content functionality when H5P content has loaded
if ( 'complete' === document.readyState ) {
initVideoStopResume();
}
else {
document.onreadystatechange = function () {
if ( 'complete' === document.readyState ) {
initVideoStopResume();
}
};
}

该脚本将等到页面加载完毕,然后遍历页面上的每个 H5P iframe,搜索交互式视频。然后,它将添加所需的功能,以在可见性更改时停止/恢复视频。

请注意,如果您在其他内容类型(如 H5P 列(中使用 IV,则此解决方案将无法正常工作。此外,它仅适用于页面上的第一个交互式视频。添加这些功能将需要更多的代码,并且没有请求。

最新更新