3

I'm developing an app which makes usage of AVPlayer, MPMediaItem and MPMediaQuery. It works as long as Itunes match. We start with a MPMediaQuery, then we perform some filtering leaving some MPMediaItems, then we have been using AVPlayer because: 1.- we also play noises during the song play 2.- we need to suscribe to play/stops events from ipod.

All this features are currently working, except if the ipod library has itunes match enabled. Even when AVPlayer status is playing, no sound comes. Is obvious that it is not triggering the song download from iCloud.

All the information I have about itunes match by the moment is this post: MPMediaItem and iTunes Match

which states you can trigger the download by using a MPMusicPlayerController play call. For the reasons given above, we cannot make use of this class to control our own player.

I have two ideas on how to solve this problem: A. Find a way to check if a song is already downloaded and available in the library to play using AVPlayer. If the song is not available let the user know that we don't support songs not available. B. Find a way to trigger the download of the song just before it becomes the next item to play.

I still cannot find how to implement any of these solutions and I haven't found any related documentation, so I submitted my app with a warning message to prevent users to use this app if they are using itunes match.

Community
  • 1
  • 1
Mariano Latorre
  • 719
  • 1
  • 10
  • 21

2 Answers2

3

On iOS 6 and up you can use [[item valueForProperty:MPMediaItemPropertyIsCloudItem] boolValue] to check if an item is already downloaded.

voidStern
  • 3,678
  • 1
  • 29
  • 32
  • MPMediaItemPropertyIsCloudItem doesn't verify that it is already downloaded. It just checks if it is an iCloud item. – miho Dec 25 '12 at 09:45
  • 5
    Actually, as soon as an item is downloaded it's a local item, not an iCloud item. So yes, `[item valueForProperty:MPMediaItemPropertyIsCloudItem]` only returns `YES` if the item is not downloaded. – voidStern Dec 26 '12 at 10:33
  • 2
    Erm, you might want to use this instead: [[item valueForProperty:MPMediaItemPropertyIsCloudItem] boolValue] otherwise, I think [item valueForProperty:MPMediaItemPropertyIsCloudItem] only returns an NSNumber wrapped boolean value, which in this case if you go if([item valueForProperty:MPMediaItemPropertyIsCloudItem]) it will say YES all the time even if the song is on the device :D – Zhang Sep 10 '14 at 04:52
2

A. Find a way to check if a song is already downloaded and available in the library to play using AVPlayer. If the song is not available let the user know that we don't support songs not available.

This isn't perfect but it works in most cases. Songs downloaded from iTunes Match will be DRM free. So you can check the assets DRM flags, if it is not exportable then it needs to be downloaded. It is possible to get a false positive with audio books/pod casts but you are mostly safe.

MPMediaItem* item
NSURL* url = [item valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset* assetToLoad = [[AVURLAsset alloc] initWithURL:url options:nil];
bool protectedCon = assetToLoad.hasProtectedContent;
bool exportable = true;

if (gApp.mSysVersionInt >= 5) {
    exportable = assetToLoad.exportable;    //4.3+
}

B. Find a way to trigger the download of the song just before it becomes the next item to play.

You can try doing this will a muted MPMusicPlayerController, but there is no way to track when the song is downloaded and sometimes it takes a very long time.

TurqMage
  • 3,321
  • 2
  • 31
  • 52
  • I hope apple soon releases documentation and API standart methods to handle this features... – Mariano Latorre Feb 16 '12 at 11:05
  • This doesn't differentiate between iTunes Match that aren't on the device and DRMed tracks that are on the device. Both will have a nil asset URL... – awolf Jun 28 '12 at 20:06
  • True but once you know they have iTunes Match, you know it is not DRMed. I don't have a good way of knowing they have iTunes Match. – TurqMage Jun 30 '12 at 04:25