Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/121.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios MP3队列播放器-在后台线程中加载?_Ios_Objective C_Audio_Avplayer_Avqueueplayer - Fatal编程技术网

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

Ios MP3队列播放器-在后台线程中加载?,ios,objective-c,audio,avplayer,avqueueplayer,Ios,Objective C,Audio,Avplayer,Avqueueplayer,我有一个AVQueuePlayer,用于播放来自互联网(http)的MP3歌曲列表。我还需要知道目前正在播放哪首歌。当前的问题是加载歌曲会导致延迟,在等待歌曲加载时会阻塞主线程(第一首歌曲以及第一首歌曲完成播放后的连续歌曲) 以下代码阻止主线程: queuePlayer = [[AVQueuePlayer alloc] init]; [queuePlayer insertItem: [AVPlayerItem playerItemWithURL:url] afterItem: nil]; //

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

以下代码阻止主线程:

queuePlayer = [[AVQueuePlayer alloc] init];
[queuePlayer insertItem: [AVPlayerItem playerItemWithURL:url] afterItem: nil]; // etc.
[queuePlayer play]
我正在寻找一种创建MP3播放列表的方法,其中下一个要播放的文件将在后台预加载。

我尝试了以下代码:

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];
问题是我不确定如何检测下一首歌曲何时开始播放。此外,文档没有指定这是否会预加载MP3文件

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

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

AVFoundation有一些专门设计的类,可以完全满足您的需求

看起来您当前的解决方案是构建一个连接所有要播放的MP3文件的
AVPlayerItem
。更好的解决方案是创建一个
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
    在播放当前项目时,会预加载播放列表中的下一个项目
  • 您可以访问
    currentItem
    属性来确定当前正在播放的
    AVPlayerItem

我也尝试过使用AVQueuePlayer。如果我理解正确,第一个MP3文件不会加载到后台线程中。您建议如何在后台线程中预加载第一个MP3,然后让主线程知道加载完成的时间?