AVPlayer无法从音乐库播放

5
我正在尝试使用AVPlayer从我的iPhone音乐库播放歌曲。一切似乎都准备就绪,但是播放器根本没有发出任何声音。我已经苦苦挣扎了一段时间,非常感谢任何帮助!
注意:我意识到我可以使用AVAudioPlayer,但我想直接从我的音乐库中读取文件,并且据我所知,AVAudioPlayer不支持这样做(我必须先导出歌曲,这需要更多时间)。我不能使用MPMusicPlayerController,因为最终目标是将歌曲转换为NSData并在另一个设备上播放。
最重要的是,我想知道为什么这段代码没有播放:
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");
}];

在我调用播放方法后,输出为“准备播放”,并且AVPlayer的“rate”属性为1.0。 MPMediaItem存在,并且我可以使用"valueForProperty"方法获取正确的标题、艺术家等信息。有任何想法为什么没有声音从播放器中传出吗?


1
你尝试在块之外声明AVPlayer和AVPlayerItem吗?就像在NSArray *keyArray之后立即声明。 - meggar
我试过了。在外部声明和初始化它们并没有什么区别。在外部声明并在处理程序内初始化似乎是被禁止的。不过还是谢谢你的建议! - JohnG
2个回答

12

找到可行的解决方案:

  1. 我把AVPlayer设置为属性(感谢meggar的提示!)
  2. 在使用initWithAsset方法之前,我确保AVPlayer为nil。

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

希望这能帮助到有需要的人!


1

另一个原因是配置 AVAudioSession。这对我很有效。

 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
  [[AVAudioSession sharedInstance] setActive: YES error: nil];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接