You can toggle picture in picture mode on any video element using the new webkitSetPresentationMode
method on the video element.
This is currently supported in Mac OSX Catalina, and is soon coming to Mobile Safari with the release of iOS 14.
PiP Demo
Here’s a working version which sniffs for support via webkitSupportsPresentationMode
and toggles picture in picture mode.
If the button is grayed out, your browser does not support
webkitSetPresentationMode
Picture in Picture Code sample with React Hooks
Here is an example of loading a video, and attaching the relative events to a PiP button.
import React, { useEffect, useState, useRef } from "react";
const PIPDemo = () => {
const video = useRef(null);
const [pip, enablePip] = useState(false);
const MODE_PIP = "picture-in-picture";
const MODE_INLINE = "inline";
useEffect(() => {
// detect out if the browser supports PresentationMode
const supportsPiP = (videoEl) => {
return (
videoEl &&
videoEl.webkitSupportsPresentationMode &&
typeof videoEl.webkitSetPresentationMode === "function"
);
};
// set pip state
enablePip(supportsPiP(video.current));
}, [video]);
const togglePiP = () => {
const { current: v } = video;
if (!pip) return;
// switch between the 2 modes
v.webkitSetPresentationMode(
v.webkitPresentationMode === MODE_PIP ? MODE_INLINE : MODE_PIP,
);
};
return (
<div>
<video
ref={video}
id="video"
src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
controls
/>
<div id="controls">
<button type="button" onClick={() => video.current.play()}>
Play
</button>
<button type="button" onClick={() => video.current.pause()}>
Pause
</button>
<button type="button" onClick={() => togglePiP()} disabled={!pip}>
Picture in Picture
</button>
</div>
</div>
);
};