我创建了一个方法来解析.m3u8
文件,下载引用的文件,然后重新创建一个新的.m3u8
文件,以便在本地提供以供离线播放。一切都行得通,但也许我误用了NSScaner
或Grand Central Dispatch,因为在我看来这个方法应该快速运行并在GCD中排队下载。但是,该方法需要花费足够的时间来运行(在后台,是的,但是我希望尽快创建新文件,而不是在完成所有内容下载时)。任何人都可以看到我的瓶颈在哪里?提前谢谢。
- (void)beginDownloadAndCreateLocalM3U8FileForLocalPlaybackFromPlaylist:(NSString*)playlist forId:(NSString*)_id withProgressBlock:(void (^)(float))progress withCompletionBlock:(void (^)(id))success
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
@autoreleasepool {
NSString *stringURL = playlist;
NSURL *url = [NSURL URLWithString:stringURL];
NSError *error;
NSString *stringData = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
NSString *foundData;
NSScanner *scanner=[NSScanner scannerWithString:stringData];
NSUInteger counter = 0;
NSMutableString *m3u8 = [NSMutableString new];
[scanner scanUpToString:@"#EXTINF" intoString:&foundData];
[m3u8 appendString:foundData];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if (![self directoryExistsAtAbsolutePath:[NSString stringWithFormat:@"%@/Web", documentsDirectory]]) {
[[NSFileManager defaultManager] createDirectoryAtPath: [NSString stringWithFormat:@"%@/Web", documentsDirectory] withIntermediateDirectories: YES attributes:nil error: &error];
}
if (![self directoryExistsAtAbsolutePath:[NSString stringWithFormat:@"%@/Web/%@", documentsDirectory, _id]]) {
[[NSFileManager defaultManager] createDirectoryAtPath: [NSString stringWithFormat:@"%@/Web/%@", documentsDirectory, _id] withIntermediateDirectories: YES attributes:nil error: &error];
} else {
success([NSString stringWithFormat:@"http://127.0.0.1:12345/%@.m3u8", _id]);
return;
}
while (![scanner isAtEnd]) {
[scanner scanUpToString:@"\n" intoString: &foundData];
if ([foundData hasPrefix:@"#EXTINF:"]) {
[m3u8 appendFormat:@"%@\n", foundData];
} else if ([foundData hasPrefix:@"http:"]) {
NSData *urlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:foundData]];
if ( urlData )
{
NSString *filePath = [NSString stringWithFormat:@"%@/Web/%@/%i.ts", documentsDirectory, _id, counter];
NSString *localURL = [NSString stringWithFormat:@"http://127.0.0.1:12345/%@/%i.ts", _id, counter];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
@autoreleasepool {
[urlData writeToFile:filePath atomically:YES];
}
});
//assemble the m3u8 file here for each entry with the original durations. No need to recalculate.
//NSLog(@"Adding this: %@", filePath);
[m3u8 appendFormat:@"%@\n", localURL];
counter++;
}
}
}
[m3u8 appendString:@"#EXT-X-ENDLIST"];
[m3u8 writeToFile:[NSString stringWithFormat:@"%@/Web/%@.m3u8", documentsDirectory, _id] atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSLog(@"Final m3u8 is %@", m3u8);
success([NSString stringWithFormat:@"http://127.0.0.1:12345/%@.m3u8", _id]);
}
});
}
答案 0 :(得分:2)
这一行
NSData *urlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:foundData]];
...在您的while
循环中与您的扫描仪同步运行,您的扫描仪无法前进到下一个令牌,直到下载的URL已下载。尝试提升低优先级dispatch_async()以涵盖else
案例的所有逻辑,而不仅仅是writeToFile:
调用。