/ / Funkcja addPeriodicTimeObserver AVPlayera nie jest wykonywana poprawnie - szybkie, maco, powiadomienia, avfoundation, appkit

Funkcja addPeriodicTimeObserver AVPlayera nie jest wykonywana poprawnie - szybka, macos, powiadomienia, avfoundation, appkit

tło

Próbuję uzyskać bardzo prosty odtwarzacz audio skonfigurowany w aplikacji macOS. ja używam Xcode 9.3 na macOS 10.13.4.


Ustawiać

mam MediaManager klasa do kontrolowania AVPlayer obiekt:

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()
}

}

Aby wizualnie śledzić postęp odtwarzanego elementu audio, podklasuję NSSlider jako tak:

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
})

}
}

Do celów testowych właśnie ustawiam currentFile własność MediaManager singleton do lokalnego pliku.


Problem

W bloku, który przechodzę do addPeriodicTimeObserver funkcja, jeśli skomentuję wszystko, co gra poprawnie. Jeśli jednak pojawi się tam nawet instrukcja drukowania, nic się nie dzieje, plik nigdy nie jest odtwarzany, a aplikacja po prostu się zawiesza.


pytania

  1. Co się dzieje w tym bloku? Nawet pojedyncze zdanie zatrzymuje AVPlayer z grania.
  2. Czy to dobry projekt dla odtwarzacza plików audio? Aby mieć MediaManager singleton i słuchacz w środku PlayerSlider.

Odpowiedzi:

0 dla odpowiedzi № 1

To, co napisałeś, prosi okresowego obserwatora, aby oddzwonił co 0,5 * 109sekund, ale 0,5 jest zaokrąglane w dół do 0, więc jest co 0 sekund. Żadne z nich nie jest możliwe (dlaczego nie addPeriodicTimeObserver wspomnieć o tym?), więc spróbuj

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