video.requestPictureInPicture() floats a video in a small always-on-top window that survives tab switches; its PictureInPictureWindow reports width and height and fires resize, so you can swap in a better source. Document Picture-in-Picture opens an empty same-origin window you fill with real DOM, so a whole custom player can move out of the page and back. The Remote Playback API adds casting: video.remote prompts for a Chromecast or AirPlay device and reports whether any is reachable.
const video = document.querySelector('#player video');
video.remote.watchAvailability((yes) => { cast.hidden = !yes; console.log('device:', yes); });
cast.onclick = () => video.remote.prompt().catch((e) => console.log('prompt ->', e.name));
pip.onclick = async () => { // all three calls need a user gesture
const w = await video.requestPictureInPicture();
console.log('PiP window', `${w.width}x${w.height}`);
};
popOut.onclick = async () => {
const win = await documentPictureInPicture.requestWindow({ width: 320, height: 200 });
win.document.body.append(player); // move the live element, listeners and all
console.log('doc PiP opened; same origin:', win.opener === window);
};device: false PiP window 284x160 doc PiP opened; same origin: true
Every entry point needs transient activation, so none of it runs unattended; that output is headless Chrome 152 1 driven by scripted trusted clicks, where no cast device exists and the button hides itself. A PiP window starts with no CSS, so clone your <link rel="stylesheet"> elements into win.document.head, and move the player back on pagehide. Video PiP is in Chrome 69+, Safari 13.1 10 + and Firefox 153 555 (July 2026), short of Baseline only because Firefox for Android lacks it; Document PiP is desktop Chrome and Edge 116+ and Firefox 151+; Remote Playback is Chrome and Edge 121+ and Safari 13.1+, neither of them in Firefox.