/ / Функцията addPeriodicTimeObserver на AVPlayer не се изпълнява правилно - бърз, макрос, известия, аванс, апкит

Функцията AddPeriodicTimeObserver на AVPlayer не се изпълнява правилно - бърз, макрос, известия, авангард, appkit

Заден план

Опитвам се да получа много аудио плейър, създаден в приложение за macOS. Използвам Xcode 9.3 за macOS 10.13.4.


Настройвам

имам 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
})

}
}

За целите на тестването просто зададох currentFile собственост на MediaManager singleton към локален файл.


проблем

В блока, който преминавам към addPeriodicTimeObserver ако коментирам всичко, което файлът играе добре. Въпреки това, ако има дори изявление за отпечатване там, нищо не се случва. Файлът никога не се възпроизвежда и приложението просто виси.


въпроси

  1. Какво става в този блок? Дори едно изявление спира AVPlayer от игра.
  2. Дали това е добър дизайн за аудио файлов плейър? За да има MediaManager singleton и слушателя вътре PlayerSlider.

Отговори:

0 за отговор № 1

Това, което сте написали, изисква от периодичния наблюдател да ви се обажда на всеки 0.5 * 109секунди, но 0.5 е закръглено надолу до 0, така че е на всеки 0 секунди. Нито пък е възможно (защо не addPeriodicTimeObserver споменете това?), така че опитайте

let interval = CMTime(seconds: 1, preferredTimescale: 10)  // every tenth of a second, say