首页 文章

MP3队列播放器 - 加载后台线程?

提问于
浏览
1

我有 AVQueuePlayer 用于播放来自互联网(http)的MP3歌曲列表 . 我还需要知道哪首歌正在播放 . 当前的问题是加载歌曲会导致延迟,在等待歌曲加载时阻塞主线程(第一首歌曲以及第一首歌曲在完成首次播放后的连续歌曲) .

以下代码阻止主线程:

queuePlayer = [[AVQueuePlayer alloc] init];
[queuePlayer insertItem: [AVPlayerItem playerItemWithURL:url] afterItem: nil]; // etc.
[queuePlayer play]

I am looking for a way to create a playlist of MP3s where the next file to be played back is preloaded in the background.

我尝试了以下代码:

NSArray* tracks = [NSArray arrayWithObjects:@"http://example.com/song1.mp3", @"http://example.com/song2.mp3", @"http://example.com/song3.mp3", nil];

for (NSString* trackName in tracks)
{
    AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:[NSURL URLWithString:trackName]
                                                    options:nil];

    AVMutableCompositionTrack* audioTrack = [_composition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                      preferredTrackID:kCMPersistentTrackID_Invalid];

    NSError* error;
    [audioTrack insertTimeRange:CMTimeRangeMake([_composition duration], audioAsset.duration)
                        ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0]
                         atTime:kCMTimeZero
                          error:&error];

    if (error)
    {
        NSLog(@"%@", [error localizedDescription]);
    }

    // Store the track IDs as track name -> track ID
    [_audioMixTrackIDs setValue:[NSNumber numberWithInteger:audioTrack.trackID]
                         forKey:trackName];

}

_player = [[AVPlayer alloc] initWithPlayerItem:playerItem];

[_player play];

这个问题是 I am not sure how to detect when the next song starts playing . 此外,文档未指定是否预先加载MP3文件 .

我正在寻找一个解决方案:

  • 在播放之前通过在后台预先加载MP3来播放MP3(理想情况下,在当前歌曲结束之前开始加载下一首歌曲,以便在当前歌曲结束后立即播放)

  • 允许我查看当前播放的歌曲 .

1 回答

  • 1

    AVFoundation有一些专门用于完成你正在寻找的课程 .

    看起来您当前的解决方案是构建一个 AVPlayerItem ,它连接您想要播放的所有MP3文件 . 更好的解决方案是创建一个 AVQueuePlayer ,其中包含您要播放的 AVPlayerItem 对象数组 .

    NSArray* tracks = [NSArray arrayWithObjects:@"http://example.com/song1.mp3", @"http://example.com/song2.mp3", @"http://example.com/song3.mp3", nil];
    NSMutableArray *playerItems = [[NSMutableArray alloc] init];
    
    for (NSString* trackName in tracks)
    {
        NSURL *assetURL = [NSURL URLWithString:trackName];
        if (!assetURL) {
            continue;
        }
    
        AVURLAsset* audioAsset = [[AVURLAsset alloc] initWithURL:assetURL
                                                         options:nil];
        AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:audioAsset];
        [playerItems addObject:playerItem];
    }
    
    _player = [[AVQueuePlayer alloc] initWithItems:playerItems];
    
    [_player play];
    

    在回答您的最终总结问题时:

    • 是, AVQueuePlayer DOES 在播放当前播放列表时预加载播放列表中的下一个项目 .

    • 您可以访问 currentItem 属性以确定当前正在播放的 AVPlayerItem .

相关问题