一、先看结果:一个真实可用的多浮窗视频工具
在 macOS 上,如果你有以下需求:
-
一边工作一边看技术视频
-
同时悬浮多个网页视频进行对照
-
希望视频窗口不影响当前操作、不被遮挡
那么你大概率会遇到这样的问题:
系统画中画只能开一个,网页视频窗口尺寸不可控,多开后性能迅速下降。
基于这些实际痛点,我最终把自己的技术方案打磨成了一款 macOS 工具:
FloatPlay(多浮窗视频播放)
它的核心能力很简单:
-
多个网页视频同时悬浮在桌面之上
-
浮窗大小、比例始终与视频内容匹配
-
支持对视频播放状态、音量进行统一控制
-
多窗口场景下依然保持流畅
-
快速显示/隐藏,极致大小 便于摸鱼
记录一下我用 WebKit 折腾这件事的过程,尤其是一些当时没想明白、后来才踩明白的点。
二、WebKit 方案选择说明
在播放对象为网页视频(如在线课程、Web 播放器)时,直接使用原生播放器方案存在以下问题:
-
视频源协议和 DRM 处理复杂
-
不同平台页面差异较大
-
需要自行维护播放逻辑
使用 WebKit(WKWebView)可以直接复用网页播放器能力,避免重复实现播放逻辑,因此本方案以 WKWebView 作为视频承载组件。
三、浮窗结构实现
每个视频浮窗对应一个独立的 macOS Window:
-
Window 处于
floating层级 -
内部包含一个 WKWebView
-
支持窗口拖动与尺寸调整
Swift
window.level = .floating
window.isMovableByWindowBackground = true
window.level = .floating window.isMovableByWindowBackground = true
窗口本身仅负责展示,视频布局与行为控制主要在 WebView 内完成。
四、通过 JavaScript 控制网页视频布局
在直接加载网页的情况下,存在以下问题:
-
页面包含多余 UI 元素
-
视频区域无法自适应窗口大小
-
调整窗口尺寸后比例异常
为解决上述问题,在页面加载完成后向 WebView 注入 JavaScript,对页面进行处理:
-
查找
video元素 -
强制视频宽高匹配 WebView
-
禁用页面滚动
-
移除页面默认边距
示例逻辑如下:
javascript
const video = document.querySelector('video');
if (video) {
video.style.width = '100%';
video.style.height = '100%';
video.style.objectFit = 'contain';
}
document.body.style.margin = '0';
document.body.style.overflow = 'hidden';
处理后,视频显示区域可稳定匹配浮窗尺寸。
五、播放状态与音量控制方式
在多浮窗场景下,网页默认的音频控制方式不可控,多个视频可能同时发声。
解决方式为统一通过 JavaScript 控制视频音量与播放状态:
javascript
if (video) {
video.volume = 0.3;
video.muted = false;
}
该方式仅影响当前 WebView 内的视频,不会改变系统音量设置。
六、多浮窗场景下的性能问题与优化
在测试多个浮窗同时播放网页视频时,会出现以下现象:
-
页面加载速度下降
-
播放过程中出现卡顿
-
系统资源占用明显增加
排查后发现,多个 WKWebView 使用独立 Web 会话配置时,会重复创建相关 Web 进程和资源。
优化方式为:
-
多个 WKWebView 共用同一套 Web 会话资源
-
减少重复初始化 WebKit 运行环境
(具体实现方式为共享进程池 / 会话配置,名称可能因实现方式不同略有差异)
优化后,多浮窗同时播放的稳定性和资源占用情况均有所改善。
七、实际使用场景说明
基于上述实现方式,该工具主要适用于以下场景:
-
工作过程中悬浮播放技术视频
-
多个网页视频同时对照观看
-
在不切换主窗口的情况下持续观看内容
工具本身不对网页播放逻辑进行重写,仅对显示和控制方式进行约束。
八、总结
该方案基于 WebKit 实现网页视频的多浮窗播放,核心在于:
-
使用 WKWebView 承载网页视频
-
通过 JavaScript 控制页面布局与播放行为
-
在多实例场景下共享 Web 会话以降低性能开销
整体实现适用于需要在 macOS 上进行多任务处理的网页视频场景。