无法通过iOS中的AVPlayer从文档目录中播放音乐?

我正在使用MediaPickerController挑选音乐文件。当我从拾音器中select音乐文件后,我将文件保存到文档目录。

以下是select和保存到文档目录的代码

//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; } } }]; } 

从文档目录播放音乐文件的代码

 - (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"]]; } } 

我能够保存文件,当我检查文件目录中是否存在文件,然后我能够find该文件。但我无法播放该文件。我不明白是什么问题。音乐文件或与我的音乐播放器代码? 编辑:我已经试过这个代码,但它是使应用程序挂起和无响应。

 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]; 

编辑:

我认为问题是与MPMediaItem转换成NSdata 。因为当我将MPMediaItem转换为NSData,然后我能够发送它的服务器和它在浏览器上播放。但我试图玩AVPlayer,然后我面临这个问题?

从苹果的文章

与资产和项目一样,初始化播放器并不意味着它已准备好播放。 您应该观察播放器的状态属性,该属性在准备播放时更改为AVPlayerStatusReadyToPlay。 您还可以观察currentItem属性以访问为该stream创build的播放器项目。

将观察者添加到您的播放器

 - (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"); } } } 

尝试这个:

 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]; } 

你可以确保你正在导入<AudioToolbox/AudioToolbox.h>

而且,在ARC中,你必须对AVPlayer对象进行强有力的引用。 请尝试声明一个强大的财产。

 @property (strong, nonatomic) AVPlayer *player;