10

I want to get programmatically queue currently played in native Music App. I can use MPMusicPlayerController to get currently playing item but I want to get not only the item but whole playing queue. Is it possible to do it using AVFoundation or any other library?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Martin Pilch
  • 3,245
  • 3
  • 38
  • 61
  • 1
    I'm sure that this is possible. 'Ecoute' in the App Store is somehow programatically retrieving the current queue, and this has nothing to do with managing the queue from within the app. For e.g. completely quit the app, go into the Music app and create a playlist with a few tracks and play it. Then go back into the app onto the now playing screen and tap the clock icon in the top right to see the queue. You'll see that all tracks in that playlist are there in the queue. How did it know which playlist? Are they using undocumented APIs? – sooper Jan 31 '14 at 04:12
  • @sooper I think they're using undocumented APIs. See my answer below. – bugloaf May 02 '14 at 01:21

4 Answers4

7

I'm pretty sure this is not possible through any public API. The Ecoute app that @sooper mentions must be using private APIs. I did a little experiment in the codebase of my own music app. First I used this code to list all the methods in the iPod music player (put #import <objc/runtime.h> at the top):

int i=0;
unsigned int mc = 0;
Method * mlist = class_copyMethodList([MPMusicPlayerController iPodMusicPlayer].class, &mc);
NSLog(@"%d methods for class", mc);
for(i=0;i<mc;i++) {
    NSLog(@"\tMethod no #%d: %s", i, sel_getName(method_getName(mlist[i])));
}
free(mlist);

This turned up some intriguing method names like numberOfItems and nowPlayingItemAtIndex:. So I added this category at the top of the file:

@interface MPMusicPlayerController (Private)

- (NSInteger)numberOfItems;
- (MPMediaItem*)nowPlayingItemAtIndex:(NSInteger)index;

@end

and I ran this code:

NSInteger numberOfItems = [[MPMusicPlayerController iPodMusicPlayer] numberOfItems];
for (NSInteger i = 0; i < numberOfItems; i++) {
    MPMediaItem* mi = [[MPMusicPlayerController iPodMusicPlayer] nowPlayingItemAtIndex:i];
    NSLog(@"%@", [mi valueForProperty:MPMediaItemPropertyTitle]);
}

and sure enough, it printed out the playlist that I had queued up in the Music app!

Of course, if you call these methods this way, Apple will reject your app, but there's a way to hide private API calls from Apple.

Community
  • 1
  • 1
bugloaf
  • 2,890
  • 3
  • 30
  • 49
  • Thanks for the answer, it seems that the functionality has been removed from the app in question since I last commented. – sooper May 10 '14 at 21:53
  • This no longer works as of iOS 12.2. I'm getting an error: "No media item for index: 10142980306396550453" despite the fact that I passed in an index of 3, not 10142980306396550453. – jjjjjjjj Mar 28 '19 at 10:10
  • @joey Did you do any more testing? I have begun designing new app but it would be useless without that functionality – Adam Apr 25 '19 at 08:44
  • never could figure it out. My suggestion would be to not build the app if it 100% relies on this functionality. – jjjjjjjj Apr 26 '19 at 05:44
3

if you can to use Apple private api. this should be best.

let player = MPMusicPlayerController.systemMusicPlayer
let items = (player.value(forKey: "queueAsQuery") as! MPMediaQuery).items
//[MPMediaItem]?
  • this works only once you have actually set the queue yourself. Also, it only works for local MPMediaItems, not for playback of Apple Music songs. Given that you can already manage the queue yourself manually, while this does work, its restrictions kinda make it useless. – jjjjjjjj Feb 16 '19 at 04:12
2

I'm afraid this is not possible. Apple does not give us access to this information from any libraries.

amergin
  • 3,106
  • 32
  • 44
-2

I've been looking into this and suddenly realized how simple it is!

- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection

mediaItemCollection is the current playlist!

hope this helps.

nmc
  • 8,724
  • 5
  • 36
  • 68
  • This is incorrect. mediaItemCollection is a MPMediaItemCollection generated by the selection in the MPMediaPickerController. This is a new list of songs generated on the spot and has nothing to do with the currently playing tracks in the iPod app. – Mick MacCallum Sep 26 '12 at 04:49
  • @0x7fffffff just wanted to ask if you had any thoughts on my comment posted to the OP? – sooper Mar 18 '14 at 03:00