AVPlayer 视频播放
问题
AVPlayer 的使用和常见问题?
答案
基本使用
import AVKit
class PlayerViewController: UIViewController {
private var player: AVPlayer?
private var playerViewController: AVPlayerViewController?
func playVideo(url: URL) {
let playerItem = AVPlayerItem(url: url)
player = AVPlayer(playerItem: playerItem)
let playerVC = AVPlayerViewController()
playerVC.player = player
present(playerVC, animated: true) {
self.player?.play()
}
}
}
自定义播放器
class CustomPlayerView: UIView {
override class var layerClass: AnyClass { AVPlayerLayer.self }
var playerLayer: AVPlayerLayer { layer as! AVPlayerLayer }
private var player: AVPlayer?
private var timeObserver: Any?
func setup(url: URL) {
let item = AVPlayerItem(url: url)
player = AVPlayer(playerItem: item)
playerLayer.player = player
playerLayer.videoGravity = .resizeAspect
// 播放进度监听
timeObserver = player?.addPeriodicTimeObserver(
forInterval: CMTime(seconds: 0.5, preferredTimescale: 600),
queue: .main
) { [weak self] time in
let seconds = CMTimeGetSeconds(time)
// 更新进度条
}
// KVO 监听状态
item.addObserver(self, forKeyPath: "status", options: .new, context: nil)
}
deinit {
if let observer = timeObserver {
player?.removeTimeObserver(observer)
}
}
}
常见场景
| 场景 | 方案 |
|---|---|
| 简单播放 | AVPlayerViewController |
| 自定义 UI | AVPlayer + AVPlayerLayer |
| 列表视频 | 复用 AVPlayer,切换 AVPlayerItem |
| 后台播放 | 开启 Background Modes: Audio |
| 画中画 | AVPictureInPictureController |
常见面试问题
Q1: AVPlayer 播放卡顿怎么排查?
答案:观察 playerItem.isPlaybackLikelyToKeepUp 和 loadedTimeRanges。常见原因:网络带宽不足、buffer 太小。可以用 preferredForwardBufferDuration 调整缓冲,或者使用 HLS 自适应码率。