Can't play music from a document catalog through AVPlayer in iOS?

I select a music file using MediaPickerController . After selecting a music file from the picker, I save the file in the document directory.

Below is the code for selecting and saving in the document catalog

//code to click on music button - (IBAction)addMusic:(id)sender { MPMediaPickerController *soundPicker=[[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeMusic]; soundPicker.delegate=self; soundPicker.allowsPickingMultipleItems=NO; [self presentViewController:soundPicker animated:YES completion:nil]; } - (void)mediaPicker: (MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection { NSLog(@"music files delegate called"); MPMediaItem *item = [[mediaItemCollection items] objectAtIndex:0]; [self uploadMusicFile:item]; [self dismissViewControllerAnimated:YES completion:nil]; } - (void) uploadMusicFile:(MPMediaItem *)song { NSURL *url = [song valueForProperty: MPMediaItemPropertyAssetURL]; AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL: url options:nil]; AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset presetName:AVAssetExportPresetAppleM4A]; exporter.outputFileType = @"com.apple.m4a-audio"; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString * myDocumentsDirectory = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; [[NSDate date] timeIntervalSince1970]; NSTimeInterval seconds = [[NSDate date] timeIntervalSince1970]; NSString *intervalSeconds = [NSString stringWithFormat:@"%0.0f",seconds]; NSString * fileName = [NSString stringWithFormat:@"%@.mp4",intervalSeconds]; NSString *exportFile = [myDocumentsDirectory stringByAppendingPathComponent:fileName]; NSURL *exportURL = [NSURL fileURLWithPath:exportFile]; exporter.outputURL = exportURL; // do the export // (completion handler block omitted) [exporter exportAsynchronouslyWithCompletionHandler: ^{ int exportStatus = exporter.status; switch (exportStatus) { case AVAssetExportSessionStatusFailed: { NSError *exportError = exporter.error; NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError); break; } case AVAssetExportSessionStatusCompleted: { NSLog (@"AVAssetExportSessionStatusCompleted"); //music data is NSdata music_data = [NSData dataWithContentsOfFile: [myDocumentsDirectory stringByAppendingPathComponent:fileName]]; // NSLog(@"Data %@",data); // data = nil; break; } case AVAssetExportSessionStatusUnknown: { NSLog (@"AVAssetExportSessionStatusUnknown"); break; } case AVAssetExportSessionStatusExporting: { NSLog (@"AVAssetExportSessionStatusExporting"); break; } case AVAssetExportSessionStatusCancelled: { NSLog (@"AVAssetExportSessionStatusCancelled"); break; } case AVAssetExportSessionStatusWaiting: { NSLog (@"AVAssetExportSessionStatusWaiting"); break; } default: { NSLog (@"didn't get export status"); break; } } }]; } 

Code for playing a music file from a document directory

 - (void)musicPlay:(UIGestureRecognizer *)recognizer { if(!isMusicPlaying) { if([musicFile isEqualToString:@"none"]) { NSLog(@"INSIDE IF"); UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"Warning" message:@"No music exist" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; } else { NSURL *fileURL; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; bc.music_upload=[bc.music_upload lastPathComponent]; NSLog(@"music uplaod is %@",bc.music_upload); NSString* path = [documentsDirectory stringByAppendingPathComponent:bc.music_upload]; BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path]; if(fileExists) { NSLog(@"file already exist"); fileURL = [NSURL fileURLWithPath:path]; NSLog(@"file url is %@",fileURL); } else { NSLog(@"file already not exist"); if(![musicFile containsString:@"http://"]) { musicFile=[IMAGE_BASE_URL stringByAppendingString:musicFile]; } fileURL = [NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:musicFile]]; } NSLog(@"file url is %@",fileURL); isMusicPlaying=true; [self.img_music setImage:[UIImage imageNamed:@"play_stop.png"]]; playerItem = [AVPlayerItem playerItemWithURL:fileURL]; player = [AVPlayer playerWithPlayerItem:playerItem]; //player = [AVPlayer playerWithURL:path]; [player play]; } } else { isMusicPlaying=false; [player pause]; [self.img_music setImage:[UIImage imageNamed:@"music-icon.png"]]; } } 

I can save the file, and when I check if the file exists in the document directory, then I can find the file. But I can not play the file. I did not understand what the problem was. Is there a problem with the music file or code of my music player? ' EDIT: I tried this code, but it causes the application to freeze and not respond.

 NSURL *url = [NSURL URLWithString:@"http://sound18.mp3pk.com/pop_remix/ebodf11/ebodf11-15(www.songs.pk).mp3"]; NSData *data = [NSData dataWithContentsOfURL:url]; AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil]; [audioPlayer play]; 

EDIT:

I think the problem is converting MPMediaItem to NSdata strong>. Therefore, when I convert MPMediaItem to NSData , then I can send it to the server, and it plays in the browser. But I'm trying to play with AVPlayer , after which I encounter this problem?

+6
source share
3 answers

From Apple article

As in the case of assets and elements, initialization of the player does not mean its readiness for playback. You should monitor the status of the player who goes into AVPlayerStatusReadyToPlay when he is ready to play. You can also observe the currentItem property to access the player element created for the stream.

Add an observer to the player

 - (void)musicPlay:(UIGestureRecognizer *)recognizer { // your player code [player addObserver:self forKeyPath:@"status" options:0 context:nil]; } // Observe for the player status - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == _player && [keyPath isEqualToString:@"status"]) { if (_player.status == AVPlayerStatusFailed) { NSLog(@"AVPlayer Failed"); } else if (_player.status == AVPlayerStatusReadyToPlay) { NSLog(@"AVPlayerStatusReadyToPlay"); [_player play]; } else if (_player.status == AVPlayerItemStatusUnknown) { NSLog(@"AVPlayer Unknown"); } } } 
+3
source

try the following:

 NSURL *url = [NSURL URLWithString:filePath]; // like file:///... AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; if (asset) { AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset]; AVPlayer *player = [AVPlayer playerWithPlayerItem:item]; [player play]; } 
0
source

Could you make sure that you are importing <AudioToolbox/AudioToolbox.h> .

Also, with ARC, you should have a strong reference to the AVPlayer object. Try declaring one strong property.

 @property (strong, nonatomic) AVPlayer *player; 
0
source

All Articles