Discover generated subtitles and subtitle styles
Accessibility & Inclusion 进阶 11m

探索生成式字幕和字幕样式

Discover generated subtitles and subtitle styles

2026年6月10日

在 Apple 官方观看视频

一句话判断

✅ 视频播放器的脏活累活被 Apple 底层接管了:设备端 AI 字幕生成和实时样式预览现在对标准播放器“零代码”默认生效。

这场 Session 讲了什么

这场 Session 最值得关注的一件事,就是 Apple 把原本需要开发者手写几百行代码的“AI 字幕生成”和“字幕样式实时预览”,直接塞进了 AVFoundation 底层。以前做视频 App,如果要支持听障人士或者多语言用户,你得自己接 ASR (自动语音识别) 和翻译 API,还得自己画字幕渲染层。现在,只要你的视频源没有自带对应语言的字幕,系统会在设备端自动用 AI 模型生成语音转写或翻译字幕,并且直接在播放界面展示。

对于使用 AVPlayerViewControllerAVPlayerView 的开发者,这完全是白嫖,你什么都不用做,字幕菜单里就会自动多出一个带 ✨ 图标的 AI 生成选项。对于做自定义播放器的开发者,Apple 也提供了 AVLegibleMediaOptionsMenuControllerAVPlayerLayer 的新 API,让你能快速把系统级的字幕选择和样式预览菜单嵌进自己的 UI 里。这对做长视频、直播或教育类 App 的团队来说,能省下至少一个月的开发时间。

值得深挖的点

设备端 AI 字幕的“零代码”代价与边界

Apple 敢把 AI 字幕做成默认开启,是因为他们把整个流程藏在了 AVFoundation 的媒体管道里。系统会优先使用媒体包里的人工字幕 (Authored subtitles),如果没有,才会 fallback 到设备端模型去跑语音转文字 (Speech transcription) 或字幕翻译 (Language translation)。

这种设计的 trade-off 很明显。好处是开发者零成本接入,且数据完全在设备端处理,没有隐私和服务器成本问题。坑在于,你失去了对生成文本的控制权。设备端模型目前主要支持英语语音转写,以及从英语字幕翻译成其他语言。如果你的视频里满是生僻的专业术语,或者口音极重,AI 生成的字幕可能会有错漏,而开发者目前没有 API 去注入自定义词典或进行后处理纠正。它解决的是“从无到有”的可用性 (Accessibility) 问题,而不是“绝对精准”的专业字幕问题。

字幕样式预览的 UX 升级与 API 巧思

以前用户想改字幕颜色或大小,必须切出 App 去系统的“设置 -> 辅助功能”里改,改完再回来看看效果,体验极其割裂。这次引入的字幕样式预览 (Subtitle style preview) 终于把这个流程闭环了。

底层实现上,Apple 用了一个很聪明的占位符机制。当你调用 setCaptionPreviewProfileID 时,系统会暂停渲染原有的视频字幕,在屏幕上打出一个占位文本(如果你 text 传 nil,就显示系统默认的本地化文本)。这个占位文本会应用你正在预览的样式。用户选定后,调用 stopShowingCaptionPreview 恢复原字幕,并用 MACaptionAppearanceSetActiveProfileID 全局生效。这个 API 设计避免了开发者自己去截图或者离屏渲染字幕样式,直接把渲染压力交给了 AVPlayerLayer

代码片段

1. 获取系统字幕样式并触发预览

场景:在自定义播放器的设置菜单中,列出所有系统字幕样式,并在用户点击时实时预览。

import AVFoundation
import MediaAccessibility

// 获取系统内所有的字幕样式 Profile ID
func loadSubtitleStyles() -> [String] {
    // 拿到系统预设和用户自定义的所有样式 ID
    let profileIDs = MACaptionAppearanceCopyProfileIDs() as? [String] ?? []
    return profileIDs
}

// 在 AVPlayerLayer 上触发样式预览
func previewStyle(profileID: String, playerLayer: AVPlayerLayer) {
    // text 传 nil 会使用系统默认的本地化预览文本
    // position 可以用来偏移预览文本,避免被你的自定义 UI 挡住
    playerLayer.setCaptionPreviewProfileID(
        profileID, 
        position: .zero, 
        text: nil
    )
}

坑:position 参数是相对于默认位置的偏移量,如果你的自定义控制栏在底部,记得给 Y 轴一个向上的负值偏移,否则预览文本会被控制栏挡住。

2. 停止预览并应用最终样式

场景:用户确认了某个字幕样式,关闭菜单并让新样式全局生效。

import AVFoundation
import MediaAccessibility

// 结束预览并应用用户选择的样式
func applyAndStopPreview(profileID: CFString, playerLayer: AVPlayerLayer) {
    // 移除占位文本,恢复视频原本的字幕渲染
    playerLayer.stopShowingCaptionPreview()
    
    // 将选中的样式设为系统活动样式,这会影响到设备上所有支持该特性的 App
    MACaptionAppearanceSetActiveProfileID(profileID)
}

坑:MACaptionAppearanceSetActiveProfileID 是系统级修改,一旦调用,用户在其他 App 里的字幕样式也会跟着变。千万不要在用户只是“滑过”菜单项时调用,必须在明确的“确认/选中”动作后才调用。

最佳实践

  • 全面排查自定义播放器:如果你的 App 用了自定义播放器 UI,赶紧检查是否暴露了字幕选择入口。如果没有,直接实例化 AVLegibleMediaOptionsMenuController 挂载到你的视图上,这是接入 AI 字幕和样式预览最省事的路径。
  • 不要试图拦截或修改 AI 字幕:目前 AVFoundation 没有提供拦截生成式字幕文本的回调。如果你的业务强依赖字幕的准确性(比如医疗、法律视频),请务必在媒体打包阶段提供高质量的人工字幕 (Authored subtitles),系统会优先使用你提供的字幕。
  • 合理布局预览文本:在调用 setCaptionPreviewProfileID 时,务必计算好底部播放器控制栏的高度,通过 position 参数上移预览文本,确保用户在调整样式时能看清完整的预览效果。

还有什么值得关注

  • UI 标识:AI 生成的字幕在菜单中会带有一个 Sparkle (✨) 图标,翻译生成的还会带有 “Translated” 标签,方便用户区分人工字幕和 AI 字幕。
  • 全场景覆盖:生成字幕不仅支持 VOD (视频点播) 和本地文件,还直接支持 HLS (HTTP Live Streaming) 直播流,这对做赛事或新闻直播的 App 是巨大利好。
  • 跨端一致性:除了 iOS 和 macOS,tvOS 和 visionOS 27 也同步支持了英语语音转写字幕,大屏设备的无障碍体验得到了补齐。
AVFoundation Accessibility AI Subtitles AVPlayerLayer MediaAccessibility