我想知道如何获取播放器的状态(AVPlayer)(缓冲,播放,停止,错误)并根据这些状态(包括锁定屏幕上的播放器)更新ui。我该怎么办呢?
我有一个标签可能包含: “缓冲......”,“播放”,“停止”或“错误”。
基本上,我有以下内容:
的MediaPlayer :
import Foundation
import AVFoundation
class MediaPlayer {
static let sharedInstance = MediaPlayer()
fileprivate var player = AVPlayer(url: URL(string: "my_hls_stream_url_here")!)
fileprivate var isPlaying = false
func play() {
player.play()
isPlaying = true
}
func pause() {
player.pause()
isPlaying = false
}
func toggle() {
if isPlaying == true {
pause()
} else {
play()
}
}
func currentlyPlaying() -> Bool {
return isPlaying
}
}
PlayerViewController :
class PlayerViewController: UIViewController {
@IBOutlet weak var label: UILabel!
@IBAction func playStopButtonAction(_ sender: UIButton) {
MediaPlayer.sharedInstance.toggle()
}
override func viewDidLoad() {
super.viewDidLoad()
label.text = "Disconnected"
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
print("Audio session ok\n")
} catch {
print("Error: Audio session.\n")
}
// Show only play/pause button on the lock screen
if #available(iOS 9.1, *) {
let center = MPRemoteCommandCenter.shared()
[center.previousTrackCommand, center.nextTrackCommand, center.seekForwardCommand, center.seekBackwardCommand, center.skipForwardCommand, center.skipBackwardCommand, center.ratingCommand, center.changePlaybackRateCommand, center.likeCommand, center.dislikeCommand, center.bookmarkCommand, center.changePlaybackPositionCommand].forEach {
$0.isEnabled = false
}
center.togglePlayPauseCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
MediaPlayer.sharedInstance.toggle()
return MPRemoteCommandHandlerStatus.success
}
center.playCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
MediaPlayer.sharedInstance.play()
return MPRemoteCommandHandlerStatus.success
}
center.pauseCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
MediaPlayer.sharedInstance.pause()
return MPRemoteCommandHandlerStatus.success
}
} else {
// Fallback on earlier versions
print("Error (MPRemoteCommandCenter)")
}
}
override func remoteControlReceived(with event: UIEvent?) {
guard let event = event else {
print("No event\n")
return
}
guard event.type == UIEventType.remoteControl else {
print("Another event received\n")
return
}
switch event.subtype {
case UIEventSubtype.remoteControlPlay:
print("'Play' event received\n")
case UIEventSubtype.remoteControlPause:
print("'Pause' event received\n")
case UIEventSubtype.remoteControlTogglePlayPause:
print("'Toggle' event received\n")
default:
print("\(event.subtype)\n")
}
}
}
答案 0 :(得分:0)
我认为您可以使用timeControlStatus
的{{1}}属性。根据{{3}},AVPlayer
,paused
可以是waitingToPlayAtSpecifiedRate
或buffering
。
如果您确实需要playing
州,则可以观察error
to the doc或error
property是否设为status
关于这些属性的简单KVO观察者可以解决这个问题。
答案 1 :(得分:0)
开始的地方可能是使用AVPlayer的“status”属性。它是一个包含以下值的枚举(直接来自文档):
'unknown':表示尚未知道播放器的状态,因为它尚未尝试加载新的媒体资源进行播放。
'readyToPlay':表示播放器已准备好播放AVPlayerItem实例。
'失败':表示播放器因错误而无法播放AVPlayerItem实例。
至于如何判断内容是否实际正在播放,你可以使用布尔检查,因为它似乎已经部分实现了。对于暂停和停止,您可以保持文件加载暂停,并删除文件以便停止,以便区分这两者。
对于缓冲,如果枚举不是未知或 readyToPlay 那么理论上应该意味着有一个文件正在附加但尚未准备好播放(即缓冲)。