diff --git a/docs/pages/component/events.mdx b/docs/pages/component/events.mdx
index 47f902042f..f59d35f21e 100644
--- a/docs/pages/component/events.mdx
+++ b/docs/pages/component/events.mdx
@@ -317,7 +317,7 @@ Example:
### `onPictureInPictureStatusChanged`
-
+
Callback function that is called when picture in picture becomes active or inactive.
diff --git a/docs/pages/component/methods.mdx b/docs/pages/component/methods.mdx
index 5c1f39a249..223fbd2f3e 100644
--- a/docs/pages/component/methods.mdx
+++ b/docs/pages/component/methods.mdx
@@ -80,7 +80,7 @@ Future:
### `enterPictureInPicture`
-
+
`enterPictureInPicture()`
@@ -114,7 +114,7 @@ NOTE: Video ads cannot start when you are using the PIP on iOS (more info availa
### `exitPictureInPicture`
-
+
`exitPictureInPicture()`
diff --git a/src/Video.web.tsx b/src/Video.web.tsx
index 920e406521..1dcc6843dd 100644
--- a/src/Video.web.tsx
+++ b/src/Video.web.tsx
@@ -50,6 +50,7 @@ const Video = forwardRef(
onVolumeChange,
onEnd,
onPlaybackStateChanged,
+ onPictureInPictureStatusChanged,
},
ref,
) => {
@@ -180,6 +181,31 @@ const Video = forwardRef(
[setFullScreen],
);
+ const enterPictureInPicture = useCallback(() => {
+ try {
+ if (!nativeRef.current) {
+ console.error('Video Component is not mounted');
+ } else {
+ nativeRef.current.requestPictureInPicture();
+ }
+ } catch (e) {
+ console.error(e);
+ }
+ }, []);
+
+ const exitPictureInPicture = useCallback(() => {
+ if (
+ nativeRef.current &&
+ nativeRef.current === document.pictureInPictureElement
+ ) {
+ try {
+ document.exitPictureInPicture();
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ }, []);
+
useImperativeHandle(
ref,
() => ({
@@ -193,8 +219,8 @@ const Video = forwardRef(
dismissFullscreenPlayer,
setFullScreen,
save: unsupported,
- enterPictureInPicture: unsupported,
- exitPictureInPicture: unsupported,
+ enterPictureInPicture,
+ exitPictureInPicture,
restoreUserInterfaceForPictureInPictureStopCompleted: unsupported,
nativeHtmlVideoRef: nativeRef,
}),
@@ -210,6 +236,8 @@ const Video = forwardRef(
presentFullscreenPlayer,
dismissFullscreenPlayer,
setFullScreen,
+ enterPictureInPicture,
+ exitPictureInPicture,
],
);
@@ -254,6 +282,27 @@ const Video = forwardRef(
nativeRef.current.playbackRate = rate;
}, [rate]);
+ useEffect(() => {
+ if (
+ typeof onPictureInPictureStatusChanged !== 'function' ||
+ !nativeRef.current
+ ) {
+ return;
+ }
+ const onEnterPip = () =>
+ onPictureInPictureStatusChanged({isActive: true});
+ const onLeavePip = () =>
+ onPictureInPictureStatusChanged({isActive: false});
+
+ const video = nativeRef.current;
+ video.addEventListener('enterpictureinpicture', onEnterPip);
+ video.addEventListener('leavepictureinpicture', onLeavePip);
+ return () => {
+ video.removeEventListener('enterpictureinpicture', onEnterPip);
+ video.removeEventListener('leavepictureinpicture', onLeavePip);
+ };
+ }, [onPictureInPictureStatusChanged]);
+
useMediaSession(src?.metadata, nativeRef, showNotificationControls);
return (