跳到正文
Hacker News· dardarbinks·· 10 天前AI 评分22

iPhone Duo 对 Web 开发意味着什么(以及 Video.js)

What the iPhone Duo means for web development (and Video.js)

AI 导读

苹果在 iPhone Duo 上通过 feature flag 提供了 Device Posture API 和 Viewport Segments API,前者用 navigator.devicePosture 或 @media (device-posture。

正文 · AI 翻译

2026年10月6日•10分钟阅读

你可能会以为,在Video.js v10.0.0 发布之后,我们的第一篇文章会是关于可组合架构、编译器,或者我们库智能体体验研究的多部分系列深度探讨。

但你知道吗?我们一直在拼命努力让 Video.js 顺利发布。所以,与其写一篇真正的博客文章,我决定把周末花在一个小副业项目上:深入研究我们将在 iPhone Duo 上能够访问的 Web API。

我知道,我知道,这种折叠的东西已经在 Android 上流传多年了。但自从我心爱的 HTC One 十多年前坏掉之后,我一直是 iOS 用户。而现在,Tim John Apple 终于下令,轮到我折叠手机了。

而且我对轮到我很兴奋。不仅是因为再次拥有一部小手机(iPhone mini,我想你 🥺)的喜悦。还因为这对开发者意味着什么。Apple 发布了六个视频,讲述如何为 iPhone Duo 构建出色的应用。这些视频涵盖了告诉你设备物理特性和状态的 API,并且充满了设计灵感,展示了开发者现在可以构建的应用类型和交互方式。

但这是 Apple。他们有没有给我们 Web 开发者留下什么残羹剩饭?

iPhone Duo 有哪些可用的 Web API?

下载 Xcode 27.1 beta1 后,我立刻启动了模拟器设备中心,启动了一台 iPhone Duo,直奔设置,深入研究了功能标志。2

WebKit feature flags in the Settings app on a folded iPhone Duo in the Device Hub

我热爱功能标志。这个列表简直就是 Web 未来的玩具箱;那些也许某天我们能玩到的酷炫功能。我停下来,顺便查了几个。比如,CSS Rhythmic Sizing 到底是什么鬼??

但不行。我得集中注意力。我来这里是为了两件具体的事。滚动了一会儿后,我找到了它们。设备姿态 API 和视口分段 API。

设备姿态 API

设备姿态 API基本上告诉你,你正在看的显示器是 continuous(例如,你的普通屏幕,平的或曲面的,太2018 年了)还是 folded(例如,部分折叠的折叠手机,像笔记本电脑)。这在 JavaScript 中有效——navigator.devicePosture——或在 CSS 中——@media (device-posture: folded)。

视口分段 API

视口分段 API告诉你显示器的各个区域。在 JavaScript 中,window.viewport.segments 会给你一个 DOMRect 数组,告诉你各分段的大小、形状和位置。

在 CSS 中,你可以通过两种方式了解分段。首先,@media (horizontal-viewport-segments: n) 和 @media (vertical-viewport-segments: n) 让你响应(你猜对了)水平和垂直视口分段的数量。其次,你可以使用 CSS 环境变量访问任何分段的位置和大小。想访问右上角分段的宽度?env(viewport-segment-width 1 0) 就能帮你实现。(第一个数字是水平索引,第二个是垂直索引)。

比如说,你有一个全出血的两列布局,当屏幕折叠时,你想让它吸附到各个分段上,这样你的内容就不会进入折痕。你可能会写这样的代码……

这会产生这样的效果

A two-column Settings layout on an unfolded iPhone Duo, with the sidebar taking about a third of the width

The same Settings layout on a partially folded iPhone Duo, with each column snapped to one half of the screen

为折叠手机构建 Web 视频播放器

好吧,这些都挺好,但让我告诉你我们真正来这里的原因。在苹果媒体活动之后,我看到一些人试用了新的 Netflix iPhone Duo 应用,折叠播放器非常合理。视频在上半部分,控件在下半部分,还有一个微妙的效果,将视频反射到下半屏幕上。

A hand holding a partially folded iPhone Duo playing Netflix, with video on the top half and large controls on the bottom half

截图来自 Dave2D 的“iPhone Duo 上手印象——他们做到了”。

在 Video.js 中度过了一年,显然我的第一个想法是“我们能做这个吗?”

简短的回答是“不能”。尽管打开的 Duo 基本上就是一台 iPad,苹果仍然不允许我们的元素全屏。我们只能使用原生控件。

Fullscreen video on a folded iPhone Duo using Safari’s native controls, spread across the bottom half

但这样结束博客文章太无聊了。而且不知为何,Fullscreen API 确实作为一个功能标志可用。所以我进去启用它……然后……

Video.js controls in fullscreen on a folded iPhone Duo, with the video on the top half and the control bar at the bottom of the screen

天哪,那些是 iPhone Duo 上全屏的 Video.js 控件吗??我觉得不需要太多想象力就能猜到接下来会发生什么。

让我们看看我能否用 Video.js 组件和 CSS 重现 Netflix 的 UI。

将控件放在下半屏幕

我首先获取一个带有 shadcn CLI 的 Video.js 皮肤,并为其添加一个全新的部分。3

我还需要一些额外的控件和图标来匹配 Netflix 的 UI,所以我添加了一点更多的 JS:

从这里开始?如果你一直在关注,这个 CSS 应该不会太令人惊讶。我们检查是否处于垂直折叠姿态,然后定位视频和控件。4

瞧!如果你忽略苹果在顶部绘制的自定义全屏控件,你几乎可以假装这是一个原生应用。

Video.js on a folded iPhone Duo with the video on the top half and Netflix-style tiled controls filling the bottom half

在下半屏幕反射视频

既然我们在这里,让我们更进一步。Netflix 视频“反射”到下半屏幕。我们也能做到吗?

首先,我尝试-webkit-box-reflect,它很乐意反射普通 DOM 元素,但不幸的是不能反射<video>。至少在 iOS Safari 上不行。然后,我记得我的一位同事构建了一个Mux Player 版本,模仿了YouTube 的环境模式。

这是它的要点。首先,我们将每一帧复制到一个小画布上:

然后,我们翻转那个画布,模糊它,并淡化它:

就是这样。控件后面有一个柔和的投射。

The same Video.js Duo layout with a blurred, mirrored reflection of the video glowing behind the bottom controls

就在那个重磅消息上……

大约现在,我想起我必须启用三个功能标志才能到达这里。虽然我可以想象苹果启用 Viewport Segments API 和 Device Posture API,但考虑到苹果可能有的 ergonomic 和功耗问题,很难想象 Fullscreen API 会被启用。

当然,尽管粉丝们(说实话包括我)想要假装不是这样,确实有一个完整的优秀 Android 折叠手机生态系统。所以让我们在我手边的一个 Pixel 9 Pro Fold 模拟器上试试……运行 Chromium 157……

Fullscreen video on a folded Pixel 9 Pro Fold emulator, with the video on the top half and the bottom half left black

不行。尽管 CSS 媒体查询报告了正确的姿态和分段,Chromium 只在上半部分显示全屏内容。下半部分被裁剪,故意如此。5

所以。在 iPhone Duo 和 Pixel Fold 上,Netflix UI 仍然只是一个梦想。

哦好吧。我仍然很高兴我们做得相当接近。在这一切结束时?这无论如何变成了一篇 Video.js v10 发布文章。我喜欢我们新的可组合架构让我能够想象一个视频播放器,并直接用一些简单的 HTML/CSS 构建它。相当不错。


脚注

  1. 不是 27.2,那样就太合理了。如果你要管理多个版本的 Xcode,我们团队偏爱 Xcodes 这款应用。↩

  2. 好奇的话,路径是“应用”>“Safari”>“高级”>“功能标志”。没错,这个设置确实存在,只是被奇怪地埋在屏幕底部一个巨大空隙的下方。↩

  3. 我可以重新定位现有的控件,但为了这个演示,在 DOM 里复制这些东西更简单。↩

  4. 完全坦白。并非一切都如我所愿。在定位顶部内容时,bottom: env(viewport-segment-bottom 0 0) 把视频正好放在了接缝上。而在定位控件时,height: env(viewport-segment-height 0 1) 让内容远远超出了屏幕底部。不知道为什么。如果你知道我漏掉了什么,请告诉我!↩

  5. 理论上,这说得通。你只希望 <video> 出现在上半部分,这样它就不会跨越接缝。但在实践中,也许 Chromium 可以像 WebKit 似乎已经做的那样,只重新定位 <video>,同时让整个全屏容器跨越两个部分。也许我该给 Chromium 提个 PR……↩

来源:Hacker News · videojs.org