Deliver a great playback experience on tvOS
Audio & Video 进阶 26m

在 tvOS 上打造出色的播放体验

Deliver a great playback experience on tvOS

2021年6月10日

在 Apple 官方观看视频

一句话判断

如果你的 tvOS 视频播放 App 还没有用 AVPlayerViewController,你正在错过一整套系统级的播放体验增强——包括 Up Next 集成、Siri 控制和画中画。

这场 Session 讲了什么

这场 Session 聚焦 tvOS 上的媒体播放体验,核心信息只有一个:用 AVPlayerViewController(AVPlayerViewController)。Apple 在 tvOS 15 中对它做了大量增强,让它成为 tvOS 播放场景下的事实标准方案。

Session 详细讲解了如何将你的自定义播放器迁移到 AVPlayerViewController,包括处理自定义 UI overlay、字幕轨道管理、章节导航等常见需求。还介绍了与系统 TV App 的 Up Next 功能集成——用户在你的 App 中开始看的内容,会自动出现在系统级的”接着看”列表中,这是巨大的流量入口。

另外还涵盖了新的 Now Playing Info 集成和 Siri 远程控制的最佳实践。Apple 明确表示,使用系统播放器能自动获得未来的系统级特性支持,而自定义播放器则不会。

值得深挖的点

Up Next 集成的收益与代价

Up Next 是 tvOS 用户进入内容的主要入口之一。通过 TVUserStore API,你可以将用户观看进度同步到系统的 Up Next 列表。这意味着用户不需要打开你的 App 就能看到未看完的内容。但代价是你需要正确实现内容元数据的提供,包括标题、描述、封面图、观看进度百分比。如果这些数据不准确,用户看到的就是一个信息混乱的推荐列表。

自定义 UI overlay 与 AVPlayerViewController 的共存

很多开发者不用 AVPlayerViewController 的原因是要自定义播放界面。tvOS 15 允许你在 AVPlayerViewController 上叠加自定义的 UI overlay,同时保留系统提供的转场动画、字幕选择器和播放控制。这是一个很好的折中方案——既保持了系统级特性的支持,又不完全放弃自定义需求。

代码片段

配置 AVPlayerViewController 的基本信息

let player = AVPlayer(url: videoURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player

// 设置 Now Playing 信息,让 Siri 和控制中心能识别
var nowPlayingInfo = [String: Any]()
nowPlayingInfo[MPMediaItemPropertyTitle] = "我的视频标题"
nowPlayingInfo[MPMediaItemPropertyArtist] = "频道名称"
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo

同步观看进度到 Up Next

import TVServices

// 更新用户的观看进度
let contentItem = TVContentItem(identifier: TVContentIdentifier("com.example.video.123")!)
contentItem.title = "第三集:转折"
contentItem.playbackProgress = 0.65  // 看了 65%

TVUserStore.shared.updateWatchedContent([contentItem]) { error in
    if let error = error {
        print("同步观看进度失败:\(error)")
    }
}

添加自定义 UI overlay

// 在 AVPlayerViewController 上叠加自定义控件
let overlayView = CustomPlaybackOverlay(frame: view.bounds)
overlayView.translatesAutoresizingMaskIntoConstraints = false
playerViewController.contentOverlayView?.addSubview(overlayView)

NSLayoutConstraint.activate([
    overlayView.topAnchor.constraint(equalTo: playerViewController.contentOverlayView!.topAnchor),
    overlayView.bottomAnchor.constraint(equalTo: playerViewController.contentOverlayView!.bottomAnchor),
    overlayView.leadingAnchor.constraint(equalTo: playerViewController.contentOverlayView!.leadingAnchor),
    overlayView.trailingAnchor.constraint(equalTo: playerViewController.contentOverlayView!.trailingAnchor)
])

最佳实践

新项目: 直接使用 AVPlayerViewController 作为播放器,不要造轮子。自定义 UI 通过 contentOverlayView 实现。从第一天就集成 Up Next,这是 tvOS 用户发现内容的主要路径。

已有项目: 如果使用自定义播放器,制定迁移计划。先处理 Now Playing Info 和远程控制,再处理 Up Next 集成。迁移过程中可以先用 AVPlayerViewController 处理基本播放,逐步把自定义 UI 迁移到 overlay 上。

还有什么值得关注

  • tvOS 15 支持了通过系统级控制来调整字幕和音频轨道,无需自己实现 UI。
  • AVPlayerViewController 自动支持画中画,用户可以在看视频的同时浏览其他内容。
  • 使用 AVPlayerViewController 的 App 在未来 tvOS 版本中自动获得新的播放特性。
WWDC 2021