Last active
May 1, 2019 02:48
-
-
Save flagoworld/969648081b288b445569 to your computer and use it in GitHub Desktop.
AVAssetResourceLoaderDelegate - Stream from server that requires specific auth headers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SNIPIT, use AVPlayer like this (don't forget to add your KVO method) | |
_streamer = [RangeStreamer new]; | |
AVURLAsset *asset = [AVURLAsset assetWithURL:[NSURL URLWithString:@"myscheme://example.com/path/to/protected.mp3"]]; | |
[asset.resourceLoader setDelegate:_streamer queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; | |
_playerItem = [AVPlayerItem playerItemWithAsset:asset]; | |
_player = [[AVPlayer alloc] initWithPlayerItem:_playerItem]; | |
[_player addObserver:self forKeyPath:@"status" options:0 context:nil]; | |
[_playerItem addObserver:self forKeyPath:@"status" options:0 context:nil]; | |
_player.actionAtItemEnd = AVPlayerActionAtItemEndNone; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RangeStreamer.h | |
// iOS Player | |
// | |
// Created by Ryan Layne on 4/2/15. | |
// | |
#import <Foundation/Foundation.h> | |
#import <AVFoundation/AVFoundation.h> | |
@interface RangeStreamer : NSObject <AVAssetResourceLoaderDelegate> | |
@property (atomic) NSInteger currentOffset; | |
@property (atomic) NSInteger chunkSize; | |
@property (atomic) BOOL shouldCancel; | |
@property (atomic) NSInteger contentLength; | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RangeStreamer.m | |
// iOS Player | |
// | |
// Created by Ryan Layne on 4/2/15. | |
// | |
#import "RangeStreamer.h" | |
#import "SNDMecha.h" | |
@implementation RangeStreamer | |
- (id)init | |
{ | |
if(!(self = [super init])) return nil;sms | |
_shouldCancel = NO; | |
_currentOffset = 0; | |
_chunkSize = 8192; | |
_contentLength = 1; | |
return self; | |
} | |
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest | |
{ | |
NSURLRequest *request = loadingRequest.request; | |
AVAssetResourceLoadingDataRequest *dataRequest = loadingRequest.dataRequest; | |
AVAssetResourceLoadingContentInformationRequest *contentRequest = loadingRequest.contentInformationRequest; | |
NSMutableURLRequest* mutableRequest = [request mutableCopy]; | |
mutableRequest.URL = [[NSURL alloc] initWithScheme:@"http" host:mutableRequest.URL.host path:mutableRequest.URL.path]; | |
// Add auth headers | |
[SNDMecha configureRequest:mutableRequest action:mutableRequest.URL.path contentType:@"application/octet-stream" data:[NSData new]]; | |
while(_currentOffset < _contentLength) | |
{ | |
if(_shouldCancel) | |
{ | |
NSLog(@"Cancel Steamer"); | |
break; | |
} | |
if(dataRequest.requestedOffset == 0 && dataRequest.requestedLength == 2) | |
{ | |
[mutableRequest setValue:[NSString stringWithFormat:@"bytes=%lli-%lli", dataRequest.requestedOffset, dataRequest.requestedOffset + dataRequest.requestedLength] forHTTPHeaderField:@"Range"]; | |
}else | |
{ | |
[mutableRequest setValue:[NSString stringWithFormat:@"bytes=%li-%li", _currentOffset, _currentOffset + _chunkSize] forHTTPHeaderField:@"Range"]; | |
} | |
NSHTTPURLResponse *response = nil; | |
NSError *error = nil; | |
NSData *data = [NSURLConnection sendSynchronousRequest:mutableRequest returningResponse:&response error:&error]; | |
if(error) | |
{ | |
NSLog(@"STREAM ERROR: %@", error); | |
continue; | |
} | |
if(!response.allHeaderFields[@"Content-Range"]) | |
{ | |
NSLog(@"STREAM MISSING CONTENT-RANGE: %@", response); | |
break; | |
} | |
if(contentRequest) | |
{ | |
contentRequest.byteRangeAccessSupported = YES; | |
contentRequest.contentType = @"public.mp3"; | |
contentRequest.contentLength = [[response.allHeaderFields[@"Content-Range"] componentsSeparatedByString:@"/"][1] integerValue]; | |
_contentLength = contentRequest.contentLength; | |
} | |
if(dataRequest.requestedOffset == 0 && dataRequest.requestedLength == 2) | |
{ | |
break; | |
} | |
[dataRequest respondWithData:data]; | |
_currentOffset += data.length + 1; | |
} | |
[loadingRequest finishLoading]; | |
return YES; | |
} | |
- (void)resourceLoader:(AVAssetResourceLoader *)resourceLoader didCancelLoadingRequest:(AVAssetResourceLoadingRequest *)loadingRequest | |
{ | |
_shouldCancel = YES; | |
} | |
- (void)dealloc | |
{ | |
_shouldCancel = YES; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
swift sample would be useful!