0
votes

I'm attempting to write an IOS app that will play my iPhone music library content, showing artwork, and "announcing" title, artist, etc.

I have it working nicely using Apple's Media Player framework. I can display Playlist names and queue the songs in a selected Playlist. I use the "MPMusicPlayerControllerNowPlayingItemDidChange" observer notification to pause playback, retrieve metadata, and do the announcements via AVSpeechSynthesizer. I was a happy camper until I ran into the dreaded "Media Player framwork doesn't respond to observer notifications in background" issue.

So, I started looking at the AVFoundation Framework. I found a sample that plays local song files via URLs in the background and. I'm failing miserably in attempting to retrieve Music Library content via the AVFoundation. I have also failed in supplying content retrieved via the Media Player framework to the AVFoundation player. (Note: The URLs retrieved from MPMediaItem are of a bogus "ipod-library://item/item.m4a?id=#########################" format. Creating AVPlayerItem with this "URL" doesn't work.)

Has anyone managed to accomplish this? I'm developing for my own usage. I have no intention of posting the app in Apple's App Store, so I'm willing to use hidden APIs or un-Apple approved methodology.

A Swift code example would be great. (Objective-C not so much)

1

1 Answers

0
votes

Having fetched an MPMediaItem from the user's library, obtain its assetURL. Creating an AVPlayer from the resulting URL does work.

Actual code from one of my example apps:

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