3

i have succesfully created a AVAudioEngine. It plays local sound-files from the project-directory. But how can I get access to the Music Library on the phone?

Is there a way I can combine AVAudioEngine with the MPMediaPickerController ?

Thank you

Joel
  • 396
  • 1
  • 15

1 Answers1

2

Yes :)

You need to set the MPMediaPickerControllerDelegate on your MPMediaPickerController so you will get notified when the user does something in the MPMediaPickerController. Here are the methods you can use on MPMediaPickerControllerDelegate.

As you can see, there is the method mediaPicker(_:didPickMediaItems:) which is called when the user has picked a song to play. That gives you a (MPMediaItemCollection) which has items containing the songs which the user picked.

You can loop through that collection and look at the individual items which are of type MPMediaItem.

Finally each MPMediaItem has an assetURL which you can to create the individual nodes in your AVAudioEngine.

So...something along the lines of:

Where You Create Your MPMediaPickerController

let mediaPicker = MPMediaPickerController(mediaTypes: .anyAudio)
mediaPicker.delegate = self
present(mediaPicker, animated: true, completion: nil)

Delegate Methods

public func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
  for item in mediaItemCollection.items {
     if let assetURL = item.assetURL {
        //There you go :)
     }
  }
}

Remember to dismiss the MPMediaPickerController when done with it (and remember to do so when canceling too (there is a delegate method for that too)).

Hope that points you in the right direction.

pbodsk
  • 6,787
  • 3
  • 21
  • 51
  • now the Question is how do I put the assetURL into the AVAudioEngine? AVAudioFile *file = [[AVAudioFile alloc] initForReading:_item.assetURL error:nil]; -> this doesn't working. – Joel Mar 14 '17 at 10:41
  • OK, interesting :) do you get any errors in return? What if you pass it an error object instead of `nil`, just to see if it returns any errors to you. Where do you declare your `AVAudioEngine` instance? It should be as a property on your class (just to make sure). – pbodsk Mar 14 '17 at 11:30
  • yes I have it as a property :) in my mediapicker delegate method there is no item with a assetURL found. Maybe songs from Music Library have no assetURL? – Joel Mar 14 '17 at 12:17
  • Ah...I have a theory now:) . Maybe you are trying to pick/play a song that is not stored locally on your device? `MPMediaPickerController` has a property called `showCloudItems`, could you set that to false/NO so you only see items that actually are on your device. That should guarantee that you have an `assetURL`. – pbodsk Mar 14 '17 at 12:23
  • Thats it! I had forgotten to download a few songs on this testDevice! Yesterday I had used another device where I had downloaded some songs ;) showCloudItems = NO is a good trick to avoid this . Thank you +1 – Joel Mar 14 '17 at 12:30
  • Fantastic! I just remembered the `showCloudItems` property and now I remember that I had the same issue when I was trying to get this to work :) glad you got it working in the end. – pbodsk Mar 14 '17 at 12:33