Audio & Video 进阶 0m
与附近的人共享 visionOS 体验
Share visionOS experiences with nearby people
2025年6月9日
一句话判断
visionOS 26 的 SharePlay 终于支持同一房间的多人协作——窗口栏上一个分享按钮,就能让所有人看到同一个 app 在同一个位置,而且已有 SharePlay 代码零改动就能用。
这场 Session 讲了什么
visionOS 26 引入了 Nearby Window Sharing:每个窗口右侧新增一个分享按钮,点击后选择附近的人,窗口就会以相同位置和大小出现在所有人的空间里。窗口栏变绿表示正在共享。
核心体验:
- 共享窗口在所有人面前出现在同一个物理位置
- 任何人都可以移动窗口,移动对所有人可见
- 手指靠近窗口时内容自动淡出,保证手势可见
- 可以同时和 FaceTime 远程参与者共享(Spatial Persona 自动排列在附近参与者旁边)
已有 SharePlay app 零改动即可支持 nearby sharing。但 session 给了几个增强体验的 API:
- Share Menu 集成:用
ShareLink把 GroupActivity 暴露到新的 Share 菜单。Immersive Space 没有窗口栏,需要自己提供按钮调用activate()。 - 检测附近参与者:
ParticipantState.isNearbyWithLocalParticipant区分附近和远程参与者。 - 参与者 Pose:
ParticipantState.pose告诉你每个人在 ImmersiveSpace 场景里的位置,可以用来在每人旁边放置内容。 - AVPlayer 同步:visionOS 26 的 AVPlayer 精确同步附近参与者的音视频播放,解决回声问题。
- 多窗口关联:
.groupActivityAssociationmodifier 选择哪个 WindowGroup 是 SharePlay 的主窗口。 - Shared World Anchors:ARKit 新增共享锚点,内容锚定到物理空间,仅和附近参与者共享。
值得深挖的点
-
Shared World Anchors 是杀手级特性。之前 SharePlay 的内容是”跟着窗口走”的,现在可以锚定到物理空间。想象多人在同一个房间里协作摆放虚拟家具、在墙上画白板、或者一起看锚定在桌面上的 3D 模型。
-
AVPlayer 同步是附近场景的刚需。因为人就在旁边,设备间微小的音频延迟都会被听到形成回声。visionOS 26 的 AVPlaybackCoordinator 精确处理了这个问题。
-
参与者 Pose 不是实时追踪的。它在分享开始、重新居中等关键事件后更新。不要拿它做需要实时位置的交互。
-
Immersive Space 共享需要设置
supportsGroupImmersiveSpace,否则共享的是窗口而不是沉浸空间。
代码片段
把 GroupActivity 暴露到 Share 菜单:
struct BoardGameView: View {
var body: some View {
VolumetricWindowGroup {
BoardGameScene()
}
// 隐藏的 ShareLink,让 Share 菜单能启动 SharePlay
.shareLink(activity: BoardGameActivity(), isHidden: true)
}
}
检测附近参与者:
for participant in session.activeParticipants {
if participant.isNearbyWithLocalParticipant {
// 这个人和我在同一个房间
assignToSameTeam(participant)
}
}
创建 Shared World Anchor:
// 检查共享锚点是否可用
for await availability in worldTracking.anchorSharingAvailabilityUpdates {
if availability == .available {
break
}
}
// 创建共享锚点
let anchor = WorldAnchor(
originFromAnchorTransform: furnitureTransform,
sharedWithNearbyParticipants: true // 关键参数
)
try await worldTracking.add(anchor)
最佳实践
- 已有 SharePlay 代码先测试一下 nearby sharing 是否直接可用,大概率零改动就行。
- Immersive Space 一定要保留一个非沉浸模式,让用户可以从 Share 菜单启动共享。
- 用 participant pose 在每人旁边放 UI(记分板、工具栏),不要假设所有人都在窗口正前方。
- 共享媒体用 AVPlayer + AVPlaybackCoordinator,不要自己做同步。
- Shared World Anchor 的 identifier 在所有设备上一致,用它做同步标识符。
- 共享锚点在 SharePlay 结束后不持久化,和普通 world anchor 不同。
还有什么值得关注
- “Customize spatial Persona templates in SharePlay” 讲了 seat pose 和自定义座位安排。
- “Coordinate media experiences with Group Activities” 补充了 AVPlaybackCoordinator 的 setup。
- “Create a great spatial playback experience” 是 visionOS 媒体播放的基础。
- “Explore enhancements to your spatial business app” 讲了企业 app 如何用自己的网络层配合 shared world anchors。
- Defenderella by Rock Paper Reality 是 nearby sharing 的游戏 demo。
Audio & Video 空间计算