亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

iOS 邊下邊播的實(shí)現(xiàn)代碼

 更新時(shí)間:2017年11月13日 11:52:58   投稿:mrr  
在之前項(xiàng)目中使用的是AVPlayer直接播放URL地址,但是不知道是相機(jī)的wifi不夠穩(wěn)定還是代碼的問(wèn)題,app總是出現(xiàn)緩沖卡頓。后來(lái)考慮改成邊下邊播模式,下面小編給大家?guī)?lái)了iOS 邊下邊播的實(shí)現(xiàn)代碼,需要的朋友參考下吧

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

AVAssetResourceLoaderDelegate 代理方法,來(lái)看看如何實(shí)現(xiàn)

首先要實(shí)現(xiàn)兩個(gè)必須的代理方法

AVAssetResourceLoaderDelegateObjective-C
#pragma mark - AVAssetResourceLoaderDelegate
//開(kāi)始加載
- (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
//開(kāi)始加載
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest {
  [self addLoadingRequest:loadingRequest];
  return YES;
}
//取消加載
- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest {
  [self removeLoadingRequest:loadingRequest];
}

然后要定義一個(gè)下載類,其實(shí)就是分段下載數(shù)據(jù)的下載器

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
//服務(wù)器響應(yīng)
- (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];
  }
}
//服務(wù)器返回?cái)?shù)據(jù) 可能會(huì)調(diào)用多次
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
  if (self.cancel) return;
  //SRQLog(@"收到響應(yīng)了: %@",data);
  self.cacheLength += data.length;
  if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidUpdateCache)]) {
    [self.delegate requestTaskDidUpdateCache];
  }
}
//請(qǐng)求完成會(huì)調(diào)用該方法,請(qǐng)求失敗則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
//服務(wù)器響應(yīng)
- (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];
  }
}
//服務(wù)器返回?cái)?shù)據(jù) 可能會(huì)調(diào)用多次
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
  if (self.cancel) return;
  //SRQLog(@"收到響應(yīng)了: %@",data);
  self.cacheLength += data.length;
  if (self.delegate && [self.delegate respondsToSelector:@selector(requestTaskDidUpdateCache)]) {
    [self.delegate requestTaskDidUpdateCache];
  }
}
//請(qǐng)求完成會(huì)調(diào)用該方法,請(qǐng)求失敗則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];
      }
    }
  }
}

最后將拿到的數(shù)據(jù)塞進(jìn)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;
  //讀文件,填充數(shù)據(jù)
  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]];
  //如果完全響應(yīng)了所需要的數(shù)據(jù),則完成
  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;
  //讀文件,填充數(shù)據(jù)
  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]];
  //如果完全響應(yīng)了所需要的數(shù)據(jù),則完成
  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];
}

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

總結(jié)

以上所述是小編給大家介紹的iOS 邊下邊播的實(shí)現(xiàn)代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 學(xué)習(xí)iOS開(kāi)關(guān)按鈕UISwitch控件

    學(xué)習(xí)iOS開(kāi)關(guān)按鈕UISwitch控件

    這篇文章主要為大家詳細(xì)介紹了iOS開(kāi)關(guān)按鈕UISwitch控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • IOS中無(wú)限滾動(dòng)Scrollview效果

    IOS中無(wú)限滾動(dòng)Scrollview效果

    這篇文章主要為大家詳細(xì)介紹了IOS中無(wú)限滾動(dòng)Scrollview效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-02-02
  • iOS 11 AppIcon不顯示問(wèn)題小結(jié)

    iOS 11 AppIcon不顯示問(wèn)題小結(jié)

    小編在更新xcode9后,在運(yùn)行老項(xiàng)目時(shí)遇到iOS 11 AppIcon不顯示問(wèn)題,下面小編大家分享一下我的思路,需要的朋友參考下吧
    2017-10-10
  • iOS 適配iPhone X的方法

    iOS 適配iPhone X的方法

    下面小編就為大家分享一篇iOS 適配iPhone X的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • IOS用AFN發(fā)送字符串形式的Json數(shù)據(jù)給服務(wù)器實(shí)例

    IOS用AFN發(fā)送字符串形式的Json數(shù)據(jù)給服務(wù)器實(shí)例

    本篇文章主要介紹了IOS用AFN發(fā)送字符串形式的Json數(shù)據(jù)給服務(wù)器實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • IOS 開(kāi)發(fā)之UITextField的光標(biāo)操作擴(kuò)展

    IOS 開(kāi)發(fā)之UITextField的光標(biāo)操作擴(kuò)展

    這篇文章主要介紹了IOS 開(kāi)發(fā)之UITextField的光標(biāo)操作擴(kuò)展的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • iOS中修改UITextField占位符字體顏色的方法總結(jié)

    iOS中修改UITextField占位符字體顏色的方法總結(jié)

    這篇文章給大家分享了iOS中修改UITextField占位符字體顏色的三個(gè)方法,分別是使用attributedPlaceholder屬性、重寫drawPlaceholderInRect方法和修改UITextField內(nèi)部placeholderLaber的顏色,下面我們一起來(lái)看看詳細(xì)的方法介紹。
    2016-09-09
  • iOS開(kāi)發(fā)之?dāng)?shù)字每隔3位用逗號(hào)分隔

    iOS開(kāi)發(fā)之?dāng)?shù)字每隔3位用逗號(hào)分隔

    以前在做電商app時(shí)經(jīng)常會(huì)針對(duì)稍大的金額展示出來(lái),需要每隔千位添加逗號(hào)便于用戶識(shí)別,下面通過(guò)本文給大家分享ios中數(shù)字每隔3位用逗號(hào)分隔的實(shí)例代碼,需要的朋友參考下吧
    2017-09-09
  • iOS實(shí)現(xiàn)點(diǎn)贊動(dòng)畫特效

    iOS實(shí)現(xiàn)點(diǎn)贊動(dòng)畫特效

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)點(diǎn)贊動(dòng)畫特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • iOS WKWebView適配實(shí)戰(zhàn)篇

    iOS WKWebView適配實(shí)戰(zhàn)篇

    這篇文章主要介紹了iOS WKWebView適配實(shí)戰(zhàn)篇,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06

最新評(píng)論