iOS 아래 에서 방송 되 는 실현 코드

11956 단어 ios방송 하 다
프로젝트 에 사 용 된 것 은 AVPlayer 가 URL 주 소 를 직접 재생 하 는 것 입 니 다.그러나 카메라 의 와 이 파이 가 안정 적 이지 않 은 지 코드 의 문제 인지 모 르 겠 습 니 다.app 은 항상 버퍼 카드 가 발생 하기 때문에 사 이 드 밑 에 방송 하 는 모드 로 바 꾸 는 것 을 고려 했 습 니 다.많은 자 료 를 찾 아 보 았 는데 대부분 같은 방법 을 사용 하 는 것 을 발 견 했 습 니 다.
AVAssetResourceLoader Delegate 대리 방법,어떻게 실현 되 는 지 살 펴 보 자.
우선 두 가지 필요 한 대리 방법 을 실현 해 야 한다.

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];
      }
    }
  }
}
마지막 으로 받 은 데 이 터 를 AVAsset Resource Loader Delegate 에이전트 에 넣 고 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 에서 아래 에 방송 되 는 실현 코드 입 니 다.여러분 께 도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기