原生画中画API:让视频飞出浏览器窗口

更新日期: 2026-05-03 阅读: 16 标签: API

视频明明在网页里放着,用户一切到别的标签页,内容就“失踪”了。这种体验我一直不太接受。尤其是后台盯监控、边查文档边看直播、边记笔记边听课程这类场景,明明浏览器已经有现成能力,很多前端页面还在自己搓悬浮窗,越做越重。

其实画中画这事,前端真没多复杂。原生API就够用,几行JS,视频就能从网页里“飞”出去。


最小可用版本

const video = document.querySelector('#player');
const pipBtn = document.querySelector('#pipBtn');

pipBtn.addEventListener('click', async () => {
  try {
    if (document.pictureInPictureElement) {
      await document.exitPictureInPicture();
      return;
    }

    if (document.pictureInPictureEnabled && video.readyState > 0) {
      await video.requestPictureInPicture();
    }
  } catch (err) {
    console.error('进入画中画失败:', err.message);
  }
});

核心就两个方法:

  • video.requestPictureInPicture()

  • document.exitPictureInPicture()

就这两个,别一上来整一堆状态机。很多页面把简单功能写复杂,问题不在API,在自己先把自己吓住了。


几个容易踩的坑

1. 必须是video元素

你拿一个普通div或者canvas直接调,肯定不行。这个能力本质上还是围着媒体元素转的。很多人页面上看着像播放器,实际外面套了三层壳,真要进画中画,还是得拿到里面那个<video>。

HTML大概像这样:

<video
  id="player"
  src="/assets/demo.mp4"
  controls
  playsinline
  preload="metadata"
  style="width: 640px"
></video>

<button id="pipBtn">打开小窗</button>

2. 用户手势触发

这点很关键。你在接口回调里、定时器里、自动播放逻辑里直接调用,大概率会被浏览器拦下来。这个能力通常要求由用户主动点击触发。所以我一般不在自动逻辑里搞,老老实实给个按钮,最省事。

3. 状态要跟着事件走

video.addEventListener('enterpictureinpicture', () => {
  console.log('已经进入画中画');
  pipBtn.textContent = '关闭小窗';
});

video.addEventListener('leavepictureinpicture', () => {
  console.log('已经退出画中画');
  pipBtn.textContent = '打开小窗';
});

这里我一般会直接监听事件,不太喜欢自己维护一份“是否画中画”的前端状态。浏览器都告诉你进没进了,还自己存个布尔值,后面切标签、切视频源、用户手动关窗口,状态一漂就开始对不上。


多视频场景的处理

真实业务里经常不是单视频页面,而是列表页。比如课程列表、会议回放、监控大盘,同时能看到多个视频卡片。这个时候你不能让每个按钮都各管各的,不然一会儿这个进,一会儿那个抢,页面就乱了。

我一般会这么处理:

async function togglePip(videoEl) {
  try {
    const current = document.pictureInPictureElement;

    if (current && current !== videoEl) {
      await document.exitPictureInPicture();
    }

    if (document.pictureInPictureElement === videoEl) {
      await document.exitPictureInPicture();
    } else {
      await videoEl.requestPictureInPicture();
    }
  } catch (e) {
    console.error('切换画中画失败:', e);
  }
}

这个处理不花哨,但够稳。先把现场清干净,再让当前视频进去。很多bug不是API本身有坑,是页面上同时存在多个播放器,开发时默认“用户只会点一个”,上线后用户偏不。


切换视频源时的处理

还有一个点经常被忽略:切源时要退画中画。比如用户正在小窗播放A视频,这时候列表里点了B视频,你如果直接改src,不同浏览器表现可能不一样,轻则黑屏,重则按钮状态错乱。保险写法是先退,再切,再按需重进。

async function switchVideo(video, nextSrc) {
  if (document.pictureInPictureElement) {
    await document.exitPictureInPicture();
  }

  video.src = nextSrc;
  await video.play();
}


