前端实现视频画中画功能:主窗口与小窗同步控制完整方案
你是否注意到,在观看长视频时,如果切换到其他标签页或最小化浏览器,往往需要重新加载才能继续观看。B 站等平台的画中画功能解决了这个问题,允许视频以小窗形式悬浮在其他内容之上。
随着 Chrome 108+ 对 Document Picture-in-Picture API 的支持,我们不再局限于传统的 <video> 元素画中画,而是可以将整个文档片段移入独立小窗,并保留完整的交互能力(如自定义进度条、按钮)。本文将演示如何构建一个主页面与画中画小窗之间实时同步播放、暂停、音量及进度的完整方案。
为什么要使用 Document PiP API
传统 Picture-in-Picture API 仅支持将 <video> 元素本身移出,无法携带自定义控件。新的 Document Picture-in-Picture API 则允许将整个 DOM 节点放入新窗口,优势在于:
- 完整 HTML 支持:小窗内可包含按钮、进度条等任意交互元素
- 无缝集成:主页面与小窗共享 JavaScript 上下文,便于状态同步
- 尺寸灵活:可自定义小窗宽高,适应不同布局需求
- 双向通信:主窗口与画中画窗口可实时同步播放状态
注意:该功能目前主要在 Chrome 108+ 版本中可用,Firefox 和 Safari 尚未完全支持。
完整代码案例
以下是一个可直接运行的示例。为了演示效果,代码中使用了本地视频资源 1.mp4,实际使用时请替换为有效的视频地址。
CSS 样式
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: auto;
: (, , , );
: ;
: (, , , );
: hidden;
}
{
: (to right, , );
: white;
: ;
: center;
}
{
: ;
: ;
: (, , , );
}
{
: ;
: ;
: ;
: auto;
}
{
: flex;
: ;
: ;
}
{
: ;
: ;
: ;
: hidden;
: (, , , );
}
{
: relative;
: ;
: ;
}
{
: absolute;
: ;
: ;
: ;
: ;
: block;
}
{
: flex;
: ;
: ;
: ;
}
{
: ;
: white;
: none;
: ;
: ;
: pointer;
: ;
: all ease;
: flex;
: center;
: ;
}
{
: ;
: (-);
: (, , , );
}
{
: ;
: not-allowed;
: none;
: none;
}
{
: ;
: white;
: ;
: ;
: (, , , );
}
{
: ;
: ;
: ;
: solid ;
}
{
: ;
}
{
: flex;
: flex-start;
: ;
}
{
: ;
: white;
: ;
: ;
: ;
: flex;
: center;
: center;
: ;
: ;
}
{
: fixed;
: ;
: ;
: ;
: ;
: black;
: ;
: hidden;
: (, , , );
: ;
: none;
}
{
: ;
: ;
: cover;
}
{
: absolute;
: ;
: ;
: ;
: flex;
: center;
: ;
: ;
: opacity ;
}
{
: ;
}
{
: ;
: ;
: ;
: ;
: monospace;
}
{
: ;
: ;
: ;
: ;
: solid ;
}
{
: flex;
: ;
: ;
: wrap;
}
{
: flex;
: center;
: ;
}
{
: ;
}
{
: ;
}
(: ) {
{
: column;
}
}



