国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

iOS之播放器邊下邊播的實例演示

2020-02-19 15:51:34
字體:
來源:轉載
供稿:網友

在開發iOS時,有時候需要一個播放器,并且需要緩存視頻,其實這個時候是邊下邊播,如果數據完整,可以將視頻數據保存到硬盤,那么iOS之播放器邊下邊播的實例演示大家有了解過嗎?下面就讓武林技術頻道小編根據問題逐步分析一下吧!

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

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之播放器邊下邊播的實例演示,希望對你有幫助。如果您有任何問題,請留言,小編會及時回復您。非常感謝您對武林技術頻道的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 灵台县| 壤塘县| 磐石市| 武定县| 宁海县| 金平| 化德县| 洪湖市| 板桥市| 甘肃省| 元朗区| 五寨县| 望都县| 鞍山市| 油尖旺区| 方城县| 阿城市| 三河市| 新源县| 枣阳市| 凉城县| 淄博市| 若羌县| 彭泽县| 蓬安县| 柞水县| 科技| 静安区| 吉安市| 灵武市| 连山| 原阳县| 丹阳市| 土默特右旗| 汉川市| 迭部县| 海门市| 新蔡县| 梅州市| 冕宁县| 鲁山县|