欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

AVAssetResourceLoaderDelegate 代理方法,來看看如何實現(xiàn)

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

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];
}

然后要定義一個下載類,其實就是分段下載數(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ù)器返回數(shù)據(jù) 可能會調(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];
  }
}
//請求完成會調(diào)用該方法,請求失敗則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ù)器返回數(shù)據(jù) 可能會調(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];
  }
}
//請求完成會調(diào)用該方法,請求失敗則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ù)塞進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 邊下邊播的實現(xiàn)代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

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

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

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

    IOS中無限滾動Scrollview效果

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

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

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

    iOS 適配iPhone X的方法

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

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

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

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

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

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

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

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

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

    iOS實現(xiàn)點贊動畫特效

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

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

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

最新評論