Skip to content

Instantly share code, notes, and snippets.

@flagoworld
Last active May 1, 2019 02:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flagoworld/969648081b288b445569 to your computer and use it in GitHub Desktop.
Save flagoworld/969648081b288b445569 to your computer and use it in GitHub Desktop.
AVAssetResourceLoaderDelegate - Stream from server that requires specific auth headers
// 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;
//
// 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
//
// 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
@abacaj
Copy link

abacaj commented May 1, 2019

swift sample would be useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment