亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS 邊下邊播的實現代碼

2020-07-26 02:37:40
字體:
來源:轉載
供稿:網友

項目中之前使用的是AVPlayer直接播放URL地址,但是不知道是相機的wifi不夠穩定還是代碼的問題,app總是出現緩沖卡頓,就考慮改寫成邊下邊播的模式,查過了許多資料,發現大部分都是用的同一種方法

AVAssetResourceLoaderDelegate 代理方法,來看看如何實現

首先要實現兩個必須的代理方法

AVAssetResourceLoaderDelegateObjective-C#pragma mark - AVAssetResourceLoaderDelegate//開始加載- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {  [self addLoadingRequest:loadingRequest];  return YES;}//取消加載- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest {  [self removeLoadingRequest:loadingRequest];}#pragma mark - AVAssetResourceLoaderDelegate//開始加載- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {  [self addLoadingRequest:loadingRequest];  return YES;}//取消加載- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest {  [self removeLoadingRequest:loadingRequest];}

然后要定義一個下載類,其實就是分段下載數據的下載器

AVAssetResourceLoaderDelegateObjective-C- (void)start {  NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[self.requestURL originalSchemeURL] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:RequestTimeout];  if (self.requestOffset > 0) {    [request addValue:[NSString stringWithFormat:@"bytes=%ld-%ld", self.requestOffset, self.fileLength - 1] forHTTPHeaderField:@"Range"];  }  self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];  self.task = [self.session dataTaskWithRequest:request];  [self.task resume];}#pragma mark - NSURLSessionDataDelegate//服務器響應- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {  if (self.cancel) return;  SRQLog(@"response: %@",response);  completionHandler(NSURLSessionResponseAllow);  NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;  NSString * contentRange = [[httpResponse allHeaderFields] objectForKey:@"Content-Range"];  NSString * fileLength = [[contentRange componentsSeparatedByString:@"/"] lastObject];  self.fileLength = fileLength.integerValue > 0 ? fileLength.integerValue : response.expectedContentLength;  if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidReceiveResponse)]) {    [self.delegate requestTaskDidReceiveResponse];  }}//服務器返回數據 可能會調用多次- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {  if (self.cancel) return;  //SRQLog(@"收到響應了: %@",data);  self.cacheLength += data.length;  if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidUpdateCache)]) {    [self.delegate requestTaskDidUpdateCache];  }}//請求完成會調用該方法,請求失敗則error有值- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {  if (self.cancel) {    SRQLog(@"下載取消");  }else {    if (error) {      if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidFailWithError:)]) {        [self.delegate requestTaskDidFailWithError:error];      }    }else {      //可以緩存則保存文件      if (self.cache) {        [FileHandle cacheTempFileWithFileName:[NSString fileNameWithURL:self.requestURL]];      }      if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidFinishLoadingWithCache:)]) {        [self.delegate requestTaskDidFinishLoadingWithCache:self.cache];      }    }  }}- (void)start {  NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[self.requestURL originalSchemeURL] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:RequestTimeout];  if (self.requestOffset > 0) {    [request addValue:[NSString stringWithFormat:@"bytes=%ld-%ld", self.requestOffset, self.fileLength - 1] forHTTPHeaderField:@"Range"];  }  self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];  self.task = [self.session dataTaskWithRequest:request];  [self.task resume];}#pragma mark - NSURLSessionDataDelegate//服務器響應- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {  if (self.cancel) return;  SRQLog(@"response: %@",response);  completionHandler(NSURLSessionResponseAllow);  NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;  NSString * contentRange = [[httpResponse allHeaderFields] objectForKey:@"Content-Range"];  NSString * fileLength = [[contentRange componentsSeparatedByString:@"/"] lastObject];  self.fileLength = fileLength.integerValue > 0 ? fileLength.integerValue : response.expectedContentLength;  if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidReceiveResponse)]) {    [self.delegate requestTaskDidReceiveResponse];  }}//服務器返回數據 可能會調用多次- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {  if (self.cancel) return;  //SRQLog(@"收到響應了: %@",data);  self.cacheLength += data.length;  if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidUpdateCache)]) {    [self.delegate requestTaskDidUpdateCache];  }}//請求完成會調用該方法,請求失敗則error有值- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {  if (self.cancel) {    SRQLog(@"下載取消");  }else {    if (error) {      if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidFailWithError:)]) {        [self.delegate requestTaskDidFailWithError:error];      }    }else {      //可以緩存則保存文件      if (self.cache) {        [FileHandle cacheTempFileWithFileName:[NSString fileNameWithURL:self.requestURL]];      }      if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidFinishLoadingWithCache:)]) {        [self.delegate requestTaskDidFinishLoadingWithCache:self.cache];      }    }  }}

