Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions PersistentStreamPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
- (void)persistentStreamPlayerDidLoadAsset:(nonnull PersistentStreamPlayer *)player;
- (void)persistentStreamPlayerDidFailToLoadAsset:(nonnull PersistentStreamPlayer *)player;

- (void)persistentStreamPlayerWillSendRequestForAuthenticationChallenge:(nonnull NSURLAuthenticationChallenge *)challenge;


@end

@interface PersistentStreamPlayer : NSObject
Expand Down
51 changes: 49 additions & 2 deletions PersistentStreamPlayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ - (void)dealloc
- (void)prepareToPlay
{
self.pendingRequests = [NSMutableArray array];
AVURLAsset *asset;
if ([self localFileExists]) {
asset = [AVURLAsset URLAssetWithURL:self.localURL options:nil];
} else {
asset = [AVURLAsset URLAssetWithURL:self.audioRemoteStreamingURL options:nil];
}

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:self.audioRemoteStreamingURL options:nil];
[asset.resourceLoader setDelegate:self queue:dispatch_get_main_queue()];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset automaticallyLoadedAssetKeys:@[@"duration"]];
self.player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
Expand Down Expand Up @@ -146,6 +151,14 @@ - (void)seekToTime:(NSTimeInterval)time
}

#pragma mark - NSURLConnection delegate
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([self.delegate respondsToSelector:@selector(persistentStreamPlayerWillSendRequestForAuthenticationChallenge:)]) {
[self.delegate persistentStreamPlayerWillSendRequestForAuthenticationChallenge:challenge];
}

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
self.fullAudioDataLength = 0;
Expand All @@ -156,7 +169,9 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
self.fullAudioDataLength += data.length;
[self appendDataToTempFile:data];
if (self.response.statusCode == 200) {
[self appendDataToTempFile:data];
}
[self processPendingRequests];
}

Expand All @@ -175,6 +190,17 @@ - (BOOL)tempFileExists
{
return [[NSFileManager defaultManager] fileExistsAtPath:self.tempURL.path];
}

- (BOOL)localFileExists
{
//TODO: this should also do some sanity check on the file

// Check if the content stored in the file is playable, if not try to get the file from the server again.
NSURL *localFileURL = [[NSURL alloc] initFileURLWithPath:self.localURL.path];
AVAsset *asset = [AVAsset assetWithURL:localFileURL];

return asset.isPlayable ? [[NSFileManager defaultManager] fileExistsAtPath:self.localURL.path] : NO;
}

- (NSData *)dataFromFileInRange:(NSRange)range
{
Expand All @@ -200,6 +226,27 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection
}
}

- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error{

for (AVAssetResourceLoadingRequest *loadingRequest in self.pendingRequests) {
NSURLComponents * component = [[NSURLComponents alloc] initWithURL:loadingRequest.request.URL resolvingAgainstBaseURL:NO];
component.scheme = self.originalURLScheme ?: @"http";

if ([component.URL.absoluteString isEqualToString: connection.currentRequest.URL.absoluteString] ) {
[loadingRequest finishLoadingWithError:error];
[self.pendingRequests removeObject:loadingRequest];
}
}

if ([self.pendingRequests count] == 0) {
if ([self.delegate respondsToSelector:@selector(persistentStreamPlayerDidFailToLoadAsset:)]) {
[self.delegate persistentStreamPlayerDidFailToLoadAsset:self];
}
}

}

- (float)volume
{
return self.player.volume;
Expand Down