首页/新闻资讯/正文详情

videojs v10 源代码系列解读:26 · presentation 子系统:全屏/PiP/远程播放/方向锁

发布时间:2026/9/26 3:42:50 来源:云帆数科 栏目:资讯中心
videojs v10 源代码系列解读:26 · presentation 子系统:全屏/PiP/远程播放/方向锁
卷四收官篇。presentation 子系统core/src/dom/presentation/处理「播放器的呈现形态」——全屏、画中画、远程播放、屏幕方向锁。这是浏览器兼容的重灾区iOS Safari 的 webkit 前缀、Safari PWA 的 PiP 陷阱、方向锁的异步竞态。这篇看 v10 怎么把这些坑一个个填平。架构纯函数库 feature 装配先说一个我读源码时的发现presentation/下的文件fullscreen.ts、pip.ts等是纯函数库没有任何事件监听。事件监听在 store feature 层store/features/fullscreen.ts等。这个分离很清晰presentation/*.ts——无状态的浏览器兼容封装「怎么请求全屏」「怎么判断在不在全屏」。store/features/*.ts——feature 装配「什么时候同步状态到 store」「绑什么事件」。另外presentation/index.ts3 行只导出 fullscreen/pip/remote-playback——orientation 不在桶文件里仅由 orientation-lock feature 直接路径导入因为它不是「能力」而是「配置型 feature」。fullscreen三级降级 四层判定请求全屏的三级降级presentation/fullscreen.ts:54-79// L57-66container 存在且 document 支持全屏el.requestFullscreen()// L60-62 — 标准el.webkitRequestFullscreen()// L64-66 — webkit 前缀// L69-72都不行 →video.webkitSetPresentationMode(fullscreen)// iOS presentationMode 兜底// L75-78最后 →video.requestFullscreen()// 媒体自定义如 Cast 场景的 host 提供标准 → webkit 前缀 → iOS presentationMode → 媒体自定义。四级路径覆盖所有浏览器。退出全屏的顺序刻意相反exitFullscreenL81-102webkit 的 presentationMode 先退L84-88再标准doc.exitFullscreen()L90-92。为什么因为 iOS 的 presentation mode 是独立状态得先解除它标准 API 才能生效。判断「在不在全屏」的四层判定isFullscreenL29-52// 1. L30-33 — iOS presentationModevideo.webkitPresentationModefullscreen// 2. L35-38 — 标准/webkit 的 fullscreenElement 比对fullscreenElementcontainer||fullscreenElementmedia// 3. L44-46 — :fullscreen 伪类matchesFullscreen 内部 try/catchL20-27container.matches(:fullscreen)||media.matches(:fullscreen)// 4. L50-51 — 非标准 video.isFullscreen由 video host 设置第 3 层的注释L40-43解释了为什么需要它:fullscreen伪类匹配全屏元素及其祖先跨 shadow boundary——覆盖「内层video通过原生控件进全屏」的情况此时 fullscreenElement 是内层元素但 container 是它的祖先。第 4 层的video.isFullscreen是非标准属性——由 media host15 篇设置覆盖 Cast 这种「概念上的全屏」接收端全屏本地 document 无感知。能力探测的动态探针isFullscreenEnabledL5-13doc.fullscreenEnabled || doc.webkitFullscreenEnabled都假时动态创建一个video探针L11检测isFunction(video.webkitSetPresentationMode)L12——iOS Safari 的旧路径。这和 21 篇 volume 的canSetVolume是同一套「运行时探针」手法。feature 装配store/features/fullscreen.ts:44-66attach({target,signal,set}){set({fullscreenAvailability:isFullscreenEnabled()?available:unsupported});// L47-49constsync()set({fullscreen:isFullscreen(container,media)});// L51-54sync();// L56listen(document,fullscreenchange,sync,{signal});// L58listen(document,webkitfullscreenchange,sync,{signal});// L59if(webkitPresentationModeinvideo){// L62-65 — iOS 补充listen(media,webkitpresentationmodechanged,sync,{signal});}}同时绑标准和非标准事件iOS 再补一个。还有一个贴心细节L16-19requestFullscreen先退 PiP——注释写着 “browser behavior is inconsistent”有些浏览器全屏时会打断 PiP主动退更可控。pipSafari PWA 陷阱presentation/pip.ts的请求/退出逻辑和 fullscreen 对称webkit 优先/回退最有意思的是能力探测L5-14exportfunctionisPictureInPictureEnabled():boolean{if(document.pictureInPictureEnabled){// Safari PWA 排除UA 匹配 Safari 且 display-mode: standalone 时禁用if(/.*Version\/.*Safari\/.*/.test(navigator.userAgent)matchMedia((display-mode: standalone)).matches){returnfalse;// L7-9}returntrue;}// webkit 探针回退 L12-13}Safari 的 PWAstandalone 模式里 PiP 会崩——pictureInPictureEnabled说支持实际用就炸。v10 用 UA display-mode: standalone双重判定提前排除。这种坑不可能从规范推出来只能是实踩后写进代码的。feature 装配store/features/pip.ts:49-71监听enterpictureinpicture/leavepictureinpictureL63-64 iOS 的webkitpresentationmodechangedL67-70。togglePictureInPicture同样先退 fullscreenL34-46——PiP 和全屏互斥。remote-playback鸭子类型 浏览器 UIpresentation/remote-playback.ts27 行最短// L4-10 — 鸭子类型检测exportfunctionresolveRemote(media){if(isObject(media.remote)stateinmedia.remotepromptinmedia.remote){returnmedia.remote;// cast 成 MediaRemotePlaybackCapability[remote]}returnnull;}// L20-26 — 请求远程播放exportfunctionrequestRemotePlayback(media){constremoteresolveRemote(media);if(!remote)thrownewDOMException(Remote playback not supported,NotSupportedError);// L23remote.prompt();// L25 — AirPlay/Cast 的设备选择 UI 由浏览器弹出}注意 L25——remote.prompt()触发的是浏览器原生的设备选择 UIAirPlay/Cast 菜单。v10 不自己画设备列表。17 篇讲的GoogleCast组件提供了RemotePlayback的规范实现google-cast/remote-playback.ts这里消费的正是那个接口。orientation异步竞态的优雅解法presentation/orientation.ts77 行是我觉得这份源码里「小而美」的典范。问题screen.orientation.lock()是async的——await 期间用户可能已经调了unlock()。怎么防止「迟到的 lock 覆盖已生效的 unlock」解法是两个标志分离「事实」和「意图」L30-31letlockedfalse;// 事实lock 真正成功letdesiredfalse;// 意图调用方想要锁lock()的完整流程L45-65asynclock(){desiredtrue;// 先记意图// ... lock 非函数直接 returnL52不支持时静默try{awaitorientation.lock(type);// L55 — 异步等真正锁上if(desired)lockedtrue;// L58 — await 期间意图还在才置事实elsereleaseOrientation();// L60-64 — 意图已变立刻释放}catch{/* L56-58 */}}unlock(){desiredfalse;// L67 — 只改意图if(locked){releaseOrientation();lockedfalse;}// L68-70}L58 的if (desired)是竞态的裁决点await 回来时如果desired已经是 falseunlock 抢先了立刻调releaseOrientation()反向补偿——迟到的 lock 被立即撤销。这个「意图标志 完成后校验」的模式比 Promise 链或状态机都轻。orientation-lock featureconfigurable 实战store/features/orientation-lock.ts53 行是 19 篇讲的configurable feature的内置使用者// L16-52 — 可配置 feature默认 { type: landscape }L51orientationLockFeature({type:portrait})// 这样定制它的 attachL21-49做边沿检测wasFullscreen标志L25、L35记住上一次全屏态进入全屏lock()L29-30、退出unlock()L31-32——方向锁跟随全屏状态自动开关全屏看视频锁横屏退出解锁。同样监听三种 fullscreenchangeL40-46abort 兜底 unlockL48。小结presentation 子系统是「浏览器兼容教科书」带走这些手法纯函数库 feature 装配分离——兼容封装无状态监听在 feature。多级降级链——fullscreen 四级请求路径退出顺序刻意相反。四层全屏判定——presentationMode/fullscreenElement/:fullscreen伪类/非标准属性覆盖 shadow DOM 和 Cast。运行时探针——动态video探测 iOS 能力和 volume 的 canSetVolume 同款。Safari PWA 陷阱——UA display-mode 双判。意图/事实双标志解异步竞态——orientation 的 desired/locked。互斥主动处理——全屏先退 PiP、PiP 先退全屏“browser behavior is inconsistent”。至此卷四讲完。播放器核心的全貌feature 组装19-21、无头 Core22-23、选择器24、输入桥25、presentation26。下一篇进入卷五——SPF 流处理框架全系列的重头戏15 篇。

相关推荐

呼和浩特膜内贴中式塑料桶定制 5L-50L规格全 食品级材质厂家直供
呼和浩特膜内贴中式塑料桶定制 5L-50L规格全 食品级材质厂家直供

膜内贴中式塑料桶是目前工业包装领域应用范围较广的一种中小规格包装容器,主要采用PP(聚丙烯)材质通过注塑工艺一体成型,中式结构的桶身带有加强筋设计,方便堆叠存放,搭配膜内贴印刷工艺可以实现标签与桶壁的融合,美观… · 2026/9/26 3:42:50

Claude Code v2.1.196 组织级默认模型配置指南:用 TaoToken 统一 Key 打通代码评审链路,Token 消耗直降 25%
Claude Code v2.1.196 组织级默认模型配置指南:用 TaoToken 统一 Key 打通代码评审链路,Token 消耗直降 25%

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 3:42:44

OpenClaw教程(五)—— 为AI助手添加翅膀(网络能力):Brave Search 与浏览器配置实战
OpenClaw教程(五)—— 为AI助手添加翅膀(网络能力):Brave Search 与浏览器配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 3:42:44

江苏羊预混料源头厂家实力推荐 尔饲料用户力荐
江苏羊预混料源头厂家实力推荐 尔饲料用户力荐

尔公司是国内专注反刍动物营养的饲料企业,多年来深耕肉羊养殖细分领域,为全国羊养殖主体提供羊饲料、羊预混料等产品及定制化营养方案,业务覆盖肉羊全生长周期的饲养需求。作为国内较早布局反刍动物饲料的企业,尔至今已有二十余年… · 2026/9/26 6:58:36

战略规划部经理绩效考核方案与战略执行力提升路径
战略规划部经理绩效考核方案与战略执行力提升路径

在现代企业中,绩效考核作为员工管理的重要手段,直接影响着员工的工作积极性与团队的整体表现。特别是在战略规划部经理的考核中,如何全面、客观地评估其工作绩效、能力和态度,是保证考核结果公正且有效的关键。为了实现这一目标,绩效考核方案通过系统化的评估体系,结合自… · 2026/9/26 6:58:36

具身智能异构算力实战:英特尔全栈方案与部署优化
具身智能异构算力实战:英特尔全栈方案与部署优化

1. 从数字世界跨入物理世界:具身智能到底在解决什么问题数字AI和物理AI之间隔着的,不是一层软件,而是一整个物理世界的复杂性。你让一个大语言模型写首诗、做个表格、生成一段代码,它可以在纯数字空间里完成闭环,输入是… · 2026/9/26 6:58:36

企业管理部经理绩效考核方案与管理效能优化路径解析
企业管理部经理绩效考核方案与管理效能优化路径解析

在企业管理中,绩效评估对于员工的职业发展以及公司整体运营的优化至关重要。特别是对于企业管理部经理而言,他们不仅是部门目标达成的关键,更是跨部门协作、资源调配以及战略执行的重要执行者。 为了确保这些经理的工作成效能够得到科学、准确的评估,本方案设计了一个全面… · 2026/9/26 6:58:36

杭州高净值家族高端出行管家服务机构哪家服务好?惟舍之旅一站式私享出行方案
杭州高净值家族高端出行管家服务机构哪家服务好?惟舍之旅一站式私享出行方案

随着国内经济发展和高净值家族资产规模的持续增长,高净值群体的全球出行需求正在发生本质变化。过去家族出行多依赖传统旅行社的标准化套餐,或是单独对接公务机包机服务商,需求只停留在完成出行的基础层面;而现在,越来越多顶层实业… · 2026/9/26 6:58:36

吃透Power BI:从数据建模到网关部署的系统级实践
吃透Power BI:从数据建模到网关部署的系统级实践

1. 为什么“吃透Power BI”不是学完菜单栏就算数“从0到1,带你吃透Power BI”——这句话里最值得拆开揉碎的,其实是“吃透”两个字。不是“会用”,不是“能做报表”,更不是“点开软件导个Excel就完事”。我带过三轮企业内训&#… · 2026/9/26 6:58:30

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码