chromium/chrome/test/data/media/picture-in-picture/window-size.html

<!DOCTYPE html>
<html>
<head>
  <title>Picture-in-Picture Window Size Test</title>
</head>
<body>
  <video controls preload=auto src='../bigbuck.webm'></video>
</body>
<script>
  const video = document.querySelector('video');

  // This video is created here in order to be used in
  // `secondPictureInPicture()`. Unfortunately, the `requestPictureInPicture()`
  // method has to be called during a user activation event handler so it's not
  // possible to load the video on-demand.
  const secondVideo = document.createElement('video');
  secondVideo.src = '../bigbuck.webm';
  secondVideo.load();

  async function requestPictureInPictureAndDisable() {
    const promise = video.requestPictureInPicture();
    video.disablePictureInPicture = true;
    try {
      await promise;
    } catch(e) {
      return "rejected";
    }
    return true;
  }

  async function enterPictureInPicture() {
    await _waitForMetadata();
    const pip_window = await video.requestPictureInPicture();

    // If the video size were 0,0 then this might not be true, but it isn't.
    if (pip_window.width == 0 || pip_window.height == 0)
      throw '0 is not a good initial size for a PiP window';

    pip_window.addEventListener('resize', () => {
      // Do not accept zero, and fail the test if so.
      if (pip_window.width == 0 || pip_window.height == 0)
        throw '0 is not a good updated size for a PiP window';
      document.title = 'resized'
    }, { once: true });

    video.addEventListener('leavepictureinpicture', () => {
      document.title = 'leavepictureinpicture';
    }, { once: true });

    return true;
  }

  function _waitForMetadata() {
    return new Promise(resolve => {
      if (video.readyState >= HTMLMediaElement.HAVE_METADATA) {
        resolve();
        return;
      }

      video.addEventListener('loadedmetadata', () => {
        resolve();
      }, { once: true });
    });
  }

  function exitPictureInPicture() {
    document.exitPictureInPicture();
  }

  function isInPictureInPicture() {
    return document.pictureInPictureElement == video;
  }

  function isPaused() {
    return video.paused;
  }

  function secondPictureInPicture() {
    secondVideo.requestPictureInPicture();
  }

  async function ensureVideoIsPlaying() {
    await video.play();
    return true;
  }

  async function changeVideoSrc() {
    if (video.srcObject) {
      video.srcObject.getTracks().forEach(track => track.stop());
      video.srcObject = null;
    }
    video.src = '../bigbuck.webm';
    await video.play();
    return true;
  }

  async function changeVideoSrcToMediaStream() {
    const canvas = document.createElement('canvas');
    canvas.getContext('2d').fillRect(0, 0, canvas.width, canvas.height);
    video.srcObject = canvas.captureStream();
    await video.play();
    return true;
  }

  async function changeVideoSrcToNoAudioTrackVideo() {
    video.src = '../engagement/engagement_no_audio_track.webm';
    await video.play();
    return true;
  }

  function addVisibilityChangeEventListener() {
    document.addEventListener('visibilitychange', () => {
      document.title = document.visibilityState;
    });
  }

  function addPauseEventListener() {
    video.addEventListener('pause', () => {
      document.title = 'pause';
    });
  }

  function addPlayEventListener() {
    video.addEventListener('play', () => {
      document.title = 'play';
    });
  }

  function setMediaSessionActionHandler(name) {
    navigator.mediaSession.setActionHandler(name, _ => {
      document.title = name;
    });
  }

  function unsetMediaSessionActionHandler(name) {
    navigator.mediaSession.setActionHandler(name, null);
  }

  function addPictureInPictureEventListeners() {
    video.addEventListener('enterpictureinpicture', () => {
      document.title = 'enterpictureinpicture';
    });
    video.addEventListener('leavepictureinpicture', () => {
      document.title = 'leavepictureinpicture';
    });
  }

  function tryToEnterPictureInPictureAfterLeaving() {
    video.addEventListener('leavepictureinpicture', () => {
      video.requestPictureInPicture()
      .then(_ => { document.title = 'entered Picture-in-Picture after leaving'; })
      .catch(e => { document.title = 'failed to enter Picture-in-Picture after leaving'; });
    });
  }
</script>
</html>