iOS 아래 에서 방송 되 는 실현 코드
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 에서 아래 에 방송 되 는 실현 코드 입 니 다.여러분 께 도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Swift의 패스트 패스Objective-C를 대체하기 위해 만들어졌지만 Xcode는 Objective-C 런타임 라이브러리를 사용하기 때문에 Swift와 함께 C, C++ 및 Objective-C를 컴파일할 수 있습니다. Xcode는 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.