iTunes Match + AVplayer + MPMediaQuery not working - itunes

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.

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

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.

Related

How to pass the MediaLibrary to the AudioService and start playing from specific song in flutter

I have all the UI and logic to read songs from the device and I made my own loagic for playlists because android 10 has a bug. Anyways, so I'm looking on the audio_service package. The example has it all, but the Media library is hardcoded. Despite the name I can imagine this as Playlist with a list of songs.
How can I pass the playlist chosen to play. Maybe Shared preferences?
And another question: Is there a way from which song to start playing the playlist?

UIVideoAtPathIsCompatibleWithSavedPhotosAlbum returns false when deploying on the iPhone

One of my app's features is to download a mp4 file and store it to the local phone album.
I have tried several approaches since and the result is always the same, it worked on the simulator but not on the actual iPhone. Xcode is version 5.0.1, iPhone 4.
Below is the code I applied on the last attempt before posted here using ASIHttpRequest library and the result is still the same, it worked on the simulator but not the phone itself.
download:
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url]; // url is the address to the mp4 file
NSString* filePath = [NSString stringWithFormat:#"%#%#", NSTemporaryDirectory(), filename]; //filename is the file I save to, e.g. xxx.mp4
[request setDownloadDestinationPath:filePath];
[request setDelegate:self];
[request setDidFinishSelector:#selector[ASIRequestDone:)];
[request setDidFailSelector:#select[ASIRequestFail:)];
when download is finished, save it to the photo album (in ASIRequestDone delegate)
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(filePath))
{
//comes to here when running in simulators
UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, #selector(video:didFinishSavingWithError:cotextInfo:),nil);
}
else
{
//always comes to here when running on the actual iPhone.
}
I have checked the pathFile it's this
/private/var/mobile/Applications/xxxxxxxxxx/tmp/xxxxx.mp4
which is alright to me. What I am not getting is it works fine when running on Simulator and hence I am stuck not sure what to do next. (I have also checked the permission accessing the the photo albums and yes the app has it).
I also tried to removed the compatible checking and went straight into the method UISaveVideoAtPathToSavedPhotosAlbum, it didn't throw any error on delegate didFinishSavingWithError. however, the video didn't show up on the photo album either, I am guessing it's correct as the phone seems to say that video is not compatible to be shown on the album. Again, my issue is that it does work on the simulator and how do I fix this on the actual iphone, e.g. why it thinks the video is not compatible? is something to do with the mp4 itself or is it something to do during the download step? What could I do next to resolve the issue? (ps. I also have control over the mp4 files, is there a list of mp4 compatibility on the iphone that you know? I am thinking perhaps it's genuine that the file is not compatible on the phone (but on the simulator!?))
Found the answer to my question and I hope it could help out someone who suffers from the same issue. Turns out video resolution is the factor between the simulator and the actual phone when it comes to store video to the gallery; to be specific:
Compatibility checking UIVideoAtPathIsCompatibleWithSavedPhotosAlbum would FAIL on the actual phone but would PASS on the simulator given a sample clip capturrd as 1080p. I came cross this link a week after my post with luck.
"What video formats are compatible with the assets library?"
And I did the experiment similar to that by capturing 720p video clips instead and all files were able to be saved to the gallery. Weird thing is that the actual iphone can play the HLS stream at 1080p; howeve it won't store clips unless they are 720p, not to me anyway. And the misleading bit is that the simulator can actually do 1080p.

Is there any way to access an iTunes library to set an alarm tone?

Is there any way to access an iTunes library to set an alarm tone?
I am building an alarm app. I think we can can use local notifications when my app is in the background, but it can't play music library sounds. So when the app is in foreground, I want to play sounds from the music library and songs from my app bundle as well. How might I achieve this?
You can select the music libray of your device using the MPMusicPlayerController.
For this you need to include the MediaPlayer.framework framework and <MediaPlayer/MediaPlayer.h> header file.
You will get the picked music url using this delegate method (for this you need to add the MPMediaPickerControllerDelegate in #interface) :
- (void)mediaPicker: (MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
}
Refer this tutorial for a detailed description.

AVFoundation Record Video for web playback -- has to download WHOLE file before playback starts

I have an iPad app that records video and sends it to my SaaS application using AVFoundation. My web application then reads the file, and plays it using JWPlayer.
The problem I am having, is that JWPlayer (or any player I have tried) has to download the WHOLE video file before it will play. After doing some reading, I have discovered that the videos recorded from IOS don't have "fast start from internet" enabled. Or something along those lines.
I am using AVFoundation. Is there a different way to save the video so it will stream instantly from my web server? What am I missing.
The shouldOptimizeForNetworkUse property on AVWriter allows you to do this.
You could use it to rewrite the captured movie file prior to uploading to your server (or immediately post-capture, whatever suits I suppose).
Edit:
Okay, I'm not at a Mac at the moment, but something along these lines:
AVAsset *originalFile = [AVAsset assetWithURL:originalFileURL];
NSURL *outputFileURL = wherever you want to put it;
NSError *readerError;
NSError *writerError;
AVAssetReader *reader = [AVAssetReader assetReaderWithAsset:originalFile error:&readerError];
AVAssetWriter *writer = [AVAssetWriter assetWriterWithURL:outputFileURL fileType:AVFileTypeQuickTimeMovie error:&writerError];
writer.shouldOptimizeForNetworkUse = YES;
[writer startWriting];
...
and so on.

Finding video content in iPhone playlist

Running iOS 4.2.1 I'm able to create a mixed playlist containing both audio and video. 3 items, first a video then 2 audio tracks. I know I'm working with the correct playlist.
However, cycling through the items like this...
for (MPMediaItem *mediaItem in [playlist items]) {
NSLog(#"%#",mediaItem);
NSLog(#"path %#",[mediaItem valueForProperty:MPMediaItemPropertyAssetURL]);
}
...returns me output of...
<MPConcreteMediaItem: 0x1303d0> 9016712715169871401
path ipod-library://item/item.mp3?id=9016712715169871401
<MPConcreteMediaItem: 0x12e9e0> 9016712715169871401
path ipod-library://item/item.mp3?id=9016712715169871401
...so my video asset is being excluded from the playlist. The iPhone plays the playlist correctly when I'm using it as an iPod.
I've gotten as far as I have using Ole Begemann's sample code from here. Does anyone know if video assets are supposed to be excluded? Is there another approach which would combine audio and video assets, assuming they're mixed in a playlist which I know the name of?