gpt4 book ai didi

ios - 同时下载和播放从多个 URL 拼凑而成的歌曲

转载 作者:行者123 更新时间:2023-11-29 10:54:14 25 4
gpt4 key购买 nike

我有一个 NSArray 字符串,它们是 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];

现在,我正在尝试让整首歌曲无缝播放,而无需先下载整首歌曲(所以基本上是流式传输,但不是从一个 URL 流式传输,我必须在流式传输时将多个歌曲拼凑在一起)。

我有哪些选择?

更新 1:

我试过生成manifest文件,写入文件没有错误,而且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 Live Streaming (HLS)? https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/HTTPStreamingArchitecture/HTTPStreamingArchitecture.html

虽然它通常用于视频 + 音频,但您可以在服务器上创建一个纯音频 list 文件,按顺序列出歌曲的每个片段,AVPlayer 会自动为您逐段下载。

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

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

这会获取输入文件 (sample.mp3) 并将其拆分为 5 秒的片段。它吐出一个 list 文件(在本例中为 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

如果您将 list 的 URL 传递给 AVPlayer,它可以完成剩下的工作。

关于ios - 同时下载和播放从多个 URL 拼凑而成的歌曲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19102882/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com