AVFoundation
AVPlayer
AVPlayer是一个控制器对象,用于管理媒体资源。AVPlayer基于本地文件或远程文件媒体播放。AVPlayer用于一次播放单个媒体资源,可以使用replaceCurrentItem(with:)
方法重用播放器实例来播放气体媒体资源,但同一个时刻只能管理一个媒体资源,使用AVQueuePlayer来创建和管理媒体播放的队列。
AVPlayer是一个动态变化的对象,有两种方式来观察播放器实例的状态:
- 一般状态观察:你可以使用Key-Value observing(KVO)模式来观察属性的动态变化(如当前播放Item或者播放速度)。你应当在主线程中注册或者注销KVO。
- 定时状态观察:提供两种观察时间变化的方法。
addPeriodicTimeObserver(forInterval:queue:using:) addBoundaryTimeObserver(forTimes:queue:using:)
分别定期、按边界观察时间变化。发生更改时,调用方法提供的闭包或者回调块,可以采取播放器用户界面的更新。
AVPlayer和AVPlayerItem都是非可视对象,意味着无法直接在屏幕上显示媒体视频,有两种方法可以在屏幕上显示视频:
- AVKit 最好的展示视频内容的方法使用是AVKit框架下的AVPlayerViewController类在 iOS、tvOS,或者AVPlayerView在macOS中,这些类提供一个全面完整的播放体验。
- AVPlayerLayer 可以将AVPlayerLayer添加到视图的layer层
view.layer.addSublayer(AVPlayerLayer)
中。与AVPlayerView和AVPlayerViewController不同,播放器层不显示任何播放控件,仅仅在屏幕上显示视觉内容。你可以自行构建播放传输控件,以播放,暂停和搜索媒体。
AVPlayerItem
AVPlayerItem提供了AVPlayer播放需要的媒体文件,时间、状态、文件大小等信息,是AVPlayer媒体文件的模型对象。
Example
实现类似Spotify的视频背景界面的效果。
- 创建AVPlayer并与视频资源建立连接
- 通过AVPlayerLayer将AVPlayer与view的layer层连接
- 添加通知监听,监听视频播放进度,实现循环播放
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
lazy var player: AVPlayer = {
let string = Bundle.main.path(forResource: "moments", ofType: "mp4")
let url = URL(fileURLWithPath: string!)
let player = AVPlayer(url: url)
return player
}()
lazy var playerLayer: AVPlayerLayer = {
let playerLayer = AVPlayerLayer(player: self.player)
playerLayer.frame = UIScreen.main.bounds
playerLayer.player?.play()
return playerLayer
}()
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
func setupView() {
self.view.layer.addSublayer(playerLayer)
//通知监听
NotificationCenter.default.addObserver(self, selector: #selector(didFinishedPlay(notification:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)
}
//实现循环播放
@objc func didFinishedPlay(notification: Notification) {
if let playerItem = notification.object as? AVPlayerItem {
//改变AVPlayerItem状态模型对象的时间
playerItem.seek(to: CMTime.zero, completionHandler: nil)
player.play()
}
}
}