【问题标题】:unable to play music from document directory through AVPlayer in iOS?无法通过 iOS 中的 AVPlayer 播放文档目录中的音乐?
【发布时间】:2015-09-15 04:53:22
【问题描述】:

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

以下是选择并保存到文档目录的代码

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

我可以保存文件,当我检查文件目录中是否存在文件时,我可以找到该文件。但我无法播放该文件。我不明白问题出在哪里。是音乐文件或我的音乐播放器代码有问题? ' 编辑: 我已尝试过此代码,但它使应用程序挂起且无响应。

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 玩然后我遇到了这个问题?

【问题讨论】:

    标签: ios objective-c iphone avplayer


    【解决方案1】:

    来自Apple article

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

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

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

    【讨论】:

      【解决方案2】:

      试试这个:

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

      【讨论】:

      • 它不起作用。我正在通过将文件转换为 NSData 将文件上传到服务器。
      • 当我选择将转换为 nsdata 的项目时,请查看我的代码。然后我将其上传到服务器。当我提供音乐文件的 url 时就可以了。但是当我在我的应用程序然后它不会播放。但是如果我在我的应用程序中提供任何其他网址,那么我就可以播放音乐。请告诉我为什么会这样
      • url 链接没有帮助。我已经尝试过代码。但仍然是同样的问题@Danilo
      【解决方案3】:

      请确保您导入的是<AudioToolbox/AudioToolbox.h>

      此外,使用 ARC,您必须持有对 AVPlayer 对象的强引用。请尝试声明一个强大的属性。

      @property (strong, nonatomic) AVPlayer *player;
      

      【讨论】:

      • 我正在导入这些:#import #import #import @Abhinav
      • 我明白了。您能否尝试强烈引用“AVPlayer”
      • 看看我可以在浏览器上播放文件,如果我提供一些第三方网址,那么我可以播放文件。但是我上传的文件不能正常工作。@Abhinav
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多