You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为画中画(Picture-in-Picture)窗口添加自定义控制项?

实现带会议控制按钮的画中画功能方案

核心思路

浏览器原生画中画(PiP)API仅支持视频流展示,要添加自定义控制按钮,推荐使用documentPictureInPicture API(允许将任意DOM元素放入画中画窗口),旧浏览器可降级到原生视频PiP结合媒体会话API实现基础控制。

具体实现步骤

1. 自定义画中画(推荐方案)

步骤1:检查浏览器兼容性

if ('documentPictureInPicture' in window) {
  // 支持自定义画中画逻辑
} else {
  // 降级处理或提示用户升级浏览器
}

步骤2:构建带控制按钮的DOM容器

提前在页面中准备包含视频和控制栏的结构:

<div id="pip-container" style="display:none; flex-direction:column; width:300px; background:#000;">
  <video id="meeting-video" autoplay playsinline style="width:100%;"></video>
  <div id="controls-bar" style="display:flex; justify-content:space-around; padding:8px; background:#1a1a1a;">
    <button id="hangup-btn" style="padding:8px 16px; border:none; border-radius:4px; background:#ff4444; color:white;">挂断</button>
    <button id="mic-btn" style="padding:8px 16px; border:none; border-radius:4px; background:#333; color:white;">静音</button>
    <button id="video-btn" style="padding:8px 16px; border:none; border-radius:4px; background:#333; color:white;">关闭视频</button>
  </div>
</div>

步骤3:打开自定义画中画窗口

async function openCustomPiP() {
  const pipContainer = document.getElementById('pip-container');
  pipContainer.style.display = 'flex';
  
  // 请求打开画中画窗口
  const pipWindow = await documentPictureInPicture.requestWindow({
    width: 300,
    height: 360,
  });
  
  // 将容器移入画中画窗口
  pipWindow.document.body.appendChild(pipContainer);
  
  // 绑定控制按钮事件
  bindControls(pipWindow);
}

// 绑定控制逻辑
function bindControls(pipWindow) {
  const hangupBtn = pipWindow.document.getElementById('hangup-btn');
  const micBtn = pipWindow.document.getElementById('mic-btn');
  const videoBtn = pipWindow.document.getElementById('video-btn');
  
  // 挂断按钮逻辑
  hangupBtn.addEventListener('click', () => {
    documentPictureInPicture.exit();
    // 补充你的会议终止、媒体流关闭逻辑
  });
  
  // 麦克风静音切换
  micBtn.addEventListener('click', () => {
    const isMuted = toggleMic(); // 替换为你的麦克风控制函数
    micBtn.textContent = isMuted ? '取消静音' : '静音';
    micBtn.style.background = isMuted ? '#2ecc71' : '#333';
  });
  
  // 视频开关切换
  videoBtn.addEventListener('click', () => {
    const isVideoOff = toggleVideo(); // 替换为你的视频控制函数
    videoBtn.textContent = isVideoOff ? '开启视频' : '关闭视频';
    videoBtn.style.background = isVideoOff ? '#2ecc71' : '#333';
  });
}

步骤4:处理画中画退出事件

documentPictureInPicture.addEventListener('exit', () => {
  const pipContainer = document.getElementById('pip-container');
  document.body.appendChild(pipContainer);
  pipContainer.style.display = 'none';
});

2. 原生视频PiP降级方案

针对不支持自定义画中画的浏览器,用原生视频PiP结合媒体会话API添加系统级控制:

const video = document.getElementById('meeting-video');

async function openVideoPiP() {
  await video.requestPictureInPicture();
  
  if ('mediaSession' in navigator) {
    // 绑定挂断控制
    navigator.mediaSession.setActionHandler('hangup', () => {
      document.exitPictureInPicture();
      // 补充会议终止逻辑
    });
    
    // 绑定麦克风切换
    navigator.mediaSession.setActionHandler('togglemicrophone', () => {
      const isMuted = toggleMic();
      navigator.mediaSession.setMicrophoneActive(!isMuted);
    });
    
    // 绑定视频切换
    navigator.mediaSession.setActionHandler('togglecamera', () => {
      const isVideoOff = toggleVideo();
      navigator.mediaSession.setCameraActive(!isVideoOff);
    });
  }
}

注:原生视频PiP的控制按钮为系统样式,无法自定义,仅能绑定功能逻辑。

关键注意事项

  • 画中画请求必须通过用户主动交互触发(如按钮点击),浏览器禁止自动调用。
  • 麦克风/视频控制需结合getUserMedia API获取媒体流,通过track.enabled属性切换状态。
  • 需在HTTPS环境下测试,浏览器对PiP API有安全限制。

内容的提问来源于stack exchange,提问作者Andrei Kazmirovich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:55:21