在 Web 上实现画中画功能 画中画演示 🎉

2025-06-04

在网络上实现画中画

画中画演示🎉

我在网络上最喜欢做的事情之一就是实现和测试即将推出的新功能。今天我们要实现画中画功能。

什么是画中画?

根据W3C 画中画规范 -

该规范旨在提供 API,允许网站始终在其他窗口之上创建浮动视频窗口,以便用户在与其他内容网站或设备上的应用程序交互时可以继续消费媒体。

在画中画 (PiP) 模式下,视频会显示在单独的迷你窗口中,该窗口始终位于其他窗口之上。即使用户代理不可见,此窗口也保持可见。


如何实现画中画?

HTML -

<video id="videoElement" controls="true" src="demo.mp4"></video>

<!-- button will be used to toggle the PiP mode -->
<button id="togglePipButton">Toggle Picture-in-Picture Mode!</button> 
Enter fullscreen mode Exit fullscreen mode

JavaScript -

1.requestPictureInPicture()点击togglePipButton按钮元素时调用。

requestPictureInPicture()返回一个 Promise。
当 Promise 解析后,浏览器会将视频缩小到一个迷你窗口中,用户可以移动该窗口并将其放置在其他窗口上。

let video = document.getElementById('videoElement');
let togglePipButton = document.getElementById('togglePipButton');

togglePipButton.addEventListener('click', async function (event) {
    togglePipButton.disabled = true; //disable toggle button while the event occurs
    try {
        // If there is no element in Picture-in-Picture yet, request for it
        if (video !== document.pictureInPictureElement) {
            await video.requestPictureInPicture();
        }
        // If Picture-in-Picture already exists, exit the mode
        else {
            await document.exitPictureInPicture();
        }

    } catch (error) {
        console.log(`Oh Horror! ${error}`);
    } finally {
        togglePipButton.disabled = false; //enable toggle button after the event
    }
});
Enter fullscreen mode Exit fullscreen mode

2. 检查画中画事件的变化

let video = document.getElementById('videoElement');
video.addEventListener('enterpictureinpicture', function (event) {
    console.log('Entered PiP');
    pipWindow = event.pictureInPictureWindow;
    console.log(`Window size -  \n Width: ${pipWindow.width} \n Height: ${pipWindow.height}`); // get the width and height of PiP window
});

video.addEventListener('leavepictureinpicture', function (event) {
    console.log('Left PiP');
    togglePipButton.disabled = false;
});
Enter fullscreen mode Exit fullscreen mode

我们甚至可以通过添加事件处理程序来根据画中画窗口大小的变化更新视频大小resize。这将有助于根据用户正在观看的窗口提供合适的视频质量。

3. 始终检查功能支持情况

if ('pictureInPictureEnabled' in document) {
    showPipButton();

    // loadedmetadata event occurs when meta data for the specified audio/video has been loaded.Meta data might consists of: duration, dimensions etc.
    video.addEventListener('loadedmetadata', showPipButton);

    // emptied event is fired when the media has become empty, e.g. media has already been loaded or partially loaded.
    video.addEventListener('emptied', showPipButton);
} else {
    console.log('The Picture-in-Picture Web API is not available.');
    togglePipButton.hidden = true;
}

// Enable/disable toggle button depending on whether PiP availability.
function showPipButton() {
    togglePipButton.disabled = (video.readyState === 0) || !document.pictureInPictureEnabled || video.disablePictureInPicture;
}
// video.readyState === 0 means Video metadata have not been loaded yet 
// !document.pictureInPictureEnabled means if Pip is not available
// video.disablePictureInPicture means disablePictureInPicture attribute is present in the video which will result in requestPictureInPicture() rejected promise.
Enter fullscreen mode Exit fullscreen mode

就这样!你的 Web 应用现在可以使用画中画功能了!


福利!做了个快速演示,快来看看吧!

GitHub 徽标 ananyaneogi /画中画演示

上传任何视频并以画中画模式播放

画中画演示🎉

从您的计算机添加任何视频并以画中画模式播放视频!

立即查看演示!






目前,该 API 仅支持,HTMLVideoElement但未来将进行扩展。
请查看caniuse 统计信息了解浏览器支持情况。由于这是一项渐进式增强功能,因此无论浏览器是否支持,您都可以在现有应用上使用它!太棒了!


参考

  1. W3C 画中画规范
  2. 构建现代 Web 媒体体验(2018 Chrome 开发者峰会)
文章来源:https://dev.to/ananyaneogi/implement-picture-in-picture-on-the-web-17g8
PREV
给开发团队领导的建议
NEXT
改造你的图标游戏:2023 年最佳开源图标库 🚀