diff --git a/ExampleApp/ExampleApp.xcodeproj/project.pbxproj b/ExampleApp/ExampleApp.xcodeproj/project.pbxproj index afab27b..b897340 100644 --- a/ExampleApp/ExampleApp.xcodeproj/project.pbxproj +++ b/ExampleApp/ExampleApp.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ A1115967188D6AEE00641365 /* AudioPlayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = A1115966188D6AEE00641365 /* AudioPlayerView.m */; }; A111596C188D6C8100641365 /* sample.m4a in Resources */ = {isa = PBXBuildFile; fileRef = A111596B188D6C8100641365 /* sample.m4a */; }; A111596F188D6DB100641365 /* SampleQueueId.m in Sources */ = {isa = PBXBuildFile; fileRef = A111596E188D6DB100641365 /* SampleQueueId.m */; }; + A1EBEE64188DE34500681B04 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -58,6 +59,7 @@ A111596B188D6C8100641365 /* sample.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = sample.m4a; path = Resources/sample.m4a; sourceTree = ""; }; A111596D188D6DB100641365 /* SampleQueueId.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SampleQueueId.h; sourceTree = ""; }; A111596E188D6DB100641365 /* SampleQueueId.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SampleQueueId.m; sourceTree = ""; }; + A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -65,6 +67,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + A1EBEE64188DE34500681B04 /* SystemConfiguration.framework in Frameworks */, A1115964188D691500641365 /* libStreamingKit.a in Frameworks */, A1115937188D686000641365 /* CoreGraphics.framework in Frameworks */, A1115939188D686000641365 /* UIKit.framework in Frameworks */, @@ -107,6 +110,7 @@ A1115933188D686000641365 /* Frameworks */ = { isa = PBXGroup; children = ( + A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */, A1115963188D691500641365 /* libStreamingKit.a */, A1115934188D686000641365 /* Foundation.framework */, A1115936188D686000641365 /* CoreGraphics.framework */, diff --git a/ExampleApp/ExampleApp/AppDelegate.m b/ExampleApp/ExampleApp/AppDelegate.m index 6415524..4e1e985 100644 --- a/ExampleApp/ExampleApp/AppDelegate.m +++ b/ExampleApp/ExampleApp/AppDelegate.m @@ -9,6 +9,7 @@ #import "AppDelegate.h" #import "STKAudioPlayer.h" #import "AudioPlayerView.h" +#import "STKAutoRecoveringHttpDataSource.h" #import "SampleQueueId.h" #import @@ -48,7 +49,9 @@ { NSURL* url = [NSURL URLWithString:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"]; - [audioPlayer setDataSource:[audioPlayer dataSourceFromURL:url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]]; + STKAutoRecoveringHttpDataSource* dataSource = [[STKAutoRecoveringHttpDataSource alloc] initWithHttpDataSource:(STKHttpDataSource*)[audioPlayer dataSourceFromURL:url]]; + + [audioPlayer setDataSource:dataSource withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]]; } -(void) audioPlayerViewPlayFromLocalFileSelected:(AudioPlayerView*)audioPlayerView diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.m b/StreamingKit/StreamingKit/STKAudioPlayer.m index 3127bc9..4949272 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.m +++ b/StreamingKit/StreamingKit/STKAudioPlayer.m @@ -316,9 +316,9 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ if ([self.delegate respondsToSelector:@selector(audioPlayer:internalStateChanged:)]) { dispatch_async(dispatch_get_main_queue(), ^ - { - [self.delegate audioPlayer:self internalStateChanged:internalState]; - }); + { + [self.delegate audioPlayer:self internalStateChanged:internalState]; + }); } AudioPlayerState newState; @@ -531,7 +531,12 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ while (bufferingQueue.count > 0) { - [array addObject:[[bufferingQueue dequeue] queueItemId]]; + id queueItemId = [[bufferingQueue dequeue] queueItemId]; + + if (queueItemId != nil) + { + [array addObject:queueItemId]; + } } for (QueueEntry* entry in upcomingQueue) @@ -542,12 +547,12 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ [upcomingQueue removeAllObjects]; dispatch_async(dispatch_get_main_queue(), ^ - { - if ([self.delegate respondsToSelector:@selector(audioPlayer:didCancelQueuedItems:)]) - { - [self.delegate audioPlayer:self didCancelQueuedItems:array]; - } - }); + { + if ([self.delegate respondsToSelector:@selector(audioPlayer:didCancelQueuedItems:)]) + { + [self.delegate audioPlayer:self didCancelQueuedItems:array]; + } + }); } pthread_mutex_unlock(&playerMutex); } diff --git a/StreamingKit/StreamingKit/STKAutoRecoveringHttpDataSource.m b/StreamingKit/StreamingKit/STKAutoRecoveringHttpDataSource.m index 11606c3..2a31d1b 100644 --- a/StreamingKit/StreamingKit/STKAutoRecoveringHttpDataSource.m +++ b/StreamingKit/StreamingKit/STKAutoRecoveringHttpDataSource.m @@ -73,6 +73,11 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach return (STKHttpDataSource*)self.innerDataSource; } +-(id) initWithDataSource:(STKDataSource *)innerDataSource +{ + return [self initWithHttpDataSource:(STKHttpDataSource*)innerDataSource]; +} + -(id) initWithHttpDataSource:(STKHttpDataSource*)innerDataSourceIn { if (self = [super initWithDataSource:innerDataSourceIn]) @@ -143,6 +148,8 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach -(void) dealloc { + NSLog(@"STKAutoRecoveringHttpDataSource dealloc"); + self.innerDataSource.delegate = nil; [self stopNotifier]; diff --git a/StreamingKit/StreamingKit/STKHttpDataSource.h b/StreamingKit/StreamingKit/STKHttpDataSource.h index 0a803f5..2264cf9 100644 --- a/StreamingKit/StreamingKit/STKHttpDataSource.h +++ b/StreamingKit/StreamingKit/STKHttpDataSource.h @@ -34,21 +34,15 @@ #import "STKCoreFoundationDataSource.h" -@interface STKHttpDataSource : STKCoreFoundationDataSource -{ -@private - int seekStart; - int relativePosition; - long long fileLength; - int discontinuous; - NSDictionary* httpHeaders; - AudioFileTypeID audioFileTypeHint; -} +typedef NSURL*(^URLProvider)(); -@property (readwrite, retain) NSURL* url; +@interface STKHttpDataSource : STKCoreFoundationDataSource + +@property (readonly, retain) NSURL* url; @property (readwrite) UInt32 httpStatusCode; +(AudioFileTypeID) audioFileTypeHintFromMimeType:(NSString*)fileExtension; -(id) initWithURL:(NSURL*)url; +-(id) initWithURLProvider:(URLProvider)urlProvider; @end diff --git a/StreamingKit/StreamingKit/STKHttpDataSource.m b/StreamingKit/StreamingKit/STKHttpDataSource.m index 58b332c..ae24460 100644 --- a/StreamingKit/StreamingKit/STKHttpDataSource.m +++ b/StreamingKit/StreamingKit/STKHttpDataSource.m @@ -36,13 +36,29 @@ #import "STKLocalFileDataSource.h" @interface STKHttpDataSource() +{ +@private + int seekStart; + int relativePosition; + long long fileLength; + int discontinuous; + NSURL* currentUrl; + URLProvider urlProvider; + NSDictionary* httpHeaders; + AudioFileTypeID audioFileTypeHint; +} -(void) open; + @end @implementation STKHttpDataSource -@synthesize url; -(id) initWithURL:(NSURL*)urlIn +{ + return [self initWithURLProvider:^NSURL* { return urlIn; }]; +} + +-(id) initWithURLProvider:(URLProvider)urlProviderIn { if (self = [super init]) { @@ -50,16 +66,26 @@ relativePosition = 0; fileLength = -1; - self.url = urlIn; + self->urlProvider = urlProviderIn; [self open]; - audioFileTypeHint = [STKLocalFileDataSource audioFileTypeHintFromFileExtension:urlIn.pathExtension]; + audioFileTypeHint = [STKLocalFileDataSource audioFileTypeHintFromFileExtension:self->currentUrl.pathExtension]; } return self; } +-(void) dealloc +{ + NSLog(@"STKHttpDataSource dealloc"); +} + +-(NSURL*) url +{ + return self->currentUrl; +} + +(AudioFileTypeID) audioFileTypeHintFromMimeType:(NSString*)mimeType { static dispatch_once_t onceToken; @@ -192,6 +218,8 @@ -(void) open { + self->currentUrl = urlProvider(); + CFHTTPMessageRef message = CFHTTPMessageCreateRequest(NULL, (CFStringRef)@"GET", (__bridge CFURLRef)self.url, kCFHTTPVersion1_1); if (seekStart > 0) @@ -225,7 +253,7 @@ // SSL support - if ([url.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame) + if ([self->currentUrl.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame) { NSDictionary* sslSettings = [NSDictionary dictionaryWithObjectsAndKeys: (NSString*)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamSSLLevel, diff --git a/StreamingKit/StreamingKit/STKLocalFileDataSource.h b/StreamingKit/StreamingKit/STKLocalFileDataSource.h index 2d5bc2a..2a5f571 100644 --- a/StreamingKit/StreamingKit/STKLocalFileDataSource.h +++ b/StreamingKit/StreamingKit/STKLocalFileDataSource.h @@ -35,17 +35,9 @@ #import "STKCoreFoundationDataSource.h" @interface STKLocalFileDataSource : STKCoreFoundationDataSource -{ -@private - long long position; - long long length; - AudioFileTypeID audioFileTypeHint; -} +(AudioFileTypeID) audioFileTypeHintFromFileExtension:(NSString*)fileExtension; - @property (readonly, copy) NSString* filePath; - -(id) initWithFilePath:(NSString*)filePath; @end diff --git a/StreamingKit/StreamingKit/STKLocalFileDataSource.m b/StreamingKit/StreamingKit/STKLocalFileDataSource.m index 3f98f33..acee100 100644 --- a/StreamingKit/StreamingKit/STKLocalFileDataSource.m +++ b/StreamingKit/StreamingKit/STKLocalFileDataSource.m @@ -35,8 +35,12 @@ #import "STKLocalFileDataSource.h" @interface STKLocalFileDataSource() +{ + long long position; + long long length; + AudioFileTypeID audioFileTypeHint; +} @property (readwrite, copy) NSString* filePath; - -(void) open; @end