适合画中画的场景

画中画这个能力很适合几类页面:

  • 在线教育

  • 直播回放

  • 视频客服

  • 监控预览

  • 边看边操作的后台系统

它不是炫技功能,是能改善停留时长和操作连续性的。用户不用来回切标签,视频内容也不会因为页面失焦直接废掉。

最后补一句,不要自己上来就做draggable悬浮播放器。能用浏览器原生能力解决的事,先别给自己加维护成本。原生画中画已经帮你处理了窗口层级、拖动、置顶这些问题,前端只需要把入口和状态处理好。

这功能真不算大活。一个按钮,一段事件绑定,网页里的视频就能飞出浏览器。写完你再回头看,会发现之前很多播放器需求,其实压根没必要做那么重。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13746

相关推荐

适合写api接口文档的管理工具有哪些?

现在越来越流行前后端分离开发,使用ajax交互。所以api接口文档就变的十分有意义了,目前市场有哪些比较优秀的接口文档管理工具呢?比如:MinDoc,eoLinker,apizza,RAML,Swagger等等

前后端分离,如何防止api接口被恶意调用或攻击

无论网站,还是App目前基本都是基于api接口模式的开发,那么api的安全就尤为重要了。目前攻击最常见的就是“短信轰炸机”,由于短信接口验证是App,网站检验用户手机号最真实的途径,使用短信验证码在提供便利的同时,也成了呗恶意攻击的对象,那么如何才能防止被恶意调用呢?

超赞的腾讯短网址(微信url.cn短链接)生成api接口

腾讯短网址的应用场景很广,譬如短信营销、邮件推广、微信营销、QQ营销、自媒体推广、渠道推广等,都会用到短网址。究其原因是在于短网址可以降低推广成本、用户记忆成本,提高用户点击率;在特定的场景下推广还能规避关键词,防止域名被拦截

JSON API免费接口_ 免费的天气预报、地图、IP、手机信息查询、翻译、新闻等api接口

整理提供最新的各种免费JSON接口,其中有部分需要用JSONP调用。方面前端同学的学习或在网站中的使用,包括:免费的天气预报、地图、IP、手机信息查询、翻译、新闻等api接口

ACE Editor在线代码编辑器的API使用文档

ACE 是一个开源的、独立的、基于浏览器的代码编辑器,可以嵌入到任何web页面或JavaScript应用程序中。ACE支持超过60种语言语法高亮,并能够处理代码多达400万行的大型文档

浏览器中的图像识别 API

在 Native 开发中,Android 和 IOS 平台都在系统层面直接提供给了应用开发识别图像的一些能力,比如对于二维码/条形码的识别,Android 可以使用 barcode API 、 iOS 可以使用 CIQRCodeFeature API 。

Vue 3.0 体验 Vue Function API

近 Vue 官方公布了 Vue 3.0 最重要的RFC:Function-based component API,并发布了兼容 Vue 2.0 版本的 plugin:vue-function-api,可用于提前体验 Vue 3.0 版本的 Function-based component API

vue-next 函数式 api

在分享 vue-next 各个子模块的实现之前,我觉的有必要比较全面的整理下 vue-next 中提出的函数式 api,了解这些的话,无论是对于源码的阅读,还是当正式版发布时开始学习,应该都会有起到一定的辅助作用

在原生 React Native 应用中使用 Expo API

你可以在任何 React Native 应用程序中使用尽可能少或尽可能多的 Expo SDK。 我们已经花了很多时间构建和维护这些包含原生应用特性的跨平台 API,我们很高兴最终实现了向整个 React Native 生态共享这些 API

构建API的最佳编程语言是什么?

你是否正在设计第一个Web应用程序?也许你过去已经建立了一些,但是目前也正在寻找语言的变化以提高你的技能,或尝试新的东西。有了所有信息,就很难决定为下一个产品或项目选择哪种编程语言。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!