Проблемы с переключением между плейлистами и установкой таймеров в приложении Swift iOS MPMediaPlayer

Я создаю приложение для музыкального проигрывателя, предназначенное для имитации автоматизации потоковой передачи радио или Интернета. Мне уже удалось извлечь музыку из плейлистов и отфильтровать по последней дате воспроизведения, чтобы песни не часто повторялись (любимая мозоль в моем iPod). Я хочу, чтобы он каждые четверть часа проигрывал короткие идентификаторы станций из отдельного списка воспроизведения, а затем возвращался к текущему списку воспроизведения или переключался на новый. Блокпосты, с которыми я сталкиваюсь, получают повторяющийся таймер, чтобы дождаться окончания песни перед воспроизведением идентификатора и воспроизвести только один идентификатор перед переключением обратно на музыку. Наблюдатель уведомлений…

NotificationCenter.default.addObserver(self, selector:#selector(ViewController.quarterHour), name: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange, object: nil)

…срабатывает таймер…

self.timer2 = Timer(fireAt: date, interval: 1, target: self, selector: #selector(ViewController.runVoicer(_:)), userInfo: nil, repeats: true)
self.timer2.tolerance = 0.1
        

…который запускает эту функцию:

    @objc func quarterHour() {
        self.timer2 = Timer.scheduledTimer(timeInterval: 900, target: self, selector: #selector(ViewController.runVoicer(_:)), userInfo: nil, repeats: true)
        self.timer2.tolerance = 0.1
        }

Медиа-запрос, который выбирает из плейлиста Voicers…

    @objc func runVoicer(_:AnyObject) {
        mp.pause()
        let queryVoice = MPMediaQuery.songs()
        let predicate = MPMediaPropertyPredicate(value: "Voicers",
                                                forProperty: MPMediaPlaylistPropertyName,
                                                comparisonType: .equalTo)
        queryVoice.addFilterPredicate(predicate)
        var collection = [MPMediaItem]()
        let unixDefault = Date(timeIntervalSince1970: 100)
        if let voicers = queryVoice.items {
            collection = voicers.sorted{$0.lastPlayedDate ?? unixDefault > $1.lastPlayedDate ?? unixDate}
        }
        let voiceCollection = MPMediaItemCollection(items: collection)
        mp.setQueue(with: voiceCollection)
            mp.play()
        fetchRockPlaylist()
    }

… не только прерывает песню, когда таймер срабатывает, вместо использования уведомления «…NowPlayingItemDidChange», но также продолжает играть, вместо этого возвращаясь к функции, указанной внизу, после одного воспроизведения, потому что я не могу найти какой-либо метод для изоляции первого элемента в массив голосовой коллекции.


person TCollette    schedule 22.11.2020    source источник
comment
Раньше я не видел варианта ответа, может быть, потому, что у меня не было возможности сделать это (очень новое здесь). Починил это…   -  person TCollette    schedule 28.11.2020


Ответы (1)


Обновление: не потребовалось много времени, чтобы понять, что подход с таймером никогда не применялся. Присущая задержка при переключении списков воспроизведения на лету означала прослушивание следующей песни за секунду или две до того, как сработает идентификатор. После нескольких дней исследований я добился прорыва в Playground, перебирая два массива и вставляя элементы из одного в другой через равные промежутки времени. Итак, после перезаписи функции для вызова обоих списков воспроизведения, а также перетасовки, сортировки и фильтрации результирующих массивов по мере необходимости, этот цикл размещал идентификаторы после каждых 3 песен…

let arrayCount = voiceCollection.count
var interR = 0
var indexV = 0
// for loop iterates through rock collection by 3, inserts item from voice collection
    for i in 0..<arrayCount {
       rockSet.insert(voiceCollection[indexV], at:interR)
       interR += 4
       indexV += 1
}

Теперь он работает именно так, как я хочу. Единственная оставшаяся проблема — убедиться, что у меня как минимум в 3 раза больше доступных песен, чем ID, иначе я получу ошибку вне допустимого диапазона, но этого легко избежать. Просто хотел опубликовать это на случай, если кто-то еще сочтет это полезным, поскольку, похоже, я не нашел примеров этого где-либо еще. Ваше здоровье…

person TCollette    schedule 27.11.2020