Воспроизведение содержимого музыкальной библиотеки IOS с помощью AVFoundation
Я пытаюсь написать приложение для IOS, которое будет воспроизводить содержимое моей музыкальной библиотеки iPhone, показывать обложки и "объявлять" название, исполнителя и т. Д.
У меня это работает хорошо, используя Apple Media Player Framework. Я могу отображать имена списков воспроизведения и ставить в очередь песни в выбранном списке воспроизведения. Я использую уведомление наблюдателя "MPMusicPlayerControllerNowPlayingItemDidChange", чтобы приостановить воспроизведение, извлечь метаданные и сделать объявления через AVSpeechSynthesizer. Я был счастливым туристом, пока не столкнулся с ужасной проблемой "Фреймворк Media Player не отвечает на уведомления наблюдателей в фоновом режиме".
Итак, я начал смотреть на AVFoundation Framework. Я нашел образец, который воспроизводит локальные файлы песен через URL-адреса в фоновом режиме и. Я с треском проваливаюсь, пытаясь получить содержимое музыкальной библиотеки через AVFoundation. Мне также не удалось доставить контент, извлеченный из среды Media Player, в проигрыватель AVFoundation. (Примечание: URL-адреса, полученные из MPMediaItem, являются поддельной " библиотекой ipod://item/item.m4a? Id=############################## ## "формат. Создание AVPlayerItem с этим"URL"не работает.)
Кому-нибудь удалось это сделать? Я разрабатываю для собственного использования. Я не собираюсь публиковать приложение в Apple App Store, поэтому я готов использовать скрытые API или методологию, не одобренную Apple.
Пример кода Swift был бы великолепен. (Objective-C не так много)
1 ответ
Получив MPMediaItem из библиотеки пользователя, получите его assetURL
, Создание AVPlayer из полученного URL работает.
Фактический код из одного из моих примеров приложений:
func oneSong () -> (URL?, String?) {
let query = MPMediaQuery.songs()
// always need to filter out songs that aren't present
let isPresent = MPMediaPropertyPredicate(value:false,
forProperty:MPMediaItemPropertyIsCloudItem,
comparisonType:.equalTo)
query.addFilterPredicate(isPresent)
let item = query.items?[0]
return (item?.assetURL, item?.title)
}
@IBAction func doPlayOneSongAVPlayer (_ sender: Any) {
let (url, title) = self.oneSong()
if let url = url, let title = title {
self.avplayer = AVPlayer(url:url)
self.avplayer.play()
MPNowPlayingInfoCenter.default().nowPlayingInfo = [
MPMediaItemPropertyTitle : title
]
}
}