TransWikia.com

How to play Multiple Videos in requestPictureInPicture?

Stack Overflow Asked by maddie on December 2, 2021

requestPictureInPicture is so amazing, but it looks like it only works with 1 video.

How can I get requestPictureInPicture to play multiple videos, so I can watch two videos at the same time?

Basically this only displays one video:

      video
      .requestPictureInPicture()
      .catch(error => {
        console.log(error) // Error handling
      });
      video2
      .requestPictureInPicture()
      .catch(error => {
        console.log(error) // Error handling
      });

https://codepen.io/zecheesy/pen/YzwBJMR

Thoughts: Maybe we could put two videos in a canvas? And have the pictureInPicture play both videos at the same time? https://googlechrome.github.io/samples/picture-in-picture/audio-playlist

I’m not sure if this is possible. Would love your help so much!

One Answer

Regarding opening two PictureInPitcure windows simultaneously, the specs have a paragraph just for it, where they explain they actually leave it as an implementation detail:

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.

So the best we can say it that you should not expect it to open two windows simultaneously.


Now, if you really wish, you can indeed draw both videos on a canvas and pass this canvas to a PiP window, after piping its captureStream() to a third <video>, though this require that both videos are served with the proper Access-Control-Allow-Origin headers, and moreover, it requires your browser to actually support the PiP API (current Firefox has a PiP feature which is not the PiP API).

Here is a proof of concept:

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>

And beware, since I did mute the videos fo SO, scrolling in a way the original videos are out of sight will pause them.

Answered by Kaiido on December 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP