【发布时间】:2018-05-12 19:52:21
【问题描述】:
背景
我正在尝试在 macOS 应用程序中设置一个非常基本的音频播放器。我在 macOS 10.13.4 上使用 Xcode 9.3。
设置
我有一个MediaManager 类来控制AVPlayer 对象:
let EPISODE_SELECTED_KEY = "EPISODE_SELECTED"
class MediaManager {
static var shared: MediaManager = MediaManager()
var player: AVPlayer?
var currentFile: URL? {
didSet {
if (currentFile != nil) {
play(URL: currentFile!)
NotificationCenter.default.post(name: NSNotification.Name(EPISODE_SELECTED_KEY), object: nil)
}
}
}
func play(URL: URL) {
let item = AVPlayerItem(url: URL)
player = AVPlayer(playerItem: item)
player?.play()
}
}
为了直观地跟踪正在播放的音频项目的进度,我将NSSlider 子类化如下:
class PlayerSlider: NSSlider {
var observerToken: Any?
var mediaManager = MediaManager.shared
override var isEnabled: Bool {
didSet {
// Register for PlayerManager notification.
NotificationCenter.default.addObserver(self, selector: #selector(setupPlayerObserver), name: Notification.Name(EPISODE_SELECTED_KEY), object: nil)
}
}
override var doubleValue: Double {
didSet {
// Make sure the player has an active item.
guard mediaManager.currentEpisode != nil || mediaManager.currentFile != nil else {
return
}
// Update player with slider's position.
let seekTime = CMTime(seconds: (mediaManager.player?.currentTime().seconds)! * (doubleValue / 100), preferredTimescale: CMTimeScale(NSEC_PER_SEC))
mediaManager.player?.seek(to: seekTime)
}
}
@objc func setupPlayerObserver() {
// Setup observer to update UI every 0.5 seconds.
let interval = CMTime(seconds: 0.5, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
self.observerToken = mediaManager.player!.addPeriodicTimeObserver(forInterval: interval, queue: .main, using: { (time) in
// Update slider value to audio item progress.
let duration = self.mediaManager.player!.currentItem!.duration.seconds
let seekTime = self.mediaManager.player!.currentTime().seconds
self.doubleValue = seekTime / duration * 100
})
}
}
出于测试目的,我只是将MediaManager 单例的currentFile 属性设置为本地文件。
问题
在我传递给addPeriodicTimeObserver 函数的块中,如果我注释掉文件播放正常的所有内容。但是,如果那里甚至有一个 print 语句,则什么也不会发生。该文件从不播放,应用程序只是挂起。
问题
- 该块内发生了什么?即使是单个语句也会阻止
AVPlayer播放。 - 这是音频文件播放器的好设计吗?让
MediaManager单例和PlayerSlider中的侦听器。
【问题讨论】:
标签: swift macos notifications avfoundation appkit