在画中画模式中开始视频,同时(!)在 javascript 中打开一个新的 window
Starting a video in picture in picture mode, while(!) opening a new window in javascript
我正在尝试调用从按钮触发的以下两个命令:
window.open('https://www.google.com/', '_blank');
await video.requestPictureInPicture();
但无论我如何尝试调用这些函数,一个都不起作用(在 移动设备 设备上)
我的理论是,这两个命令都需要用户交互,并且由于用户只提供一个交互(按钮单击),因此只会执行一个命令,而另一个将由于缺少用户交互而被阻止。
有人知道如何实现吗?
代码示例可在以下位置找到:
https://codepen.io/eyalsi/pen/QWOqQRQ
我认为画中画请求被拒绝是因为原始 window 在调用 API 之前失去了焦点。如果您推迟新的 window 开幕,那么它将有效 demo。
可供参考的代码:
let status = '';
if (!('pictureInPictureEnabled' in document)) {
status = '<span style="color:darkred;">The Picture-in-Picture API is not available.</span>'
} else if (!document.pictureInPictureEnabled) {
status = '<span style="color:darkred;">The Picture-in-Picture API is disabled.</span>';
} else {
status = '<span style="color:green">PiP available!</span>'
}
console.log(status);
stat.insertAdjacentHTML('beforeend', `<br>Status: ${status}`);
let pipWindow;
let log = console.log;
togglePipButton.addEventListener("click", async function(event) {
log("Toggling Picture-in-Picture...");
togglePipButton.disabled = true;
try {
// enqueue the task in message queue <-- fix
setTimeout(() => {
log("opening window");
window.open("https://developer.mozilla.org/en-US/", "MDN");
});
if (video !== document.pictureInPictureElement) {
log("requestPictureInPicture");
let pipWindow = await video.requestPictureInPicture();
await video.play();
} else {
await document.exitPictureInPicture();
}
} catch (error) {
console.error(error);
} finally {
togglePipButton.disabled = false;
}
});
// Note that this can happen if user clicked the "Toggle Picture-in-Picture"
// button but also if user clicked some browser context menu or if
// Picture-in-Picture was triggered automatically for instance.
video.addEventListener("enterpictureinpicture", function(event) {
log("> Video entered Picture-in-Picture");
pipWindow = event.pictureInPictureWindow;
log(`> Window size is ${pipWindow.width}x${pipWindow.height}`);
pipWindow.addEventListener("resize", onPipWindowResize);
});
video.addEventListener("leavepictureinpicture", function(event) {
log("> Video left Picture-in-Picture");
pipWindow.removeEventListener("resize", onPipWindowResize);
});
function onPipWindowResize(event) {
log(`> Window size changed to ${pipWindow.width}x${pipWindow.height}`);
}
/* Feature support */
if ("pictureInPictureEnabled" in document) {
// Set button ability depending on whether Picture-in-Picture can be used.
setPipButton();
video.addEventListener("loadedmetadata", setPipButton);
video.addEventListener("emptied", setPipButton);
} else {
// Hide button if Picture-in-Picture is not supported.
togglePipButton.hidden = true;
}
function setPipButton() {
togglePipButton.disabled =
video.readyState === 0 ||
!document.pictureInPictureEnabled ||
video.disablePictureInPicture;
}
video {
background: #1e2327;
border-radius: 4px;
width: 30%;
}
button {
margin: 1rem 0 0 0;
}
<video id="video" controls playsinline src="https://storage.googleapis.com/media-session/caminandes/short.mp4" poster="https://storage.googleapis.com/media-session/caminandes/artwork-512.png"></video>
<br>
<button id="togglePipButton">Toggle PIP AND new window</button>
<div id="stat"></div>
<p>
<br> Taken originally from:
<a href="https://googlechrome.github.io/samples/picture-in-picture/">GoogleChrome/samples</a>
</p>
或者你可以在请求画中画后在finally块中调用window.open()
。在 Chrome 98 和 Windows 10 上测试,在 Safari 15.2 上测试 iPad。
注意:Whosebug 上的代码片段无法打开新的 popups/windows。要进行测试,请使用上面提供的 demo link。
我正在尝试调用从按钮触发的以下两个命令:
window.open('https://www.google.com/', '_blank');
await video.requestPictureInPicture();
但无论我如何尝试调用这些函数,一个都不起作用(在 移动设备 设备上) 我的理论是,这两个命令都需要用户交互,并且由于用户只提供一个交互(按钮单击),因此只会执行一个命令,而另一个将由于缺少用户交互而被阻止。
有人知道如何实现吗?
代码示例可在以下位置找到: https://codepen.io/eyalsi/pen/QWOqQRQ
我认为画中画请求被拒绝是因为原始 window 在调用 API 之前失去了焦点。如果您推迟新的 window 开幕,那么它将有效 demo。
可供参考的代码:
let status = '';
if (!('pictureInPictureEnabled' in document)) {
status = '<span style="color:darkred;">The Picture-in-Picture API is not available.</span>'
} else if (!document.pictureInPictureEnabled) {
status = '<span style="color:darkred;">The Picture-in-Picture API is disabled.</span>';
} else {
status = '<span style="color:green">PiP available!</span>'
}
console.log(status);
stat.insertAdjacentHTML('beforeend', `<br>Status: ${status}`);
let pipWindow;
let log = console.log;
togglePipButton.addEventListener("click", async function(event) {
log("Toggling Picture-in-Picture...");
togglePipButton.disabled = true;
try {
// enqueue the task in message queue <-- fix
setTimeout(() => {
log("opening window");
window.open("https://developer.mozilla.org/en-US/", "MDN");
});
if (video !== document.pictureInPictureElement) {
log("requestPictureInPicture");
let pipWindow = await video.requestPictureInPicture();
await video.play();
} else {
await document.exitPictureInPicture();
}
} catch (error) {
console.error(error);
} finally {
togglePipButton.disabled = false;
}
});
// Note that this can happen if user clicked the "Toggle Picture-in-Picture"
// button but also if user clicked some browser context menu or if
// Picture-in-Picture was triggered automatically for instance.
video.addEventListener("enterpictureinpicture", function(event) {
log("> Video entered Picture-in-Picture");
pipWindow = event.pictureInPictureWindow;
log(`> Window size is ${pipWindow.width}x${pipWindow.height}`);
pipWindow.addEventListener("resize", onPipWindowResize);
});
video.addEventListener("leavepictureinpicture", function(event) {
log("> Video left Picture-in-Picture");
pipWindow.removeEventListener("resize", onPipWindowResize);
});
function onPipWindowResize(event) {
log(`> Window size changed to ${pipWindow.width}x${pipWindow.height}`);
}
/* Feature support */
if ("pictureInPictureEnabled" in document) {
// Set button ability depending on whether Picture-in-Picture can be used.
setPipButton();
video.addEventListener("loadedmetadata", setPipButton);
video.addEventListener("emptied", setPipButton);
} else {
// Hide button if Picture-in-Picture is not supported.
togglePipButton.hidden = true;
}
function setPipButton() {
togglePipButton.disabled =
video.readyState === 0 ||
!document.pictureInPictureEnabled ||
video.disablePictureInPicture;
}
video {
background: #1e2327;
border-radius: 4px;
width: 30%;
}
button {
margin: 1rem 0 0 0;
}
<video id="video" controls playsinline src="https://storage.googleapis.com/media-session/caminandes/short.mp4" poster="https://storage.googleapis.com/media-session/caminandes/artwork-512.png"></video>
<br>
<button id="togglePipButton">Toggle PIP AND new window</button>
<div id="stat"></div>
<p>
<br> Taken originally from:
<a href="https://googlechrome.github.io/samples/picture-in-picture/">GoogleChrome/samples</a>
</p>
或者你可以在请求画中画后在finally块中调用window.open()
。在 Chrome 98 和 Windows 10 上测试,在 Safari 15.2 上测试 iPad。
注意:Whosebug 上的代码片段无法打开新的 popups/windows。要进行测试,请使用上面提供的 demo link。