iOS获取m3u8文件大小 2种方式 :一种是等待线程 一种是block回调
方法使用
第一种 等待线程
long long size = [TZGetUrlFileLength getUrlFileLength:str];
//size 为0 时地址m3u8有问题,或者 中间ts段请求头 有问题。
第二种 block回调
[TZGetUrlFileLength getUrlFileLength:str withResultBlock:^(long long length, NSError * _Nonnull error) {
NSLog(@"size %lld ,error %@",length,error);
}];
方法展示
第一种 等待线程
/// 通过url (.m3u8)地址 获取文件大小返回byte
/// @param url 地址m3u8类型
+(long long)getUrlFileLength:(NSString *)url;
{
if(url.length == 0 || ![url containsString:@"m3u8"]){
NSLog(@"url 地址不是m3u8 类型");
return 0;
}
NSError *error = nil;
NSString *m3u8DataStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:url] encoding:NSUTF8StringEncoding error:&error];
if ( error ) {
NSLog( @"网络错误, 无法下载! 请检查ATS||URL是否正确:%@",url);
return 0;
}
//获取母地址 准备拼接片段来获取大小
__block NSString* urlStrTemp = [TZGetUrlFileLength getYichuTheLastStr:url];
//设置变量 记录数值
__block long long size_zone = 0;
__block NSError * errorPost = nil;
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSArray<NSString *> *tsDataArr = [m3u8DataStr componentsSeparatedByString:@"\n"];
// 考虑线程安全 加一个
dispatch_semaphore_t signal = dispatch_semaphore_create(1);
for (int i = 0 ; i<tsDataArr.count; i++) {
NSString * strTs = [NSString stringWithFormat:@"%@",tsDataArr[i]];
if ([strTs hasSuffix:@".ts"]) {
// dispatch_async(queue, ^(){
// 拼接ts单片地址
NSString * urlPost = [NSString stringWithFormat:@"%@%@",urlStrTemp,strTs];
// 异步实现同步
dispatch_group_enter(group);
// 线程安全
dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
// 判断是否中间有失败的场景
if (errorPost) {
size_zone = 0;
NSLog(@"任务中断 %@",errorPost);
// 异步实现同步
dispatch_group_leave(group);
// 线程安全
dispatch_semaphore_signal(signal);
break;
}
//1.创建NSURLSession对象(可以获取单例对象)
NSURLSession *session = [NSURLSession sharedSession];
//2.根据NSURLSession对象创建一个Task
NSURL *url = [NSURL URLWithString:urlPost];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.timeoutInterval = 5.0;
[request setHTTPMethod:@"HEAD"];
// 获取内容头信息
NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) {
if (error) {
errorPost = error;
}
//拿到响应头信息
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
//获取内容大小
NSNumber *length = [[res allHeaderFields] objectForKey:@"Content-Length"];
// 记录总量
size_zone = [length longLongValue] +size_zone;
// NSLog(@"length %lld, longZonetime222 %lld",[length longLongValue],size_zone);
// 异步实现同步
dispatch_group_leave(group);
// 线程安全
dispatch_semaphore_signal(signal);
// //4.解析拿到的响应数据
// NSLog(@"%@\n%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],res.allHeaderFields);
}];
//3.执行Task
//注意:刚创建出来的task默认是挂起状态的,需要调用该方法来启动任务(执行任务)
[dataTask resume];
// NSLog(@"length , longZonetime111 %lld",size_zone);
// });
}
}
// 异步实现同步 等待完成任务返回数值;
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"任务全部结束!longZonetime333 %lld",size_zone);
return size_zone;
}
第二种 block回调
/**
* 通过url获得网络的文件的大小 返回byte
*
* @param url 网络url 地址m3u8类型
*
* 文件的大小 byte
*/
+(void)getUrlFileLength:(NSString *)url withResultBlock:(void(^)(long long length, NSError *error))block;
{
if(url.length == 0 || ![url containsString:@"m3u8"]){
NSLog(@"url 地址不是m3u8 类型");
if (block) {
block(0,nil);
}
return;
}
NSError *error = nil;
NSString *m3u8DataStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:url] encoding:NSUTF8StringEncoding error:&error];
if ( error ) {
NSLog( @"网络错误, 无法下载! 请检查ATS||URL是否正确:%@",url);
if (block) {
block(0,nil);
}
return;
}
//获取母地址 准备拼接片段来获取大小
__block NSString* urlStrTemp = [TZGetUrlFileLength getYichuTheLastStr:url];
//设置变量 记录数值
__block long long size_zone = 0;
__block NSError * errorPost = nil;
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSArray<NSString *> *tsDataArr = [m3u8DataStr componentsSeparatedByString:@"\n"];
// 考虑线程安全 加一个
dispatch_semaphore_t signal = dispatch_semaphore_create(1);
for (int i = 0 ; i<tsDataArr.count; i++) {
NSString * strTs = [NSString stringWithFormat:@"%@",tsDataArr[i]];
if ([strTs hasSuffix:@".ts"]) {
// 拼接ts单片地址
NSString * urlPost = [NSString stringWithFormat:@"%@%@",urlStrTemp,strTs];
// 异步实现同步
dispatch_group_enter(group);
// 线程安全
dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
// 判断是否中间有失败的场景
if (errorPost) {
size_zone = 0;
NSLog(@"任务中断 %@",errorPost);
// 异步实现同步
dispatch_group_leave(group);
// 线程安全
dispatch_semaphore_signal(signal);
break;
}
//1.创建NSURLSession对象(可以获取单例对象)
NSURLSession *session = [NSURLSession sharedSession];
//2.根据NSURLSession对象创建一个Task
NSURL *url = [NSURL URLWithString:urlPost];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.timeoutInterval = 5.0;
[request setHTTPMethod:@"HEAD"];
// 获取内容头信息
NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) {
if (error) {
errorPost = error;
}
//拿到响应头信息
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
//获取内容大小
NSNumber *length = [[res allHeaderFields] objectForKey:@"Content-Length"];
// 记录总量
size_zone = [length longLongValue] +size_zone;
// NSLog(@"length %lld, longZonetime222 %lld",[length longLongValue],size_zone);
// 异步实现同步
dispatch_group_leave(group);
// 线程安全
dispatch_semaphore_signal(signal);
// //4.解析拿到的响应数据
// NSLog(@"%@\n%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],res.allHeaderFields);
}];
//3.执行Task
//注意:刚创建出来的task默认是挂起状态的,需要调用该方法来启动任务(执行任务)
[dataTask resume];
//NSLog(@"length , longZonetime111 %lld",size_zone);
}
}
// NSLog(@"任务全部结束!longZonetime333 %lld",size_zone);
// 异步实现同步 等待完成任务返回数值;
dispatch_group_notify(group, queue, ^{
NSLog(@"任务全部结束!longZonetime");
if (block) {
block(size_zone,errorPost);
}
});
}
补充方法
//获取母地址 准备拼接片段来获取大小
+(NSString *)getYichuTheLastStr:(NSString *)url{
long i_temp = 0;
for (long i =url.length; i > 0; i--) {
NSString * str = [url substringWithRange:NSMakeRange(i-1, 1)];
if ([str isEqualToString:@"/"]) {
i_temp = i;
break;
}
}
//获取母地址 准备拼接片段来获取大小
NSString* urlStrTemp = [url substringToIndex:i_temp];
return urlStrTemp;
}
不知道有没有更好的方法 目前使用比较方法 整理下。