我有一个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文件。
我正在寻找一个解决方案:
答案 0 :(得分: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
。