同时下载和播放从多个URL拼凑在一起的歌曲

我有一个NSArray的string是URL。 数组中的每个URL都指向与歌曲的某个部分相关联的数据。 我可以使用下面的代码播放完整的歌曲,它将歌曲完全下载到单个文件,然后从该文件播放:

// Get file path to store song locally NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *filePath = [NSString stringWithFormat:@"%@/temp.mp3", [paths objectAtIndex:0]]; // Remove current temp file and create a new one NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error; if ([fileManager fileExistsAtPath:filePath]) [fileManager removeItemAtPath:filePath error:&error]; [fileManager createFileAtPath:filePath contents:nil attributes:nil]; NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath]; // Initialize loop variables NSMutableData *songData = nil; NSUInteger totalLength = 0; NSString *localURLString = [NSString stringWithFormat:@"file://%@", [filePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSURL *localURL = [NSURL URLWithString:localURLString]; for (NSString *stringURL in urls) { NSURL *url = [NSURL URLWithString:stringURL]; songData = [NSMutableData dataWithContentsOfURL:url]; totalLength += songData.length; [fileHandle writeData:songData]; [fileHandle synchronizeFile]; } [fileHandle closeFile]; self.player = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithURL:localURL]]; [self.player play]; 

现在我试图让整首歌无缝地播放,而不用先下载整个歌曲(所以基本上是以stream的方式播放,而不是从一个urlstream式传输,而是在stream式播放时将多首歌曲拼凑在一起)。

我有什么select?

更新1:

我试图生成清单文件,写入文件没有错误,并且manifestString似乎是正确的格式,但玩家不玩。

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *manifestPath = [NSString stringWithFormat:@"%@/manifest.m3u8", [paths objectAtIndex:0]]; NSMutableString *manifestString = [[NSMutableString alloc] init]; [manifestString appendString:@"#EXTM3\n"]; for (NSString *stringURL in urls) { [manifestString appendFormat:@"%@\n", stringURL]; } [manifestString appendString:@"#EXT-X-ENDLIST"]; NSError *err = nil; [manifestString writeToFile:manifestPath atomically:YES encoding:NSUTF8StringEncoding error:&err]; if (err) { NSLog(@"error writing manifest: %@", err); } NSString *manifestURLString = [NSString stringWithFormat:@"file://%@", [filePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSURL *manifestURL = [NSURL URLWithString:manifestURLString]; self.player = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithURL:manifestURL]]; [self.player play]; 

既然你的目标是iOS,你有没有考虑使用HTTP实时stream媒体(HLS)? https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/HTTPStreamingArchitecture/HTTPStreamingArchitecture.html

尽pipe它通常用于video+audio,您可以在服务器上创build一个仅audio清单文件,按顺序列出歌曲的每个片段,AVPlayer将自动为您自动逐张下载。

例如,我拿了一首歌(在一个名为sample.mp3的文件中),并用ffmpeg将它分段以用于HLS:

 ffmpeg -i sample.mp3 -acodec copy -map 0 -f segment -segment_time 5 -segment_list index.m3u8 segment%05d.mp3 

这需要input文件(sample.mp3)并将其分割成5秒的段。 它吐出一个清单文件(在这种情况下index.m3u8):

 #EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-ALLOW-CACHE:YES #EXT-X-TARGETDURATION:6 #EXTINF:5.015511, segment00000.mp3 #EXTINF:4.989389, segment00001.mp3 #EXTINF:5.015511, segment00002.mp3 #EXTINF:4.989389, segment00003.mp3 #EXTINF:5.015511, segment00004.mp3 #EXTINF:4.989378, segment00005.mp3 #EXTINF:4.989389, segment00006.mp3 #EXTINF:5.015511, segment00007.mp3 #EXTINF:4.989389, segment00008.mp3 #EXTINF:5.015511, segment00009.mp3 #EXTINF:4.989389, segment00010.mp3 #EXTINF:4.571433, segment00011.mp3 #EXT-X-ENDLIST 

如果你传递一个URL到清单到AVPlayer,它可以完成剩下的工作。