最后將拿到的數據塞進AVAssetResourceLoaderDelegate代理中,交還給AVPlayer,就可以播放了

AVAssetResourceLoaderDelegateObjective-C- (BOOL)finishLoadingWithLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest {  //填充信息  CFStringRef contentType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)(MimeType), NULL);  loadingRequest.contentInformationRequest.contentType = CFBridgingRelease(contentType);  loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;  loadingRequest.contentInformationRequest.contentLength = self.requestTask.fileLength;  //讀文件,填充數據  NSUInteger cacheLength = self.requestTask.cacheLength;  NSUInteger requestedOffset = loadingRequest.dataRequest.requestedOffset;  if (loadingRequest.dataRequest.currentOffset != 0) {    requestedOffset = loadingRequest.dataRequest.currentOffset;  }  NSUInteger canReadLength = cacheLength - (requestedOffset - self.requestTask.requestOffset);  NSUInteger respondLength = MIN(canReadLength, loadingRequest.dataRequest.requestedLength);  //SRQLog(@"好不容易填充一次");  [loadingRequest.dataRequest respondWithData:[FileHandle readTempFileDataWithOffset:requestedOffset - self.requestTask.requestOffset length:respondLength]];  //如果完全響應了所需要的數據,則完成  NSUInteger nowendOffset = requestedOffset + canReadLength;  NSUInteger reqEndOffset = loadingRequest.dataRequest.requestedOffset + loadingRequest.dataRequest.requestedLength;  if (nowendOffset >= reqEndOffset) {    [loadingRequest finishLoading];    return YES;  }  return NO;}- (void)player{    self.resouerLoader     = [[ResourceLoader alloc] init];    self.asset = [AVURLAsset URLAssetWithURL:[self.videoUrl customSchemeURL] options:nil];    [self.asset.resourceLoader setDelegate:self.resouerLoader queue:dispatch_get_main_queue()];    _playerItem = [AVPlayerItem playerItemWithAsset:self.asset];    _players = [AVPlayer playerWithPlayerItem:_playerItem];}- (BOOL)finishLoadingWithLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest {  //填充信息  CFStringRef contentType = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)(MimeType), NULL);  loadingRequest.contentInformationRequest.contentType = CFBridgingRelease(contentType);  loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;  loadingRequest.contentInformationRequest.contentLength = self.requestTask.fileLength;  //讀文件,填充數據  NSUInteger cacheLength = self.requestTask.cacheLength;  NSUInteger requestedOffset = loadingRequest.dataRequest.requestedOffset;  if (loadingRequest.dataRequest.currentOffset != 0) {    requestedOffset = loadingRequest.dataRequest.currentOffset;  }  NSUInteger canReadLength = cacheLength - (requestedOffset - self.requestTask.requestOffset);  NSUInteger respondLength = MIN(canReadLength, loadingRequest.dataRequest.requestedLength);  //SRQLog(@"好不容易填充一次");  [loadingRequest.dataRequest respondWithData:[FileHandle readTempFileDataWithOffset:requestedOffset - self.requestTask.requestOffset length:respondLength]];  //如果完全響應了所需要的數據,則完成  NSUInteger nowendOffset = requestedOffset + canReadLength;  NSUInteger reqEndOffset = loadingRequest.dataRequest.requestedOffset + loadingRequest.dataRequest.requestedLength;  if (nowendOffset >= reqEndOffset) {    [loadingRequest finishLoading];    return YES;  }  return NO;}- (void)player{    self.resouerLoader     = [[ResourceLoader alloc] init];    self.asset = [AVURLAsset URLAssetWithURL:[self.videoUrl customSchemeURL] options:nil];    [self.asset.resourceLoader setDelegate:self.resouerLoader queue:dispatch_get_main_queue()];    _playerItem = [AVPlayerItem playerItemWithAsset:self.asset];    _players = [AVPlayer playerWithPlayerItem:_playerItem];}

注意:此方法服務器端最好支持Range頭,這樣才是分段下載。

總結

以上所述是小編給大家介紹的iOS 邊下邊播的實現代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲第一网站免费视频| 日韩av在线天堂网| 久久综合伊人77777蜜臀| 久久久成人精品视频| 国产亚洲精品美女久久久久| 欧美日韩精品中文字幕| 91精品中国老女人| 美女视频黄免费的亚洲男人天堂| 亚洲字幕一区二区| 欧美老妇交乱视频| 免费91麻豆精品国产自产在线观看| 欧美一级片在线播放| 亚洲精品久久久久久下一站| 久久综合国产精品台湾中文娱乐网| 欧美日韩视频在线| 久久福利网址导航| 日韩美女中文字幕| 97国产真实伦对白精彩视频8| 日韩免费av一区二区| 欧洲成人在线视频| 国产一区二区三区在线观看网站| 精品久久久国产| 日韩av电影中文字幕| 欧美精品videosex极品1| 欧美成人免费全部| 亚洲欧洲一区二区三区久久| 欧美激情日韩图片| 日韩av黄色在线观看| 日韩一区二区欧美| 91av免费观看91av精品在线| 亚洲综合精品一区二区| 欧美另类老肥妇| 91精品视频在线播放| 久久久999成人| 午夜精品一区二区三区在线| 精品欧美国产一区二区三区| 久久精品视频亚洲| 欧美一级淫片丝袜脚交| 91在线播放国产| 国产乱肥老妇国产一区二| 亚洲色图在线观看| 久久久久久这里只有精品| 日韩美女视频中文字幕| 欧美日韩性生活视频| 亚洲天堂成人在线| 国产在线久久久| 亚洲精品成人久久电影| 啊v视频在线一区二区三区| 91免费的视频在线播放| 亚洲va码欧洲m码| 国产精品久久久久久亚洲影视| 国产精品r级在线| 伊人久久精品视频| 日韩中文字幕亚洲| 国内精品久久久久影院 日本资源| 亚洲欧美精品伊人久久| 精品久久在线播放| 最近2019年好看中文字幕视频| 国产欧美中文字幕| 亚洲午夜性刺激影院| 欧美日韩一区二区免费在线观看| 成人免费xxxxx在线观看| 久久精品国产91精品亚洲| 中文字幕av日韩| 91精品久久久久久久久中文字幕| 黄网动漫久久久| 欧美日韩激情视频8区| 青草成人免费视频| 亚洲最大中文字幕| 91国产精品视频在线| 欧美成人激情视频免费观看| 国内伊人久久久久久网站视频| 九九热这里只有精品6| 久久久久久久久久久人体| 国产亚洲欧美日韩精品| 久久久久久久久久久91| 亚洲免费av电影| 国产精品精品久久久| 国产免费一区二区三区香蕉精| 亚洲欧美制服中文字幕| 久久韩剧网电视剧| 亚洲自拍小视频免费观看| 精品国产91久久久久久| 国产精品久久久久久亚洲影视| 亚洲国产美女久久久久| 亚洲精品美女久久久久| 日韩av影片在线观看| 久久久久成人网| 欧美激情亚洲综合一区| 麻豆一区二区在线观看| 久久久久久美女| 精品福利樱桃av导航| 日韩专区中文字幕| 国产精品久久一| 精品国产乱码久久久久久天美| 亚洲国产小视频在线观看| 亚洲r级在线观看| 欧美日韩性生活视频| 欧美日韩美女在线| 国产成人涩涩涩视频在线观看| 夜夜嗨av一区二区三区四区| 亚洲高清色综合| 在线播放日韩欧美| 成人自拍性视频| 亚洲欧美日韩天堂| 亚洲欧美日韩国产成人| 亚洲欧洲一区二区三区在线观看| 国产精自产拍久久久久久| 在线视频日本亚洲性| 色综合色综合网色综合| 欧美日韩亚洲视频| 91日本在线观看| 久久艹在线视频| 欧美电影在线观看完整版| 日韩中文字幕国产精品| 欧美日韩国产精品一区二区三区四区| 91精品美女在线| 国内免费精品永久在线视频| 精品视频中文字幕| 久久久伊人欧美| 57pao成人永久免费视频| 国产色婷婷国产综合在线理论片a| www.久久久久| 另类色图亚洲色图| 欧美大成色www永久网站婷| 亚洲美女av网站| 亚洲成人a**站| 国产美女精品视频| 久久综合伊人77777| 亚洲欧美日本伦理| 欧美亚洲免费电影| 91精品国产91久久久久久不卡| 国产精品久久久久久久久| 日韩国产在线播放| 欧美高清理论片| 亚洲激情电影中文字幕| 久久久久久久久久久成人| 色哟哟入口国产精品| 亚洲二区在线播放视频| 久久久久久久久久国产| 日韩精品视频免费在线观看| 在线观看精品国产视频| 91精品久久久久久久久青青| 欧美在线影院在线视频| 欧美国产日本高清在线| 97超视频免费观看| 国产有码在线一区二区视频| 日韩亚洲精品电影| 亚洲老板91色精品久久| 日韩av免费在线播放| 日韩的一区二区| 疯狂做受xxxx高潮欧美日本| 日韩欧美综合在线视频| 久久综合免费视频| 成人免费网站在线观看| 精品久久久久久久大神国产| 不卡毛片在线看| 国内揄拍国内精品少妇国语| 夜夜嗨av一区二区三区免费区| 国产精品国语对白| 久久久久久久久久久91| 精品电影在线观看| 韩日精品中文字幕| 日本欧美精品在线|