如何在requestPictureInPicture中播放多个视频?
How to play Multiple Videos in requestPictureInPicture?
requestPictureInPicture 太神奇了,但它看起来只适用于 1 个视频。
如何让requestPictureInPicture播放多个视频,让我可以同时观看两个视频?
基本上这只显示一个视频:
video
.requestPictureInPicture()
.catch(error => {
console.log(error) // Error handling
});
video2
.requestPictureInPicture()
.catch(error => {
console.log(error) // Error handling
});
https://codepen.io/zecheesy/pen/YzwBJMR
想法:也许我们可以将两个视频放在一个 canvas 中?并让 pictureInPicture 同时播放两个视频? https://googlechrome.github.io/samples/picture-in-picture/audio-playlist
我不确定这是否可行。非常希望得到您的帮助!
关于同时打开两个 PictureInPitcure windows,the specs have a paragraph 只是为了它,他们解释说他们实际上把它留作实现细节:
Operating systems with a Picture-in-Picture API usually restrict Picture-in-Picture mode to only one window. Whether only one window is allowed in Picture-in-Picture mode will be left to the implementation and the platform. However, because of the one Picture-in-Picture window limitation, the specification assumes that a given Document can only have one Picture-in-Picture window.
What happens when there is a Picture-in-Picture request while a window is already in Picture-in-Picture will be left as an implementation detail: the current Picture-in-Picture window could be closed, the Picture-in-Picture request could be rejected or even two Picture-in-Picture windows could be created. Regardless, the User Agent will have to fire the appropriate events in order to notify the website of the Picture-in-Picture status changes.
所以我们只能说您不应该期望它同时打开两个 windows。
现在,如果您真的愿意,您确实可以在 canvas 上绘制两个视频,然后将此 canvas 传递给画中画 window,然后将其 captureStream()
管道化到第三个
这是一个概念证明:
const vids = document.querySelectorAll( "video" );
const btn = document.querySelector( "button" );
// wait for both video has their metadata
Promise.all( [ ...vids ].map( (vid) => {
return new Promise( (res) => vid.onloadedmetadata = () => res() );
} ) )
.then( () => {
if( !HTMLVideoElement.prototype.requestPictureInPicture ) {
return console.error( "Your browser doesn't support the PiP API" );
}
btn.onclick = async (evt) => {
const canvas = document.createElement( "canvas" );
// both videos share the same 16/9 ratio
// so in this case it's really easy to draw both on the same canvas
// to make it dynamic would require more maths
// but I'll let it to the readers
const height = 720;
const width = 1280;
canvas.height = height * 2; // vertical disposition
canvas.width = width;
const ctx = canvas.getContext( "2d" );
const video = document.createElement( "video" );
video.srcObject = canvas.captureStream();
let began = false; // rPiP needs video's metadata
anim();
await video.play();
began = true;
video.requestPictureInPicture();
function anim() {
ctx.drawImage( vids[ 0 ], 0, 0, width, height );
ctx.drawImage( vids[ 1 ], 0, height, width, height );
// iff we are still in PiP mode
if( !began || document.pictureInPictureElement === video ) {
requestAnimationFrame( anim );
}
else {
// kill the stream
video.srcObject.getTracks().forEach( track => track.stop() );
}
}
}
} );
video { width: 300px }
<button>enter Picture in Picture</button><br>
<video crossorigin muted controls autoplay loop
src="https://upload.wikimedia.org/wikipedia/commons/2/22/Volcano_Lava_Sample.webm"></video>
<video crossorigin muted controls autoplay loop
src="https://upload.wikimedia.org/wikipedia/commons/a/a4/BBH_gravitational_lensing_of_gw150914.webm"></video>
请注意,因为我确实将视频静音,所以以原始视频看不见的方式滚动会使它们暂停。
requestPictureInPicture 太神奇了,但它看起来只适用于 1 个视频。
如何让requestPictureInPicture播放多个视频,让我可以同时观看两个视频?
基本上这只显示一个视频:
video
.requestPictureInPicture()
.catch(error => {
console.log(error) // Error handling
});
video2
.requestPictureInPicture()
.catch(error => {
console.log(error) // Error handling
});
https://codepen.io/zecheesy/pen/YzwBJMR
想法:也许我们可以将两个视频放在一个 canvas 中?并让 pictureInPicture 同时播放两个视频? https://googlechrome.github.io/samples/picture-in-picture/audio-playlist
我不确定这是否可行。非常希望得到您的帮助!
关于同时打开两个 PictureInPitcure windows,the specs have a paragraph 只是为了它,他们解释说他们实际上把它留作实现细节:
Operating systems with a Picture-in-Picture API usually restrict Picture-in-Picture mode to only one window. Whether only one window is allowed in Picture-in-Picture mode will be left to the implementation and the platform. However, because of the one Picture-in-Picture window limitation, the specification assumes that a given Document can only have one Picture-in-Picture window.
What happens when there is a Picture-in-Picture request while a window is already in Picture-in-Picture will be left as an implementation detail: the current Picture-in-Picture window could be closed, the Picture-in-Picture request could be rejected or even two Picture-in-Picture windows could be created. Regardless, the User Agent will have to fire the appropriate events in order to notify the website of the Picture-in-Picture status changes.
所以我们只能说您不应该期望它同时打开两个 windows。
现在,如果您真的愿意,您确实可以在 canvas 上绘制两个视频,然后将此 canvas 传递给画中画 window,然后将其 captureStream()
管道化到第三个
这是一个概念证明:
const vids = document.querySelectorAll( "video" );
const btn = document.querySelector( "button" );
// wait for both video has their metadata
Promise.all( [ ...vids ].map( (vid) => {
return new Promise( (res) => vid.onloadedmetadata = () => res() );
} ) )
.then( () => {
if( !HTMLVideoElement.prototype.requestPictureInPicture ) {
return console.error( "Your browser doesn't support the PiP API" );
}
btn.onclick = async (evt) => {
const canvas = document.createElement( "canvas" );
// both videos share the same 16/9 ratio
// so in this case it's really easy to draw both on the same canvas
// to make it dynamic would require more maths
// but I'll let it to the readers
const height = 720;
const width = 1280;
canvas.height = height * 2; // vertical disposition
canvas.width = width;
const ctx = canvas.getContext( "2d" );
const video = document.createElement( "video" );
video.srcObject = canvas.captureStream();
let began = false; // rPiP needs video's metadata
anim();
await video.play();
began = true;
video.requestPictureInPicture();
function anim() {
ctx.drawImage( vids[ 0 ], 0, 0, width, height );
ctx.drawImage( vids[ 1 ], 0, height, width, height );
// iff we are still in PiP mode
if( !began || document.pictureInPictureElement === video ) {
requestAnimationFrame( anim );
}
else {
// kill the stream
video.srcObject.getTracks().forEach( track => track.stop() );
}
}
}
} );
video { width: 300px }
<button>enter Picture in Picture</button><br>
<video crossorigin muted controls autoplay loop
src="https://upload.wikimedia.org/wikipedia/commons/2/22/Volcano_Lava_Sample.webm"></video>
<video crossorigin muted controls autoplay loop
src="https://upload.wikimedia.org/wikipedia/commons/a/a4/BBH_gravitational_lensing_of_gw150914.webm"></video>
请注意,因为我确实将视频静音,所以以原始视频看不见的方式滚动会使它们暂停。