检测文件流已完成并准备好使用 avplayer 播放
Detect file streaming finished and ready to play with avplayer
我正在使用 avplayer 播放来自远程服务器的音频文件。当我播放这个时,首先从 url 播放 avplayer 流,然后播放文件。现在我只想检测文件流何时结束并开始播放。
这是我的代码:
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
player = AVPlayer(url: down_url)
player.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)
player.volume = 1.0
player.play()
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "rate" {
if player.rate > 0 {
print("player started")
}
}
}
我使用此代码进行检测,但它仅在 avplayer 开始播放时打印 "player started" 一次。但是我无法检测到avplayer什么时候开始播放。
注册成为玩家物品状态的观察者属性
playerItem.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: [.old, .new], context: &playerItemContext)
此方法将被调用
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// Only handle observations for the playerItemContext
guard context == &playerItemContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
// Observer for Player status
if keyPath == #keyPath(AVPlayerItem.status) {
let status: AVPlayerItem.Status
if let statusNumber = change?[.newKey] as? NSNumber {
status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!
} else {
status = .unknown
}
// Switch over status value
switch status {
case .readyToPlay:
// Player item is ready to play.
player.play()
playerControlsView.setPlayerControlsReady()
case .failed:
// Player item failed. See error.
print("Fail")
case .unknown:
// Player item is not yet ready.
print("unknown")
}
}
}
添加Observer来监听玩家何时结束游戏
NotificationCenter.default.addObserver(self, selector:#selector(self.playerDidFinishPlaying(note:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)
当玩家结束游戏时调用此方法
@objc func playerDidFinishPlaying(note: NSNotification){
print("Finished Playing")
}
不要忘记在完成播放器后移除观察器
NotificationCenter.default.removeObserver(self)
我正在使用 avplayer 播放来自远程服务器的音频文件。当我播放这个时,首先从 url 播放 avplayer 流,然后播放文件。现在我只想检测文件流何时结束并开始播放。
这是我的代码:
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
player = AVPlayer(url: down_url)
player.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.new, context: nil)
player.volume = 1.0
player.play()
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "rate" {
if player.rate > 0 {
print("player started")
}
}
}
我使用此代码进行检测,但它仅在 avplayer 开始播放时打印 "player started" 一次。但是我无法检测到avplayer什么时候开始播放。
注册成为玩家物品状态的观察者属性
playerItem.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: [.old, .new], context: &playerItemContext)
此方法将被调用
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// Only handle observations for the playerItemContext
guard context == &playerItemContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
// Observer for Player status
if keyPath == #keyPath(AVPlayerItem.status) {
let status: AVPlayerItem.Status
if let statusNumber = change?[.newKey] as? NSNumber {
status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!
} else {
status = .unknown
}
// Switch over status value
switch status {
case .readyToPlay:
// Player item is ready to play.
player.play()
playerControlsView.setPlayerControlsReady()
case .failed:
// Player item failed. See error.
print("Fail")
case .unknown:
// Player item is not yet ready.
print("unknown")
}
}
}
添加Observer来监听玩家何时结束游戏
NotificationCenter.default.addObserver(self, selector:#selector(self.playerDidFinishPlaying(note:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)
当玩家结束游戏时调用此方法
@objc func playerDidFinishPlaying(note: NSNotification){
print("Finished Playing")
}
不要忘记在完成播放器后移除观察器
NotificationCenter.default.removeObserver(self)