swift中的AVPlayer状态监听器
Posted
技术标签:
【中文标题】swift中的AVPlayer状态监听器【英文标题】:AVPlayer state listener in swift 【发布时间】:2017-02-03 13:25:06 【问题描述】:我想知道如何获取我的播放器 (AVPlayer) 的状态(缓冲、播放、停止、错误)并根据这些状态更新用户界面(包括锁定屏幕上的播放器)。具体应该怎么做?
我的标签可能包含: “正在缓冲...”、“正在播放”、“已停止”或“错误”。
基本上,我有以下几点:
媒体播放器:
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")
【问题讨论】:
【参考方案1】:我认为您可以使用AVPlayer
的timeControlStatus
属性。根据to the doc,它可以是paused
、waitingToPlayAtSpecifiedRate
,基本上就是你所说的buffering
或playing
。
如果你真的需要error
状态,你可以观察error
property或者status
property是否设置为failed
。
对这些属性进行简单的 KVO 观察器就可以解决问题。
【讨论】:
【参考方案2】:可以从使用 AVPlayer 的“状态”属性开始。它是一个包含以下值的枚举(直接取自文档):
'unknown':表示播放器的状态未知,因为它没有尝试加载新的媒体资源进行播放。
'readyToPlay':表示播放器已准备好播放 AVPlayerItem 实例。
'failed':表示由于错误,播放器无法再播放 AVPlayerItem 实例。
至于如何判断内容是否正在播放,您可以使用布尔检查,因为您似乎已部分实现。对于暂停和停止,您可以只保留加载的文件以暂停,并删除文件以停止,这样您就可以区分两者。
对于缓冲,如果枚举不是 unknown 或 readyToPlay 那么理论上应该意味着有一个文件正在附加但还没有准备好播放(即缓冲)。
【讨论】:
我按照你的说法试过了,但我总是得到“readyToPlay”(1)/:你能告诉我我该怎么做吗?使用 KVO (#3):developer.apple.com/library/content/documentation/Swift/…以上是关于swift中的AVPlayer状态监听器的主要内容,如果未能解决你的问题,请参考以下文章