AVPlayerViewController — Apple生态系统中的内置视频播放器控制器,专为iOS和tvOS上的媒体播放而设计。它提供全屏界面,包含控件、字幕支持和AirPlay功能,无需编写自定义UI。根据 Apple Developer Documentation, 2026,AVPlayerViewController只需几行代码即可集成,并支持HLS、MP4及大多数媒体格式。
要点
AVPlayerViewController — 是AVKit框架的一个组件,为Apple应用中的视频播放提供现成界面。它免去了开发者从头创建自定义播放器的需要,提供标准控件:播放/暂停、快进、音量调节和全屏模式。
与需要手动构建UI的低级AVPlayerLayer不同,AVPlayerViewController完全管理播放器的生命周期。控制器自动处理屏幕旋转,适应带刘海iPhone的安全区域,并支持iPad多任务处理。
根据Apple Documentation (2026),AVPlayerViewController兼容AVPlayer和AVQueuePlayer,可播放单个文件和播放列表。支持本地存储URL、网络HLS流以及加密的FairPlay内容。
该组件随iOS 8与AVKit一起推出,作为已弃用的MPMoviePlayerController的替代品。在iOS 11中增加了画中画支持和字幕显示。在iOS 14中,控制器通过AVPlayerViewControllerDelegate委托获得了可自定义的传输面板。从iOS 16开始,支持无需重新创建播放器即可动态替换媒体文件。
现代AVPlayerViewController针对ProMotion显示进行了优化 — 视频帧率自动与屏幕刷新率同步。在tvOS上,该组件适配Siri Remote的焦点界面;在macOS上,则适配QuickTime Player的窗口模式。
控制器的核心是AVPlayer和AVPlayerItem的组合。AVPlayer是一个播放对象,管理时间线、速度和状态。AVPlayerItem是特定媒体文件的封装,包含元数据、轨道和加载信息。
初始化时,AVPlayerViewController获取对AVPlayer的引用,并自动创建用于显示视频的AVPlayerLayer。控制器订阅AVPlayer的KVO通知,以了解readyToPlay状态变化、加载错误和播放结束。
控件(传输面板)在点击屏幕时显示。在iOS 15+中,它们通过AVPlayerViewControllerCustomizationDelegate支持自定义,允许隐藏或替换标准按钮。
创建控制器并分配AVPlayer后,调用viewDidLoad方法,开始准备视频流。当AVPlayerItem进入AVPlayerItemStatusReadyToPlay状态时,播放器准备好显示帧。调用play()方法时,通过Video Toolbox开始解码视频流。
离开屏幕时,控制器自动暂停播放并释放解码器资源。在iOS 13+中,为了在应用最小化时保持播放,需要配置后台模式和音频会话。根据WWDC 2024,建议使用AVPlayerPlaybackCoordinator与iOS媒体中心同步。
该组件开箱即用提供丰富的功能集,使其对大多数项目具有吸引力。以下是无需额外代码的关键功能。
传输面板是界面的底部部分,包含主要控制按钮。默认情况下,面板在用户不活动3秒后隐藏,点击时显示。在iOS 16+中,通过委托可以管理各个元素的可见性。
在调试模式下,可以通过AVPlayerViewController.requiresLinearPlayback属性强制显示传输面板,该属性还会阻止暂停视频的功能。这对于广告插入和教育内容非常有用。
控制器的基本集成只需不超过10行代码。首先,使用媒体文件URL创建AVPlayer实例,然后将其传递给AVPlayerViewController并在屏幕上显示控制器。
import AVKit
let player = AVPlayer(url: URL(string: "https://example.com/video.mp4")!)
let playerVC = AVPlayerViewController()
playerVC.player = player
present(playerVC, animated: true) {
player.play()
}
调用present后,控制器全屏显示。视频开始从网络加载,一旦缓冲区达到readyToPlay阈值,调用play()后自动开始播放。
let asset = AVAsset(url: videoURL)
let item = AVPlayerItem(asset: asset)
let metadata = AVMutableMetadataItem()
metadata.key = AVMetadataKey.commonKeyTitle
metadata.value = "我的视频"
item.addMetadata(metadata)
let player = AVPlayer(playerItem: item)
let playerVC = AVPlayerViewController()
playerVC.player = player
使用AVPlayerItem可以控制元数据、时间码、音轨和字幕选择。通过AVPlayerItem,还可以使用KVO监控status属性来观察加载进度、缓冲和网络错误。
从iOS 11开始,开发者可以通过AVPlayerViewControllerDelegate协议自定义传输面板。方法playerViewController(_:willBeginFullScreenPresentationWithAnimationCoordinator:)在全屏模式进入前被调用,允许准备UI。
要隐藏单个按钮,使用AVPlayerViewController.showsPlaybackControls属性。如果将其设置为false,传输面板完全消失,只留下视频流。这对于自定义覆盖元素非常有用。
class CustomPlayerViewController: UIViewController {
private let playerVC = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
playerVC.delegate = self
playerVC.showsPlaybackControls = true
playerVC.entersFullScreenWhenPlaybackBegins = true
}
}
extension CustomPlayerViewController: AVPlayerViewControllerDelegate {
func playerViewController(
_ playerViewController: AVPlayerViewController,
willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator
) {
// 添加覆盖按钮
}
func playerViewController(
_ playerViewController: AVPlayerViewController,
didUpdate legibleMediaSelection: AVMediaSelectionGroup
) {
print("已选择新的字幕语言")
}
}
委托允许拦截字幕更改、全屏模式进入和退出以及画中画开始和完成的事件。在WWDC 2024上,Apple建议使用委托进行分析 — 记录每次过渡,精度达100毫秒。
AVPlayerViewController自动显示所有可用的字幕和音轨,如果它们嵌入在媒体文件中或在HLS清单中指定。用户可以通过点击传输面板中的字幕图标显示的菜单进行切换。
对于HLS流,M3U8清单包含可用语言选项的列表。AVPlayer加载WebVTT格式的相应字幕片段,并通过AVPlayerLayer进行渲染。在iOS 16+中,通过AVTextStyleRule增加了对字幕样式的支持。
func selectAudioTrack(languageCode: String) {
guard let group = player.currentItem?
.asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristic.audible)
else { return }
for option in group.options {
if option.extendedLanguageTag?.hasPrefix(languageCode) == true {
player.currentItem?.select(option, in: group)
}
}
}
方法selectAudioTrack在audible组的音频选项中查找其extendedLanguageTag与所需语言代码匹配的选项。这允许在多语言内容应用中实现“原声播放”功能。
画中画(PiP)模式允许在其他应用之上以浮动窗口显示视频。在iPad上,此功能从iOS 9开始可用;在iPhone上,从iOS 14开始可用。AVPlayerViewController在有UIBackgroundModes订阅时自动在传输面板中添加PiP按钮。
要激活PiP,需要在Info.plist中添加键UIBackgroundModes,值为audio和airplay。之后,控制器中出现PiP按钮,点击后视频折叠为192x108点的浮动窗口。
PiP事件通过委托处理:playerViewController(_:willStartPictureInPictureFromFullScreen:)和playerViewController(_:didStopPictureInPicture:)。根据Apple HIG,PiP窗口的最小大小应至少为120x68点,以保持内容可读性。
常见问题
不支持。YouTube视频需要使用网页视图WKWebView或YouTube iOS Helper库,因为YouTube使用自己的DRM系统。AVPlayerViewController用于通过URL直接播放媒体流。
将showsPlaybackControls属性设置为false。之后屏幕保持空白 — 只有视频流。要恢复自定义按钮,通过addSubview在控制器之上添加覆盖层。
是的,控制器完全支持HLS直播。传输面板显示Live指示器,而不是进度滑块。延迟取决于HLS配置 — 在低延迟设置下最少6秒。
订阅AVPlayerItem.status属性的KVO。出错时状态变为.failed。通过AVPlayerItem的error属性获取详细信息,并向用户显示带解释的提示 — 问题通常出在网络或URL不正确。
可以。使用带有自定义AVAssetResourceLoader的AVAsset从RAM提供数据。实现AVAssetResourceLoaderDelegate委托,从缓冲区返回字节,而不是从磁盘读取。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。