功能最全、自定义最高的播放器,也是使用最多得。使用起来较为复杂些。需导入AVKit控件(import AVKit)
相关参数
- AVPlayer: 负责控制播放器的播放,暂停等操作
- AVAsset:获取多媒体信息的抽象类,不能直接使用
- AVURLAsset: AVAsset 的一个子类,使用 URL 进行实例化,实例化对象包换 URL 对应视频资源的所有信息。
- AVPlayerItem: 管理媒体资源对象,提供播放数据源
- AVPlayerLayer: 负责显示视频,如果没有添加该类,只有声音没有画面
1、基本播放
播放设置
//创建媒体资源管理对象
self.palyerItem = AVPlayerItem(url: NSURL(string: urlString)! as URL)
//创建ACplayer:负责视频播放
self.player = AVPlayer.init(playerItem: self.palyerItem)
self.player.rate = 1.0//播放速度 播放前设置
//创建显示视频的图层
let playerLayer = AVPlayerLayer.init(player: self.player)
playerLayer.videoGravity = .resizeAspect
playerLayer.frame = self.view.bounds
self.view.layer .addSublayer(playerLayer)
//播放
self.player.play()
播放暂停
func pauseButtonSelected(sender:UIButton) {
sender.isSelected = !sender.isSelected
if sender.isSelected{
self.player.pause()
}else{
self.player.play()
}
}
2、观察AVPlayerItem属性(观察播放状态、缓存情况等)
当前播放状态
KVO观察当前的播放状态
self.palyerItem.addObserver(self, forKeyPath: "status", options: .new, context: nil)
一共有三种播放状态,准备播放、播放失败、未知。
func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status" {
switch self.palyerItem.status{
case .readyToPlay:
//准备播放
self.play()
case .failed:
//播放失败
print("failed")
case.unknown:
//未知情况
print("unkonwn")
}
}
播放时间与总时间
处理时间,有一个结构体CMTime
typedef struct{
CMTimeValue value; // 帧数
CMTimeScale timescale; // 帧率
CMTimeFlags flags;
CMTimeEpoch epoch;
} CMTime;
视频总时间
let totalTime = CMTimeGetSeconds((self?.player.currentItem?.duration)!)
当前播放时间
let currentTime = self.playItem.currentTime.value/self.playItem.currentTime.timescale;
实时的获取播放时长和控制进度条
self.player.addPeriodicTimeObserver(forInterval: CMTimeMake(1, 1), queue: DispatchQueue.main) { [weak self](time) in
//当前正在播放的时间
let loadTime = CMTimeGetSeconds(time)
//视频总时间
let totalTime = CMTimeGetSeconds((self?.player.currentItem?.duration)!)
//播放进度设置
self?.slider.value = Float(loadTime/totalTime)
//播放的时间(changeTimeFormat方法是转格式的)
self?.loadTimeLabel.text = self?.changeTimeFormat(timeInterval: loadTime)
//总时间
self?.totalTimeLabel.text =self?.changeTimeFormat(timeInterval:CMTimeGetSeconds((self?.player.currentItem?.duraton)!))
}
播放缓存
与播放缓存相关的观测属性
- loadedTimeRanges 缓存区间,可用来获取缓存了多少
- playbackBufferEmpty 缓存不够了 自动暂停播放
- playbackLikelyToKeepUp 缓存好了 手动播放
self.palyerItem.addObserver(self, forKeyPath: "loadedTimeRanges", options: .new, context: nil)
self.palyerItem.addObserver(self, forKeyPath: "playbackBufferEmpty", options: .new, context: nil)
self.palyerItem.addObserver(self, forKeyPath:"playbackLikelyToKeepUp", options: .new,context:nil)
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status" {
switch self.palyerItem.status{
case .readyToPlay:
self.play()
case .failed:
print("failed")
case.unknown:
print("unkonwn")
}
}else if keyPath == "loadedTimeRanges"{
let loadTimeArray = self.palyerItem.loadedTimeRanges
//获取最新缓存的区间
let newTimeRange : CMTimeRange = loadTimeArray.first as! CMTimeRange
let startSeconds = CMTimeGetSeconds(newTimeRange.start);
let durationSeconds = CMTimeGetSeconds(newTimeRange.duration);
let totalBuffer = startSeconds + durationSeconds;//缓冲总长度
print("当前缓冲时间:%f",totalBuffer)
}else if keyPath == "playbackBufferEmpty"{
print("正在缓存视频请稍等")
}
else if keyPath == "playbackLikelyToKeepUp"{
print("缓存好了继续播放")
self.player.play()
}
}
要记得移除观察,而且这里是self.palyerItem,不要搞错了
self.palyerItem.removeObserver(self, forKeyPath: "status", context: nil)
self.palyerItem.removeObserver(self, forKeyPath: "loadedTimeRanges", context: nil)
self.palyerItem.removeObserver(self, forKeyPath: "playbackBufferEmpty", context: nil)
self.palyerItem.removeObserver(self,forKeyPath: "playbackLikelyToKeepUp", context: nil)
NotificationCenter.default.removeObserver(self)
3、AVplayer常用相关通知
//音频中断通知
AVAudioSessionInterruptionNotification
//音频线路改变(耳机插入、拔出)
AVAudioSessionSilenceSecondaryAudioHintNotification
//媒体服务器终止、重启
AVAudioSessionMediaServicesWereLostNotification
AVAudioSessionMediaServicesWereResetNotification
//其他app的音频开始播放或者停止时
AVAudioSessionSilenceSecondaryAudioHintNotification
//播放结束
AVPlayerItemDidPlayToEndTimeNotification
//进行跳转
AVPlayerItemTimeJumpedNotification
//异常中断通知
AVPlayerItemPlaybackStalledNotification
//播放失败
AVPlayerItemFailedToPlayToEndTimeNotification
使用AVPlayerItemDidPlayToEndTime通知
NotificationCenter.default.addObserver(self, selector: #selector(playToEndTime), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
@objc func playToEndTime(){
print("播放完成")
}
4、其他
demo地址:swift视频播放器使用
iOS其他播放器的使用:iOS播放器