Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVPlayer not playing from music library

I am trying to play a song from my iPhone music library using AVPlayer. Everything seems ready to play, but the player simply won't make any sound. I've been struggling with this for a while, any help would be greatly appreciated!

Note: I realize I could use AVAudioPlayer, but I would like to read the file right from my music library and, to my understanding, AVAudioPlayer doesn't support that (I would have to export the song first, taking up more time). I cannot use MPMusicPlayerController because the end goal is to turn the song into NSData and play it on another device.

Above all, I would like to know WHY this code isn't playing:

NSArray *itemsFromQuery = [[MPMediaQuery songsQuery] items];
MPMediaItem *song = [itemsFromQuery objectAtIndex:29];
NSURL *songURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
AVURLAsset *urlAsset = [[AVURLAsset alloc] initWithURL:songURL options:nil];

NSArray *keyArray = [[NSArray alloc] initWithObjects:@"tracks", nil];

[urlAsset loadValuesAsynchronouslyForKeys:keyArray completionHandler:^{

    AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:urlAsset];

    AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];

    while (true) {
        if (player.status == AVPlayerStatusReadyToPlay && playerItem.status == AVPlayerItemStatusReadyToPlay) {
            break;
        }
    }

    if (player.status == AVPlayerStatusReadyToPlay && playerItem.status == AVPlayerItemStatusReadyToPlay) {
        NSLog(@"Ready to play");
        [player play];
    }
    else 
        NSLog(@"Not ready to play");
}];

The output is "Ready to play", and the "rate" property of the AVPlayer is 1.0 after I call the play method. The MPMediaItem exists, and I can use the valueForProperty method to obtain the correct title, artist, etc. Any ideas why no sound is coming from the player?

like image 564
JohnG Avatar asked Jun 19 '12 14:06

JohnG


2 Answers

Found something that worked:

  1. I made the AVPlayer a property (thanks for the tip meggar!)
  2. I made sure the AVPlayer was nil before using the initWithAsset method.

    NSArray *itemsFromQuery = [[MPMediaQuery songsQuery] items];
    MPMediaItem *song = [itemsFromQuery objectAtIndex:0];
    NSURL *songURL = [song valueForProperty:MPMediaItemPropertyAssetURL];
    AVURLAsset *urlAsset = [[AVURLAsset alloc] initWithURL:songURL options:nil];
    
    NSArray *keyArray = [[NSArray alloc] initWithObjects:@"tracks", nil];
    
    [urlAsset loadValuesAsynchronouslyForKeys:keyArray completionHandler:^{
    
        AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:urlAsset];
    
        player = nil;
        player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
    
        while (true) {
            if (player.status == AVPlayerStatusReadyToPlay && playerItem.status == AVPlayerItemStatusReadyToPlay)
                break;
        }
    
        [player play];
    
    }];
    

Hope this helps someone out!

like image 88
JohnG Avatar answered Nov 05 '22 01:11

JohnG


Another reason is configuring AVAudioSession. Worked for me.

 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
  [[AVAudioSession sharedInstance] setActive: YES error: nil];
like image 1
Vlad Soroka Avatar answered Nov 04 '22 23:11

Vlad Soroka