Compare commits
82 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c78dc5867 | |||
| 4df5a84569 | |||
| 70368a09ba | |||
| 018da7a2eb | |||
| d347e5e80c | |||
| 4d73784338 | |||
| 98c7d9b8f0 | |||
| 56b2dd4ace | |||
| a9b1e143a0 | |||
| c4a7251d19 | |||
| ae63d04b87 | |||
| dd7165b3d2 | |||
| 8c94b9ba5c | |||
| c2fe2c68b2 | |||
| 83bc40d5fc | |||
| b903ee58cc | |||
| 70fe37cd4a | |||
| f321f1a0d7 | |||
| a0a9553631 | |||
| ddc6cf4b2f | |||
| 22e954a5e2 | |||
| e7a952d248 | |||
| 511185c929 | |||
| 15b18069e3 | |||
| 6df11418f7 | |||
| cdb6f27a53 | |||
| b8528e30c5 | |||
| d5e531c602 | |||
| 8d61f3a3e3 | |||
| b0466171f6 | |||
| 10d799a35f | |||
| 08eaa7e85b | |||
| cd0dd97ebf | |||
| b2eeb76c90 | |||
| 5a6d93d7c1 | |||
| 8dd611c2ac | |||
| 4a0f944550 | |||
| f60e16c804 | |||
| f3f52cf1cd | |||
| 53667f8a35 | |||
| 6beebca443 | |||
| 6af12221e5 | |||
| ca80243083 | |||
| 804aa9dd6e | |||
| 0fdb461d90 | |||
| 313a55a5ca | |||
| ba8b29d106 | |||
| 5b629665d6 | |||
| 7608a42d29 | |||
| 381795fed6 | |||
| bd1d3c9aea | |||
| 6ada345b17 | |||
| e495130219 | |||
| e843a0b730 | |||
| b7f87aea98 | |||
| ca7abd75c1 | |||
| 951f905516 | |||
| bd8e6a5da9 | |||
| 48ce1f9e67 | |||
| 257532c6c9 | |||
| f85464236a | |||
| b47771ae48 | |||
| 48e082ab88 | |||
| b68e813750 | |||
| b4948882e4 | |||
| c100cb7202 | |||
| 593a08a04f | |||
| 1c9bd328e7 | |||
| dde738dffd | |||
| a9bd3557a5 | |||
| 431dd5d7f3 | |||
| aaaed1f33f | |||
| 3563fb7ea1 | |||
| c9ba30b692 | |||
| c68384ec50 | |||
| 756504f33b | |||
| 894dce8761 | |||
| c3a35fcdf3 | |||
| ce3f938309 | |||
| 429c156d8b | |||
| 0eb7687a63 | |||
| 9b952de734 |
@@ -23,6 +23,8 @@
|
||||
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 */; };
|
||||
A142571D189079BE005F0129 /* airplane.aac in Resources */ = {isa = PBXBuildFile; fileRef = A142571C18907861005F0129 /* airplane.aac */; };
|
||||
A1EBEE64188DE34500681B04 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -58,6 +60,8 @@
|
||||
A111596B188D6C8100641365 /* sample.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; name = sample.m4a; path = Resources/sample.m4a; sourceTree = "<group>"; };
|
||||
A111596D188D6DB100641365 /* SampleQueueId.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SampleQueueId.h; sourceTree = "<group>"; };
|
||||
A111596E188D6DB100641365 /* SampleQueueId.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SampleQueueId.m; sourceTree = "<group>"; };
|
||||
A142571C18907861005F0129 /* airplane.aac */ = {isa = PBXFileReference; lastKnownFileType = file; path = airplane.aac; sourceTree = "<group>"; };
|
||||
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 +69,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 +112,7 @@
|
||||
A1115933188D686000641365 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */,
|
||||
A1115963188D691500641365 /* libStreamingKit.a */,
|
||||
A1115934188D686000641365 /* Foundation.framework */,
|
||||
A1115936188D686000641365 /* CoreGraphics.framework */,
|
||||
@@ -164,6 +170,7 @@
|
||||
A111596A188D6C4B00641365 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A142571C18907861005F0129 /* airplane.aac */,
|
||||
A111596B188D6C8100641365 /* sample.m4a */,
|
||||
);
|
||||
name = Resources;
|
||||
@@ -247,6 +254,7 @@
|
||||
A111593F188D686000641365 /* InfoPlist.strings in Resources */,
|
||||
A111596C188D6C8100641365 /* sample.m4a in Resources */,
|
||||
A1115947188D686000641365 /* Images.xcassets in Resources */,
|
||||
A142571D189079BE005F0129 /* airplane.aac in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -397,11 +405,14 @@
|
||||
A111595E188D686000641365 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "ExampleApp/ExampleApp-Prefix.pch";
|
||||
INFOPLIST_FILE = "ExampleApp/ExampleApp-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
@@ -410,11 +421,14 @@
|
||||
A111595F188D686000641365 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "ExampleApp/ExampleApp-Prefix.pch";
|
||||
INFOPLIST_FILE = "ExampleApp/ExampleApp-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#import "AppDelegate.h"
|
||||
#import "STKAudioPlayer.h"
|
||||
#import "AudioPlayerView.h"
|
||||
#import "STKAutoRecoveringHTTPDataSource.h"
|
||||
#import "SampleQueueId.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
@@ -31,11 +32,16 @@
|
||||
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
audioPlayer = [[STKAudioPlayer alloc] init];
|
||||
audioPlayer = [[STKAudioPlayer alloc] initWithOptions:STKAudioPlayerOptionFlushQueueOnSeek];
|
||||
audioPlayer.meteringEnabled = YES;
|
||||
|
||||
AudioPlayerView* audioPlayerView = [[AudioPlayerView alloc] initWithFrame:self.window.bounds];
|
||||
|
||||
audioPlayerView.delegate = self;
|
||||
audioPlayerView.audioPlayer = audioPlayer;
|
||||
|
||||
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
|
||||
[self becomeFirstResponder];
|
||||
|
||||
[self.window addSubview:audioPlayerView];
|
||||
|
||||
@@ -44,20 +50,47 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL) canBecomeFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void) audioPlayerViewPlayFromHTTPSelected:(AudioPlayerView*)audioPlayerView
|
||||
{
|
||||
NSURL* url = [NSURL URLWithString:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"];
|
||||
|
||||
[audioPlayer setDataSource:[audioPlayer dataSourceFromURL:url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
|
||||
STKDataSource* dataSource = [STKAudioPlayer dataSourceFromURL:url];
|
||||
|
||||
[audioPlayer setDataSource:dataSource withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
|
||||
}
|
||||
|
||||
-(void) audioPlayerViewQueueShortFileSelected:(AudioPlayerView*)audioPlayerView
|
||||
{
|
||||
NSString* path = [[NSBundle mainBundle] pathForResource:@"airplane" ofType:@"aac"];
|
||||
NSURL* url = [NSURL fileURLWithPath:path];
|
||||
|
||||
STKDataSource* dataSource = [STKAudioPlayer dataSourceFromURL:url];
|
||||
|
||||
[audioPlayer queueDataSource:dataSource withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
|
||||
}
|
||||
|
||||
-(void) audioPlayerViewPlayFromLocalFileSelected:(AudioPlayerView*)audioPlayerView
|
||||
{
|
||||
NSString * path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"m4a"];
|
||||
NSString* path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"m4a"];
|
||||
NSURL* url = [NSURL fileURLWithPath:path];
|
||||
|
||||
[audioPlayer setDataSource:[audioPlayer dataSourceFromURL:url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
|
||||
STKDataSource* dataSource = [STKAudioPlayer dataSourceFromURL:url];
|
||||
|
||||
[audioPlayer setDataSource:dataSource withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
|
||||
}
|
||||
|
||||
-(void) audioPlayerViewQueuePcmWaveFileSelected:(AudioPlayerView*)audioPlayerView
|
||||
{
|
||||
NSURL* url = [NSURL URLWithString:@"http://fs.bloom.fm/oss/audiosamples/perfectly.wav"];
|
||||
|
||||
STKDataSource* dataSource = [STKAudioPlayer dataSourceFromURL:url];
|
||||
|
||||
[audioPlayer queueDataSource:dataSource withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -39,17 +39,27 @@
|
||||
|
||||
@protocol AudioPlayerViewDelegate<NSObject>
|
||||
-(void) audioPlayerViewPlayFromHTTPSelected:(AudioPlayerView*)audioPlayerView;
|
||||
-(void) audioPlayerViewQueueShortFileSelected:(AudioPlayerView*)audioPlayerView;
|
||||
-(void) audioPlayerViewPlayFromLocalFileSelected:(AudioPlayerView*)audioPlayerView;
|
||||
-(void) audioPlayerViewQueuePcmWaveFileSelected:(AudioPlayerView*)audioPlayerView;
|
||||
@end
|
||||
|
||||
@interface AudioPlayerView : UIView<STKAudioPlayerDelegate>
|
||||
{
|
||||
@private
|
||||
NSTimer* timer;
|
||||
UILabel* label;
|
||||
UILabel* statusLabel;
|
||||
UISlider* slider;
|
||||
UISwitch* repeatSwitch;
|
||||
UIButton* muteButton;
|
||||
UIButton* playButton;
|
||||
UIButton* stopButton;
|
||||
UIButton* playFromHTTPButton;
|
||||
UIButton* queueShortFileButton;
|
||||
UIButton* queuePcmWaveFileFromHTTPButton;
|
||||
UIButton* playFromLocalFileButton;
|
||||
UIView* meter;
|
||||
}
|
||||
|
||||
@property (readwrite, retain) STKAudioPlayer* audioPlayer;
|
||||
|
||||
@@ -53,31 +53,78 @@
|
||||
|
||||
if (self)
|
||||
{
|
||||
CGSize size = CGSizeMake(180, 50);
|
||||
CGSize size = CGSizeMake(220, 50);
|
||||
|
||||
playFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.15, size.width, size.height);
|
||||
playFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10, size.width, size.height);
|
||||
[playFromHTTPButton addTarget:self action:@selector(playFromHTTPButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[playFromHTTPButton setTitle:@"Play from HTTP" forState:UIControlStateNormal];
|
||||
|
||||
playFromLocalFileButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playFromLocalFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.15 + 50, size.width, size.height);
|
||||
playFromLocalFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 50, size.width, size.height);
|
||||
[playFromLocalFileButton addTarget:self action:@selector(playFromLocalFileButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[playFromLocalFileButton setTitle:@"Play from Local File" forState:UIControlStateNormal];
|
||||
|
||||
playButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playButton.frame = CGRectMake((320 - size.width) / 2, 350, size.width, size.height);
|
||||
[playButton addTarget:self action:@selector(playButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
queueShortFileButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
queueShortFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 100, size.width, size.height);
|
||||
[queueShortFileButton addTarget:self action:@selector(queueShortFileButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[queueShortFileButton setTitle:@"Queue short file" forState:UIControlStateNormal];
|
||||
|
||||
slider = [[UISlider alloc] initWithFrame:CGRectMake(20, 290, 280, 20)];
|
||||
queuePcmWaveFileFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
queuePcmWaveFileFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 150, size.width, size.height);
|
||||
[queuePcmWaveFileFromHTTPButton addTarget:self action:@selector(queuePcmWaveFileButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[queuePcmWaveFileFromHTTPButton setTitle:@"Queue PCM/WAVE from HTTP" forState:UIControlStateNormal];
|
||||
|
||||
size = CGSizeMake(90, 40);
|
||||
|
||||
playButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playButton.frame = CGRectMake(30, 380, size.width, size.height);
|
||||
[playButton addTarget:self action:@selector(playButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
stopButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
stopButton.frame = CGRectMake((320 - size.width) - 30, 380, size.width, size.height);
|
||||
[stopButton addTarget:self action:@selector(stopButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
||||
[stopButton setTitle:@"Stop" forState:UIControlStateNormal];
|
||||
|
||||
muteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
muteButton.frame = CGRectMake((320 - size.width) - 30, 410, size.width, size.height);
|
||||
[muteButton addTarget:self action:@selector(muteButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
||||
[muteButton setTitle:@"Mute" forState:UIControlStateNormal];
|
||||
|
||||
slider = [[UISlider alloc] initWithFrame:CGRectMake(20, 320, 280, 20)];
|
||||
slider.continuous = YES;
|
||||
[slider addTarget:self action:@selector(sliderChanged) forControlEvents:UIControlEventValueChanged];
|
||||
|
||||
size = CGSizeMake(80, 50);
|
||||
|
||||
repeatSwitch = [[UISwitch alloc] initWithFrame:CGRectMake((320 - size.width) / 2, frame.size.height * 0.15 + 180, size.width, size.height)];
|
||||
|
||||
label = [[UILabel alloc] initWithFrame:CGRectMake(0, slider.frame.origin.y + slider.frame.size.height + 10, frame.size.width, 25)];
|
||||
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
|
||||
statusLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, slider.frame.origin.y + slider.frame.size.height + label.frame.size.height + 8, frame.size.width, 50)];
|
||||
|
||||
statusLabel.textAlignment = NSTextAlignmentCenter;
|
||||
|
||||
|
||||
meter = [[UIView alloc] initWithFrame:CGRectMake(0, 450, 0, 20)];
|
||||
|
||||
meter.backgroundColor = [UIColor greenColor];
|
||||
|
||||
[self addSubview:slider];
|
||||
[self addSubview:playButton];
|
||||
[self addSubview:playFromHTTPButton];
|
||||
[self addSubview:playFromLocalFileButton];
|
||||
|
||||
[self addSubview:queueShortFileButton];
|
||||
[self addSubview:queuePcmWaveFileFromHTTPButton];
|
||||
[self addSubview:repeatSwitch];
|
||||
[self addSubview:label];
|
||||
[self addSubview:statusLabel];
|
||||
[self addSubview:stopButton];
|
||||
[self addSubview:meter];
|
||||
[self addSubview:muteButton];
|
||||
|
||||
[self setupTimer];
|
||||
[self updateControls];
|
||||
}
|
||||
@@ -99,24 +146,44 @@
|
||||
|
||||
-(void) setupTimer
|
||||
{
|
||||
timer = [NSTimer timerWithTimeInterval:0.25 target:self selector:@selector(tick) userInfo:nil repeats:YES];
|
||||
timer = [NSTimer timerWithTimeInterval:0.01 target:self selector:@selector(tick) userInfo:nil repeats:YES];
|
||||
|
||||
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
-(void) tick
|
||||
{
|
||||
if (!audioPlayer || audioPlayer.duration == 0)
|
||||
if (!audioPlayer)
|
||||
{
|
||||
slider.value = 0;
|
||||
label.text = @"";
|
||||
statusLabel.text = @"";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
slider.minimumValue = 0;
|
||||
slider.maximumValue = audioPlayer.duration;
|
||||
if (audioPlayer.duration != 0)
|
||||
{
|
||||
slider.minimumValue = 0;
|
||||
slider.maximumValue = audioPlayer.duration;
|
||||
slider.value = audioPlayer.progress;
|
||||
|
||||
label.text = [NSString stringWithFormat:@"%@ - %@", [self formatTimeFromSeconds:audioPlayer.progress], [self formatTimeFromSeconds:audioPlayer.duration]];
|
||||
}
|
||||
else
|
||||
{
|
||||
slider.value = 0;
|
||||
slider.minimumValue = 0;
|
||||
slider.maximumValue = 0;
|
||||
|
||||
label.text = @"";
|
||||
}
|
||||
|
||||
statusLabel.text = audioPlayer.state == STKAudioPlayerStateBuffering ? @"buffering" : @"";
|
||||
|
||||
slider.value = audioPlayer.progress;
|
||||
CGFloat newWidth = 320 * (([audioPlayer averagePowerInDecibelsForChannel:1] + 60) / 60);
|
||||
|
||||
meter.frame = CGRectMake(0, 460, newWidth, 20);
|
||||
}
|
||||
|
||||
-(void) playFromHTTPButtonTouched
|
||||
@@ -129,14 +196,43 @@
|
||||
[self.delegate audioPlayerViewPlayFromLocalFileSelected:self];
|
||||
}
|
||||
|
||||
-(void) queueShortFileButtonTouched
|
||||
{
|
||||
[self.delegate audioPlayerViewQueueShortFileSelected:self];
|
||||
}
|
||||
|
||||
-(void) queuePcmWaveFileButtonTouched
|
||||
{
|
||||
[self.delegate audioPlayerViewQueuePcmWaveFileSelected:self];
|
||||
}
|
||||
|
||||
-(void) muteButtonPressed
|
||||
{
|
||||
audioPlayer.muted = !audioPlayer.muted;
|
||||
|
||||
if (audioPlayer.muted)
|
||||
{
|
||||
[muteButton setTitle:@"Unmute" forState:UIControlStateNormal];
|
||||
}
|
||||
else
|
||||
{
|
||||
[muteButton setTitle:@"Mute" forState:UIControlStateNormal];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) stopButtonPressed
|
||||
{
|
||||
[audioPlayer stop];
|
||||
}
|
||||
|
||||
-(void) playButtonPressed
|
||||
{
|
||||
if (!audioPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioPlayer.state == AudioPlayerStatePaused)
|
||||
|
||||
if (audioPlayer.state == STKAudioPlayerStatePaused)
|
||||
{
|
||||
[audioPlayer resume];
|
||||
}
|
||||
@@ -146,24 +242,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
-(NSString*) formatTimeFromSeconds:(int)totalSeconds
|
||||
{
|
||||
|
||||
int seconds = totalSeconds % 60;
|
||||
int minutes = (totalSeconds / 60) % 60;
|
||||
int hours = totalSeconds / 3600;
|
||||
|
||||
return [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds];
|
||||
}
|
||||
|
||||
-(void) updateControls
|
||||
{
|
||||
if (audioPlayer == nil)
|
||||
{
|
||||
[playButton setTitle:@"Play" forState:UIControlStateNormal];
|
||||
[playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
}
|
||||
else if (audioPlayer.state == AudioPlayerStatePaused)
|
||||
else if (audioPlayer.state == STKAudioPlayerStatePaused)
|
||||
{
|
||||
[playButton setTitle:@"Resume" forState:UIControlStateNormal];
|
||||
}
|
||||
else if (audioPlayer.state == AudioPlayerStatePlaying)
|
||||
else if (audioPlayer.state & STKAudioPlayerStatePlaying)
|
||||
{
|
||||
[playButton setTitle:@"Pause" forState:UIControlStateNormal];
|
||||
}
|
||||
else
|
||||
{
|
||||
[playButton setTitle:@"Play" forState:UIControlStateNormal];
|
||||
[playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
[self tick];
|
||||
}
|
||||
|
||||
-(void) setAudioPlayer:(STKAudioPlayer*)value
|
||||
@@ -184,12 +292,12 @@
|
||||
return audioPlayer;
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(AudioPlayerState)state
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state previousState:(STKAudioPlayerState)previousState
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didEncounterError:(AudioPlayerErrorCode)errorCode
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer unexpectedError:(STKAudioPlayerErrorCode)errorCode
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
@@ -209,14 +317,17 @@
|
||||
|
||||
// This queues on the currently playing track to be buffered and played immediately after (gapless)
|
||||
|
||||
SampleQueueId* queueId = (SampleQueueId*)queueItemId;
|
||||
if (repeatSwitch.on)
|
||||
{
|
||||
SampleQueueId* queueId = (SampleQueueId*)queueItemId;
|
||||
|
||||
NSLog(@"Requeuing: %@", [queueId.url description]);
|
||||
NSLog(@"Requeuing: %@", [queueId.url description]);
|
||||
|
||||
[self->audioPlayer queueDataSource:[self->audioPlayer dataSourceFromURL:queueId.url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:queueId.url andCount:queueId.count + 1]];
|
||||
[self->audioPlayer queueDataSource:[STKAudioPlayer dataSourceFromURL:queueId.url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:queueId.url andCount:queueId.count + 1]];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(AudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(STKAudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration
|
||||
{
|
||||
[self updateControls];
|
||||
|
||||
@@ -225,4 +336,9 @@
|
||||
NSLog(@"Finished: %@", [queueId.url description]);
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer *)audioPlayer logInfo:(NSString *)line
|
||||
{
|
||||
NSLog(@"%@", line);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -36,4 +36,9 @@
|
||||
return [((SampleQueueId*)object).url isEqual: self.url] && ((SampleQueueId*)object).count == self.count;
|
||||
}
|
||||
|
||||
-(NSString*) description
|
||||
{
|
||||
return [self.url description];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,535 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
A1A499A5189E765800E2A2E2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499A4189E765800E2A2E2 /* Cocoa.framework */; };
|
||||
A1A499AF189E765800E2A2E2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1A499AD189E765800E2A2E2 /* InfoPlist.strings */; };
|
||||
A1A499B1189E765800E2A2E2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A1A499B0189E765800E2A2E2 /* main.m */; };
|
||||
A1A499B5189E765800E2A2E2 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = A1A499B3189E765800E2A2E2 /* Credits.rtf */; };
|
||||
A1A499B8189E765800E2A2E2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A1A499B7189E765800E2A2E2 /* AppDelegate.m */; };
|
||||
A1A499BB189E765800E2A2E2 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1A499B9189E765800E2A2E2 /* MainMenu.xib */; };
|
||||
A1A499BD189E765800E2A2E2 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A1A499BC189E765800E2A2E2 /* Images.xcassets */; };
|
||||
A1A499C4189E765800E2A2E2 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499C3189E765800E2A2E2 /* XCTest.framework */; };
|
||||
A1A499C5189E765800E2A2E2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499A4189E765800E2A2E2 /* Cocoa.framework */; };
|
||||
A1A499CD189E765800E2A2E2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1A499CB189E765800E2A2E2 /* InfoPlist.strings */; };
|
||||
A1A499CF189E765800E2A2E2 /* ExampleAppMacTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A1A499CE189E765800E2A2E2 /* ExampleAppMacTests.m */; };
|
||||
A1A499EC189E793300E2A2E2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499A9189E765800E2A2E2 /* Foundation.framework */; };
|
||||
A1A499F0189E793D00E2A2E2 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499EF189E793D00E2A2E2 /* CoreAudio.framework */; };
|
||||
A1A499F2189E799400E2A2E2 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499F1189E799400E2A2E2 /* AudioToolbox.framework */; };
|
||||
A1A499F3189E799F00E2A2E2 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499ED189E793700E2A2E2 /* AudioUnit.framework */; };
|
||||
A1A499F5189E79CB00E2A2E2 /* CoreAudioKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499F4189E79CB00E2A2E2 /* CoreAudioKit.framework */; };
|
||||
A1A499F9189E7A3500E2A2E2 /* libStreamingKitMac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499F8189E7A3500E2A2E2 /* libStreamingKitMac.a */; };
|
||||
A1A499FA189E7A5600E2A2E2 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499F1189E799400E2A2E2 /* AudioToolbox.framework */; };
|
||||
A1A499FC189E7A6D00E2A2E2 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499FB189E7A6D00E2A2E2 /* SystemConfiguration.framework */; };
|
||||
A1A499FD189E7BFC00E2A2E2 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A499ED189E793700E2A2E2 /* AudioUnit.framework */; };
|
||||
A1A49A01189E82EC00E2A2E2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A49A00189E82EC00E2A2E2 /* QuartzCore.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
A1A499C6189E765800E2A2E2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = A1A49999189E765800E2A2E2 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = A1A499A0189E765800E2A2E2;
|
||||
remoteInfo = ExampleAppMac;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
A1A499A1189E765800E2A2E2 /* ExampleAppMac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleAppMac.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1A499A4189E765800E2A2E2 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
A1A499A7189E765800E2A2E2 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
A1A499A8189E765800E2A2E2 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
A1A499A9189E765800E2A2E2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
A1A499AC189E765800E2A2E2 /* ExampleAppMac-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleAppMac-Info.plist"; sourceTree = "<group>"; };
|
||||
A1A499AE189E765800E2A2E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
A1A499B0189E765800E2A2E2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
A1A499B2189E765800E2A2E2 /* ExampleAppMac-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleAppMac-Prefix.pch"; sourceTree = "<group>"; };
|
||||
A1A499B4189E765800E2A2E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
A1A499B6189E765800E2A2E2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
A1A499B7189E765800E2A2E2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
A1A499BA189E765800E2A2E2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
A1A499BC189E765800E2A2E2 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
A1A499C2189E765800E2A2E2 /* ExampleAppMacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleAppMacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1A499C3189E765800E2A2E2 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
A1A499CA189E765800E2A2E2 /* ExampleAppMacTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleAppMacTests-Info.plist"; sourceTree = "<group>"; };
|
||||
A1A499CC189E765800E2A2E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
A1A499CE189E765800E2A2E2 /* ExampleAppMacTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleAppMacTests.m; sourceTree = "<group>"; };
|
||||
A1A499EA189E76BD00E2A2E2 /* libStreamingKitMac.a */ = {isa = PBXFileReference; lastKnownFileType = file; name = libStreamingKitMac.a; path = ../StreamingKit/build/Debug/libStreamingKitMac.a; sourceTree = "<group>"; };
|
||||
A1A499ED189E793700E2A2E2 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
A1A499EF189E793D00E2A2E2 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
|
||||
A1A499F1189E799400E2A2E2 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
A1A499F4189E79CB00E2A2E2 /* CoreAudioKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioKit.framework; path = System/Library/Frameworks/CoreAudioKit.framework; sourceTree = SDKROOT; };
|
||||
A1A499F8189E7A3500E2A2E2 /* libStreamingKitMac.a */ = {isa = PBXFileReference; lastKnownFileType = file; name = libStreamingKitMac.a; path = ../StreamingKit/build/Debug/libStreamingKitMac.a; sourceTree = "<group>"; };
|
||||
A1A499FB189E7A6D00E2A2E2 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
||||
A1A499FE189E82DD00E2A2E2 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
A1A49A00189E82EC00E2A2E2 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
A1A4999E189E765800E2A2E2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A49A01189E82EC00E2A2E2 /* QuartzCore.framework in Frameworks */,
|
||||
A1A499FD189E7BFC00E2A2E2 /* AudioUnit.framework in Frameworks */,
|
||||
A1A499FC189E7A6D00E2A2E2 /* SystemConfiguration.framework in Frameworks */,
|
||||
A1A499FA189E7A5600E2A2E2 /* AudioToolbox.framework in Frameworks */,
|
||||
A1A499F9189E7A3500E2A2E2 /* libStreamingKitMac.a in Frameworks */,
|
||||
A1A499F0189E793D00E2A2E2 /* CoreAudio.framework in Frameworks */,
|
||||
A1A499EC189E793300E2A2E2 /* Foundation.framework in Frameworks */,
|
||||
A1A499A5189E765800E2A2E2 /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1A499BF189E765800E2A2E2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A499F5189E79CB00E2A2E2 /* CoreAudioKit.framework in Frameworks */,
|
||||
A1A499F3189E799F00E2A2E2 /* AudioUnit.framework in Frameworks */,
|
||||
A1A499F2189E799400E2A2E2 /* AudioToolbox.framework in Frameworks */,
|
||||
A1A499C5189E765800E2A2E2 /* Cocoa.framework in Frameworks */,
|
||||
A1A499C4189E765800E2A2E2 /* XCTest.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
A1A49998189E765800E2A2E2 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499AA189E765800E2A2E2 /* ExampleAppMac */,
|
||||
A1A499C8189E765800E2A2E2 /* ExampleAppMacTests */,
|
||||
A1A499A3189E765800E2A2E2 /* Frameworks */,
|
||||
A1A499A2189E765800E2A2E2 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499A2189E765800E2A2E2 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499A1189E765800E2A2E2 /* ExampleAppMac.app */,
|
||||
A1A499C2189E765800E2A2E2 /* ExampleAppMacTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499A3189E765800E2A2E2 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A49A00189E82EC00E2A2E2 /* QuartzCore.framework */,
|
||||
A1A499FE189E82DD00E2A2E2 /* CoreGraphics.framework */,
|
||||
A1A499FB189E7A6D00E2A2E2 /* SystemConfiguration.framework */,
|
||||
A1A499F8189E7A3500E2A2E2 /* libStreamingKitMac.a */,
|
||||
A1A499F4189E79CB00E2A2E2 /* CoreAudioKit.framework */,
|
||||
A1A499F1189E799400E2A2E2 /* AudioToolbox.framework */,
|
||||
A1A499EF189E793D00E2A2E2 /* CoreAudio.framework */,
|
||||
A1A499ED189E793700E2A2E2 /* AudioUnit.framework */,
|
||||
A1A499EA189E76BD00E2A2E2 /* libStreamingKitMac.a */,
|
||||
A1A499A4189E765800E2A2E2 /* Cocoa.framework */,
|
||||
A1A499C3189E765800E2A2E2 /* XCTest.framework */,
|
||||
A1A499A6189E765800E2A2E2 /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499A6189E765800E2A2E2 /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499A7189E765800E2A2E2 /* AppKit.framework */,
|
||||
A1A499A8189E765800E2A2E2 /* CoreData.framework */,
|
||||
A1A499A9189E765800E2A2E2 /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499AA189E765800E2A2E2 /* ExampleAppMac */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499B6189E765800E2A2E2 /* AppDelegate.h */,
|
||||
A1A499B7189E765800E2A2E2 /* AppDelegate.m */,
|
||||
A1A499B9189E765800E2A2E2 /* MainMenu.xib */,
|
||||
A1A499BC189E765800E2A2E2 /* Images.xcassets */,
|
||||
A1A499AB189E765800E2A2E2 /* Supporting Files */,
|
||||
);
|
||||
path = ExampleAppMac;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499AB189E765800E2A2E2 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499AC189E765800E2A2E2 /* ExampleAppMac-Info.plist */,
|
||||
A1A499AD189E765800E2A2E2 /* InfoPlist.strings */,
|
||||
A1A499B0189E765800E2A2E2 /* main.m */,
|
||||
A1A499B2189E765800E2A2E2 /* ExampleAppMac-Prefix.pch */,
|
||||
A1A499B3189E765800E2A2E2 /* Credits.rtf */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499C8189E765800E2A2E2 /* ExampleAppMacTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499CE189E765800E2A2E2 /* ExampleAppMacTests.m */,
|
||||
A1A499C9189E765800E2A2E2 /* Supporting Files */,
|
||||
);
|
||||
path = ExampleAppMacTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499C9189E765800E2A2E2 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499CA189E765800E2A2E2 /* ExampleAppMacTests-Info.plist */,
|
||||
A1A499CB189E765800E2A2E2 /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
A1A499A0189E765800E2A2E2 /* ExampleAppMac */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1A499D2189E765800E2A2E2 /* Build configuration list for PBXNativeTarget "ExampleAppMac" */;
|
||||
buildPhases = (
|
||||
A1A4999D189E765800E2A2E2 /* Sources */,
|
||||
A1A4999E189E765800E2A2E2 /* Frameworks */,
|
||||
A1A4999F189E765800E2A2E2 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ExampleAppMac;
|
||||
productName = ExampleAppMac;
|
||||
productReference = A1A499A1189E765800E2A2E2 /* ExampleAppMac.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
A1A499C1189E765800E2A2E2 /* ExampleAppMacTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1A499D5189E765800E2A2E2 /* Build configuration list for PBXNativeTarget "ExampleAppMacTests" */;
|
||||
buildPhases = (
|
||||
A1A499BE189E765800E2A2E2 /* Sources */,
|
||||
A1A499BF189E765800E2A2E2 /* Frameworks */,
|
||||
A1A499C0189E765800E2A2E2 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
A1A499C7189E765800E2A2E2 /* PBXTargetDependency */,
|
||||
);
|
||||
name = ExampleAppMacTests;
|
||||
productName = ExampleAppMacTests;
|
||||
productReference = A1A499C2189E765800E2A2E2 /* ExampleAppMacTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
A1A49999189E765800E2A2E2 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Thong Nguyen";
|
||||
TargetAttributes = {
|
||||
A1A499C1189E765800E2A2E2 = {
|
||||
TestTargetID = A1A499A0189E765800E2A2E2;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = A1A4999C189E765800E2A2E2 /* Build configuration list for PBXProject "ExampleAppMac" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = A1A49998189E765800E2A2E2;
|
||||
productRefGroup = A1A499A2189E765800E2A2E2 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
A1A499A0189E765800E2A2E2 /* ExampleAppMac */,
|
||||
A1A499C1189E765800E2A2E2 /* ExampleAppMacTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
A1A4999F189E765800E2A2E2 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A499AF189E765800E2A2E2 /* InfoPlist.strings in Resources */,
|
||||
A1A499BD189E765800E2A2E2 /* Images.xcassets in Resources */,
|
||||
A1A499B5189E765800E2A2E2 /* Credits.rtf in Resources */,
|
||||
A1A499BB189E765800E2A2E2 /* MainMenu.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1A499C0189E765800E2A2E2 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A499CD189E765800E2A2E2 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
A1A4999D189E765800E2A2E2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A499B8189E765800E2A2E2 /* AppDelegate.m in Sources */,
|
||||
A1A499B1189E765800E2A2E2 /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1A499BE189E765800E2A2E2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A499CF189E765800E2A2E2 /* ExampleAppMacTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
A1A499C7189E765800E2A2E2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = A1A499A0189E765800E2A2E2 /* ExampleAppMac */;
|
||||
targetProxy = A1A499C6189E765800E2A2E2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
A1A499AD189E765800E2A2E2 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A1A499AE189E765800E2A2E2 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499B3189E765800E2A2E2 /* Credits.rtf */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A1A499B4189E765800E2A2E2 /* en */,
|
||||
);
|
||||
name = Credits.rtf;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499B9189E765800E2A2E2 /* MainMenu.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A1A499BA189E765800E2A2E2 /* Base */,
|
||||
);
|
||||
name = MainMenu.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499CB189E765800E2A2E2 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A1A499CC189E765800E2A2E2 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
A1A499D0189E765800E2A2E2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1A499D1189E765800E2A2E2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A1A499D3189E765800E2A2E2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "ExampleAppMac/ExampleAppMac-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../StreamingKit/StreamingKit",
|
||||
);
|
||||
INFOPLIST_FILE = "ExampleAppMac/ExampleAppMac-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1A499D4189E765800E2A2E2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "ExampleAppMac/ExampleAppMac-Prefix.pch";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../StreamingKit/StreamingKit",
|
||||
);
|
||||
INFOPLIST_FILE = "ExampleAppMac/ExampleAppMac-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A1A499D6189E765800E2A2E2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ExampleAppMac.app/Contents/MacOS/ExampleAppMac";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "ExampleAppMac/ExampleAppMac-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "ExampleAppMacTests/ExampleAppMacTests-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1A499D7189E765800E2A2E2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ExampleAppMac.app/Contents/MacOS/ExampleAppMac";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "ExampleAppMac/ExampleAppMac-Prefix.pch";
|
||||
INFOPLIST_FILE = "ExampleAppMacTests/ExampleAppMacTests-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
A1A4999C189E765800E2A2E2 /* Build configuration list for PBXProject "ExampleAppMac" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1A499D0189E765800E2A2E2 /* Debug */,
|
||||
A1A499D1189E765800E2A2E2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A1A499D2189E765800E2A2E2 /* Build configuration list for PBXNativeTarget "ExampleAppMac" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1A499D3189E765800E2A2E2 /* Debug */,
|
||||
A1A499D4189E765800E2A2E2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A1A499D5189E765800E2A2E2 /* Build configuration list for PBXNativeTarget "ExampleAppMacTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1A499D6189E765800E2A2E2 /* Debug */,
|
||||
A1A499D7189E765800E2A2E2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = A1A49999189E765800E2A2E2 /* Project object */;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:ExampleAppMac.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>B1180E29-F9F8-4232-A985-F8E21716EF14</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>ExampleAppMac</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>DD310C30-B3D0-4BD7-9565-9F29F09CC4F8</key>
|
||||
<string>https://github.com/tumtumtum/StreamingKit.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>ExampleAppMac/ExampleAppMac.xcodeproj/project.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>DD310C30-B3D0-4BD7-9565-9F29F09CC4F8</key>
|
||||
<string>../../..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>https://github.com/tumtumtum/StreamingKit.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>110</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>DD310C30-B3D0-4BD7-9565-9F29F09CC4F8</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>DD310C30-B3D0-4BD7-9565-9F29F09CC4F8</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>StreamingKit</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// ExampleAppMac
|
||||
//
|
||||
// Created by Thong Nguyen on 02/02/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "STKAudioPlayer.h"
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate, STKAudioPlayerDelegate>
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// ExampleAppMac
|
||||
//
|
||||
// Created by Thong Nguyen on 02/02/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "STKAudioPlayer.h"
|
||||
|
||||
@interface AppDelegate()
|
||||
{
|
||||
NSView* meter;
|
||||
NSSlider* slider;
|
||||
STKAudioPlayer* audioPlayer;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
-(void) applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
CGRect frame = [self.window.contentView frame];
|
||||
|
||||
NSButton* playFromHTTPButton = [[NSButton alloc] initWithFrame:CGRectMake(10, 10, frame.size.width - 20, 100)];
|
||||
|
||||
[playFromHTTPButton setTitle:@"Play from HTTP"];
|
||||
[playFromHTTPButton setAction:@selector(playFromHTTP)];
|
||||
|
||||
slider = [[NSSlider alloc] initWithFrame:CGRectMake(10, 140, frame.size.width - 20, 20)];
|
||||
[slider setAction:@selector(sliderChanged:)];
|
||||
|
||||
meter = [[NSView alloc] initWithFrame:CGRectMake(10, 200, 0, 20)];
|
||||
[meter setLayer:[CALayer new]];
|
||||
[meter setWantsLayer:YES];
|
||||
meter.layer.backgroundColor = [NSColor greenColor].CGColor;
|
||||
|
||||
[[self.window contentView] addSubview:slider];
|
||||
[[self.window contentView] addSubview:playFromHTTPButton];
|
||||
[[self.window contentView] addSubview:meter];
|
||||
|
||||
audioPlayer = [[STKAudioPlayer alloc] init];
|
||||
audioPlayer.delegate = self;
|
||||
audioPlayer.meteringEnabled = YES;
|
||||
|
||||
[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
|
||||
}
|
||||
|
||||
-(void) playFromHTTP
|
||||
{
|
||||
[audioPlayer play:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"];
|
||||
}
|
||||
|
||||
-(void) tick:(NSTimer*)timer
|
||||
{
|
||||
if (!audioPlayer)
|
||||
{
|
||||
slider.doubleValue = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CGFloat meterWidth = 0;
|
||||
|
||||
if (audioPlayer.duration != 0)
|
||||
{
|
||||
slider.minValue = 0;
|
||||
slider.maxValue = audioPlayer.duration;
|
||||
slider.doubleValue = audioPlayer.progress;
|
||||
|
||||
meterWidth = [self.window.contentView frame].size.width - 20;
|
||||
meterWidth *= (([audioPlayer averagePowerInDecibelsForChannel:0] + 60) / 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
slider.doubleValue = 0;
|
||||
slider.minValue = 0;
|
||||
slider.maxValue = 0;
|
||||
|
||||
meterWidth = 0;
|
||||
}
|
||||
|
||||
CGRect frame = meter.frame;
|
||||
|
||||
frame.size.width = meterWidth;
|
||||
|
||||
meter.frame = frame;
|
||||
}
|
||||
|
||||
-(void) sliderChanged:(NSSlider*)sliderIn
|
||||
{
|
||||
[audioPlayer seekToTime:sliderIn.doubleValue];
|
||||
}
|
||||
|
||||
-(void) updateControls
|
||||
{
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didStartPlayingQueueItemId:(NSObject*)queueItemId
|
||||
{
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishBufferingSourceWithQueueItemId:(NSObject*)queueItemId
|
||||
{
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state previousState:(STKAudioPlayerState)previousState
|
||||
{
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(STKAudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration
|
||||
{
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer unexpectedError:(STKAudioPlayerErrorCode)errorCode
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,467 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="4439" systemVersion="13A451" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="4439"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" destination="58" id="142"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder">
|
||||
<connections>
|
||||
<action selector="alignCenter:" destination="499" id="518"/>
|
||||
<action selector="alignJustified:" destination="500" id="523"/>
|
||||
<action selector="alignLeft:" destination="498" id="524"/>
|
||||
<action selector="alignRight:" destination="501" id="521"/>
|
||||
<action selector="arrangeInFront:" destination="5" id="39"/>
|
||||
<action selector="capitalizeWord:" destination="466" id="467"/>
|
||||
<action selector="centerSelectionInVisibleArea:" destination="210" id="245"/>
|
||||
<action selector="checkSpelling:" destination="201" id="225"/>
|
||||
<action selector="clearRecentDocuments:" destination="126" id="127"/>
|
||||
<action selector="copy:" destination="197" id="224"/>
|
||||
<action selector="copyFont:" destination="403" id="428"/>
|
||||
<action selector="copyRuler:" destination="506" id="522"/>
|
||||
<action selector="cut:" destination="199" id="228"/>
|
||||
<action selector="delete:" destination="202" id="235"/>
|
||||
<action selector="hide:" destination="134" id="367"/>
|
||||
<action selector="hideOtherApplications:" destination="145" id="368"/>
|
||||
<action selector="loosenKerning:" destination="419" id="435"/>
|
||||
<action selector="lowerBaseline:" destination="410" id="427"/>
|
||||
<action selector="lowercaseWord:" destination="465" id="468"/>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" destination="511" id="526"/>
|
||||
<action selector="makeBaseWritingDirectionNatural:" destination="510" id="525"/>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" destination="512" id="527"/>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" destination="516" id="529"/>
|
||||
<action selector="makeTextWritingDirectionNatural:" destination="515" id="528"/>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" destination="517" id="530"/>
|
||||
<action selector="newDocument:" destination="82" id="373"/>
|
||||
<action selector="openDocument:" destination="72" id="374"/>
|
||||
<action selector="orderFrontColorPanel:" destination="401" id="433"/>
|
||||
<action selector="orderFrontSubstitutionsPanel:" destination="457" id="458"/>
|
||||
<action selector="paste:" destination="203" id="226"/>
|
||||
<action selector="pasteAsPlainText:" destination="485" id="486"/>
|
||||
<action selector="pasteFont:" destination="404" id="436"/>
|
||||
<action selector="pasteRuler:" destination="507" id="519"/>
|
||||
<action selector="performClose:" destination="73" id="193"/>
|
||||
<action selector="performFindPanelAction:" destination="209" id="241"/>
|
||||
<action selector="performFindPanelAction:" destination="208" id="487"/>
|
||||
<action selector="performFindPanelAction:" destination="213" id="488"/>
|
||||
<action selector="performFindPanelAction:" destination="221" id="489"/>
|
||||
<action selector="performFindPanelAction:" destination="534" id="535"/>
|
||||
<action selector="performMiniaturize:" destination="23" id="37"/>
|
||||
<action selector="performZoom:" destination="239" id="240"/>
|
||||
<action selector="print:" destination="78" id="86"/>
|
||||
<action selector="raiseBaseline:" destination="409" id="426"/>
|
||||
<action selector="redo:" destination="215" id="231"/>
|
||||
<action selector="revertDocumentToSaved:" destination="112" id="364"/>
|
||||
<action selector="runPageLayout:" destination="77" id="87"/>
|
||||
<action selector="runToolbarCustomizationPalette:" destination="298" id="365"/>
|
||||
<action selector="saveDocument:" destination="75" id="362"/>
|
||||
<action selector="selectAll:" destination="198" id="232"/>
|
||||
<action selector="showGuessPanel:" destination="204" id="230"/>
|
||||
<action selector="showHelp:" destination="492" id="493"/>
|
||||
<action selector="startSpeaking:" destination="196" id="233"/>
|
||||
<action selector="stopSpeaking:" destination="195" id="227"/>
|
||||
<action selector="subscript:" destination="408" id="429"/>
|
||||
<action selector="superscript:" destination="407" id="430"/>
|
||||
<action selector="tightenKerning:" destination="418" id="431"/>
|
||||
<action selector="toggleAutomaticDashSubstitution:" destination="460" id="461"/>
|
||||
<action selector="toggleAutomaticLinkDetection:" destination="354" id="357"/>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" destination="351" id="356"/>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" destination="454" id="456"/>
|
||||
<action selector="toggleAutomaticTextReplacement:" destination="462" id="463"/>
|
||||
<action selector="toggleContinuousSpellChecking:" destination="219" id="222"/>
|
||||
<action selector="toggleGrammarChecking:" destination="346" id="347"/>
|
||||
<action selector="toggleRuler:" destination="505" id="520"/>
|
||||
<action selector="toggleSmartInsertDelete:" destination="350" id="355"/>
|
||||
<action selector="toggleToolbarShown:" destination="297" id="366"/>
|
||||
<action selector="turnOffKerning:" destination="417" id="441"/>
|
||||
<action selector="turnOffLigatures:" destination="413" id="440"/>
|
||||
<action selector="underline:" destination="392" id="432"/>
|
||||
<action selector="undo:" destination="207" id="223"/>
|
||||
<action selector="unhideAllApplications:" destination="150" id="370"/>
|
||||
<action selector="unscript:" destination="406" id="437"/>
|
||||
<action selector="uppercaseWord:" destination="452" id="464"/>
|
||||
<action selector="useAllLigatures:" destination="414" id="434"/>
|
||||
<action selector="useStandardKerning:" destination="416" id="438"/>
|
||||
<action selector="useStandardLigatures:" destination="412" id="439"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-3" userLabel="Application">
|
||||
<connections>
|
||||
<action selector="terminate:" destination="136" id="449"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="ExampleAppMac" id="56">
|
||||
<menu key="submenu" title="ExampleAppMac" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="About ExampleAppMac" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
|
||||
<menuItem isSeparatorItem="YES" id="143">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Services" id="131">
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide ExampleAppMac" keyEquivalent="h" id="134"/>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="150"/>
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit ExampleAppMac" keyEquivalent="q" id="136"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="83">
|
||||
<menu key="submenu" title="File" id="81">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="82"/>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="72"/>
|
||||
<menuItem title="Open Recent" id="124">
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="126"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="79">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Close" keyEquivalent="w" id="73"/>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="75"/>
|
||||
<menuItem title="Revert to Saved" id="112">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="74">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="78"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="217">
|
||||
<menu key="submenu" title="Edit" id="205">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="207"/>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="215">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="206">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="199"/>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="197"/>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="203"/>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="485">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="202"/>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="198"/>
|
||||
<menuItem isSeparatorItem="YES" id="214">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find" id="218">
|
||||
<menu key="submenu" title="Find" id="220">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209"/>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208"/>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221"/>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="210"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="216">
|
||||
<menu key="submenu" title="Spelling and Grammar" id="200">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204"/>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="201"/>
|
||||
<menuItem isSeparatorItem="YES" id="453"/>
|
||||
<menuItem title="Check Spelling While Typing" id="219"/>
|
||||
<menuItem title="Check Grammar With Spelling" id="346"/>
|
||||
<menuItem title="Correct Spelling Automatically" id="454">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="348">
|
||||
<menu key="submenu" title="Substitutions" id="349">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="457">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="459"/>
|
||||
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350"/>
|
||||
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351"/>
|
||||
<menuItem title="Smart Dashes" id="460">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="462">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="450">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="451">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="452">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="465">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="466">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="211">
|
||||
<menu key="submenu" title="Speech" id="212">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="196"/>
|
||||
<menuItem title="Stop Speaking" id="195"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="375">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="376">
|
||||
<items>
|
||||
<menuItem title="Font" id="377">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="388">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="389"/>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="390"/>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="391"/>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="392"/>
|
||||
<menuItem isSeparatorItem="YES" id="393"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="394"/>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="395"/>
|
||||
<menuItem isSeparatorItem="YES" id="396"/>
|
||||
<menuItem title="Kern" id="397">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="415">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="416">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="417">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="418">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="419">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="398">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="411">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="412">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="413">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="414">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="399">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="405">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="406">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="407">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="408">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="409">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="410">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="400"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="401"/>
|
||||
<menuItem isSeparatorItem="YES" id="402"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="403">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="404">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="496">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="497">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="498"/>
|
||||
<menuItem title="Center" keyEquivalent="|" id="499"/>
|
||||
<menuItem title="Justify" id="500">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="501"/>
|
||||
<menuItem isSeparatorItem="YES" id="502"/>
|
||||
<menuItem title="Writing Direction" id="503">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="508">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="509">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="510">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="511">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="512">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="513"/>
|
||||
<menuItem title="Selection" enabled="NO" id="514">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="515">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="516">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="517">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="504"/>
|
||||
<menuItem title="Show Ruler" id="505">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="506">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="507">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="295">
|
||||
<menu key="submenu" title="View" id="296">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="297">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="298"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="19">
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="24">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="23"/>
|
||||
<menuItem title="Zoom" id="239"/>
|
||||
<menuItem isSeparatorItem="YES" id="92">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Bring All to Front" id="5"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="490">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="ExampleAppMac Help" keyEquivalent="?" id="492"/>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="ExampleAppMac" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
|
||||
<view key="contentView" id="372">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</view>
|
||||
</window>
|
||||
<customObject id="494" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="window" destination="371" id="532"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="420" customClass="NSFontManager">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" destination="390" id="421"/>
|
||||
<action selector="addFontTrait:" destination="391" id="422"/>
|
||||
<action selector="modifyFont:" destination="395" id="423"/>
|
||||
<action selector="modifyFont:" destination="394" id="425"/>
|
||||
<action selector="orderFrontFontPanel:" destination="389" id="424"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.abstractpath.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Thong Nguyen. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\paperw9840\paperh8400
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
|
||||
|
||||
\f0\b\fs24 \cf0 Engineering:
|
||||
\b0 \
|
||||
Some people\
|
||||
\
|
||||
|
||||
\b Human Interface Design:
|
||||
\b0 \
|
||||
Some other people\
|
||||
\
|
||||
|
||||
\b Testing:
|
||||
\b0 \
|
||||
Hopefully not nobody\
|
||||
\
|
||||
|
||||
\b Documentation:
|
||||
\b0 \
|
||||
Whoever\
|
||||
\
|
||||
|
||||
\b With special thanks to:
|
||||
\b0 \
|
||||
Mom\
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// main.m
|
||||
// ExampleAppMac
|
||||
//
|
||||
// Created by Thong Nguyen on 02/02/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.abstractpath.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// ExampleAppMacTests.m
|
||||
// ExampleAppMacTests
|
||||
//
|
||||
// Created by Thong Nguyen on 02/02/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface ExampleAppMacTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation ExampleAppMacTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testExample
|
||||
{
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
@@ -10,7 +10,7 @@ The primary motivation of this project was to decouple the input data sources fr
|
||||
* Easy to read source
|
||||
* Mostly asynchronous API
|
||||
* Buffered and gapless playback
|
||||
* Easy to implement audio data sources (HTTP and local file system DataSources provided)
|
||||
* Easy to implement audio data sources (Local, HTTP, Auto Recovering HTTP DataSources are provided)
|
||||
* Easy to extend DataSource to support adaptive buffering, encryption, etc.
|
||||
* Optimised for low CPU/battery usage
|
||||
|
||||
@@ -20,18 +20,15 @@ StreamingKit is also available as a [Cocoapod](http://cocoapods.org/?q=Streaming
|
||||
|
||||
## Example
|
||||
|
||||
There are two main classes. The `STKDataSource` class which is the abstract base class for the various compressed audio data sources (HTTP, local file are provided). The `STKAudioPlayer` class manages and renders audio from a queue DataSources.
|
||||
There are two main classes. The `STKDataSource` class which is the abstract base class for the various compressed audio data sources. The `STKAudioPlayer` class manages and renders audio from a queue DataSources. By default `STKAudioPlayer` will automatically parse URLs and create the appropriate data source internally.
|
||||
|
||||
```objective-c
|
||||
|
||||
// Create AudioPlayer
|
||||
|
||||
STKAudioPlayer* audioPlayer = [[STKAudioPlayer alloc] init];
|
||||
audioPlayer.delegate = self;
|
||||
|
||||
// Queue on a URL to play. Each queue item has a unique ID (item1) that to identify the related file in delegate callbacks
|
||||
|
||||
[audioPlayer setDataSource:[audioPlayer dataSourceFromURL:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"] withQueueItemId:@"item1"];
|
||||
[audioPlayer play:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"];
|
||||
|
||||
|
||||
```
|
||||
|
||||
@@ -9,5 +9,5 @@ Pod::Spec.new do |s|
|
||||
s.platform = :ios
|
||||
s.requires_arc = true
|
||||
s.source_files = 'StreamingKit/StreamingKit/*.{h,m}'
|
||||
s.frameworks = 'AVFoundation', 'SystemConfiguration', 'CFNetwork', 'CoreFoundation', 'AudioToolbox'
|
||||
s.frameworks = 'AVFoundation', 'SystemConfiguration', 'CFNetwork', 'CoreFoundation', 'AudioToolbox', 'AudioUnit'
|
||||
end
|
||||
|
||||
@@ -9,5 +9,5 @@ Pod::Spec.new do |s|
|
||||
s.platform = :ios
|
||||
s.requires_arc = true
|
||||
s.source_files = 'StreamingKit/StreamingKit/*.{h,m}'
|
||||
s.frameworks = 'AVFoundation', 'SystemConfiguration', 'CFNetwork', 'CoreFoundation', 'AudioToolbox'
|
||||
s.frameworks = 'AVFoundation', 'SystemConfiguration', 'CFNetwork', 'CoreFoundation', 'AudioToolbox', 'AudioUnit'
|
||||
end
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
<FileRef
|
||||
location = "group:ExampleApp/ExampleApp.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:StreamingKit/../ExampleAppMac/ExampleAppMac.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:StreamingKit/StreamingKit.xcodeproj">
|
||||
</FileRef>
|
||||
|
||||
@@ -7,23 +7,60 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
A1E7C4CC188D57F50010896F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E7C4CB188D57F50010896F /* Foundation.framework */; };
|
||||
A1A4996B189E744400E2A2E2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A4996A189E744400E2A2E2 /* Cocoa.framework */; };
|
||||
A1A49975189E744500E2A2E2 /* StreamingKitMac.m in Sources */ = {isa = PBXBuildFile; fileRef = A1A49974189E744500E2A2E2 /* StreamingKitMac.m */; };
|
||||
A1A4997B189E744500E2A2E2 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E7C4D9188D57F60010896F /* XCTest.framework */; };
|
||||
A1A4997C189E744500E2A2E2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A4996A189E744400E2A2E2 /* Cocoa.framework */; };
|
||||
A1A4997F189E744500E2A2E2 /* libStreamingKitMac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A49969189E744400E2A2E2 /* libStreamingKitMac.a */; };
|
||||
A1A49985189E744500E2A2E2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1A49983189E744500E2A2E2 /* InfoPlist.strings */; };
|
||||
A1A49987189E744500E2A2E2 /* StreamingKitMacTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A1A49986189E744500E2A2E2 /* StreamingKitMacTests.m */; };
|
||||
A1A4998E189E745900E2A2E2 /* STKAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F2188D5E550010896F /* STKAudioPlayer.m */; };
|
||||
A1A4998F189E745C00E2A2E2 /* STKAutoRecoveringHTTPDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F4188D5E550010896F /* STKAutoRecoveringHTTPDataSource.m */; };
|
||||
A1A49991189E746000E2A2E2 /* STKCoreFoundationDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F6188D5E550010896F /* STKCoreFoundationDataSource.m */; };
|
||||
A1A49992189E746300E2A2E2 /* STKDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F8188D5E550010896F /* STKDataSource.m */; };
|
||||
A1A49993189E746500E2A2E2 /* STKDataSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FA188D5E550010896F /* STKDataSourceWrapper.m */; };
|
||||
A1A49994189E746900E2A2E2 /* STKHTTPDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FC188D5E550010896F /* STKHTTPDataSource.m */; };
|
||||
A1A49995189E746B00E2A2E2 /* STKLocalFileDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */; };
|
||||
A1A49996189E746E00E2A2E2 /* STKQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BF65D1189A6582004DD08C /* STKQueueEntry.m */; };
|
||||
A1A49997189E747000E2A2E2 /* NSMutableArray+STKAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BF65D4189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m */; };
|
||||
A1BF65D2189A6582004DD08C /* STKQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BF65D1189A6582004DD08C /* STKQueueEntry.m */; };
|
||||
A1BF65D5189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BF65D4189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m */; };
|
||||
A1E7C4DA188D57F60010896F /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E7C4D9188D57F60010896F /* XCTest.framework */; };
|
||||
A1E7C4DB188D57F60010896F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E7C4CB188D57F50010896F /* Foundation.framework */; };
|
||||
A1E7C4E0188D57F60010896F /* libStreamingKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E7C4C8188D57F50010896F /* libStreamingKit.a */; };
|
||||
A1E7C4E6188D57F60010896F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1E7C4E4188D57F60010896F /* InfoPlist.strings */; };
|
||||
A1E7C4E8188D57F60010896F /* StreamingKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4E7188D57F60010896F /* StreamingKitTests.m */; };
|
||||
A1E7C4FF188D5E550010896F /* STKAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F2188D5E550010896F /* STKAudioPlayer.m */; };
|
||||
A1E7C500188D5E550010896F /* STKAutoRecoveringHttpDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F4188D5E550010896F /* STKAutoRecoveringHttpDataSource.m */; };
|
||||
A1E7C500188D5E550010896F /* STKAutoRecoveringHTTPDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F4188D5E550010896F /* STKAutoRecoveringHTTPDataSource.m */; };
|
||||
A1E7C501188D5E550010896F /* STKCoreFoundationDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F6188D5E550010896F /* STKCoreFoundationDataSource.m */; };
|
||||
A1E7C502188D5E550010896F /* STKDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F8188D5E550010896F /* STKDataSource.m */; };
|
||||
A1E7C503188D5E550010896F /* STKDataSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FA188D5E550010896F /* STKDataSourceWrapper.m */; };
|
||||
A1E7C504188D5E550010896F /* STKHttpDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FC188D5E550010896F /* STKHttpDataSource.m */; };
|
||||
A1E7C504188D5E550010896F /* STKHTTPDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FC188D5E550010896F /* STKHTTPDataSource.m */; };
|
||||
A1E7C505188D5E550010896F /* STKLocalFileDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */; };
|
||||
A1E7C508188D62D20010896F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E7C507188D62D20010896F /* UIKit.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
A1A4997D189E744500E2A2E2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = A1E7C4C0188D57F50010896F /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = A1A49968189E744400E2A2E2;
|
||||
remoteInfo = StreamingKitMac;
|
||||
};
|
||||
A1A499E6189E769A00E2A2E2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = A1A499E1189E769A00E2A2E2 /* ExampleAppMac.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = A1A499A1189E765800E2A2E2;
|
||||
remoteInfo = ExampleAppMac;
|
||||
};
|
||||
A1A499E8189E769A00E2A2E2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = A1A499E1189E769A00E2A2E2 /* ExampleAppMac.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = A1A499C2189E765800E2A2E2;
|
||||
remoteInfo = ExampleAppMacTests;
|
||||
};
|
||||
A1E7C4DE188D57F60010896F /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = A1E7C4C0188D57F50010896F /* Project object */;
|
||||
@@ -46,6 +83,25 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
A1A49969189E744400E2A2E2 /* libStreamingKitMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libStreamingKitMac.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1A4996A189E744400E2A2E2 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; };
|
||||
A1A4996D189E744500E2A2E2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
A1A4996E189E744500E2A2E2 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
A1A4996F189E744500E2A2E2 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
A1A49972189E744500E2A2E2 /* StreamingKitMac-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StreamingKitMac-Prefix.pch"; sourceTree = "<group>"; };
|
||||
A1A49973189E744500E2A2E2 /* StreamingKitMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StreamingKitMac.h; sourceTree = "<group>"; };
|
||||
A1A49974189E744500E2A2E2 /* StreamingKitMac.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StreamingKitMac.m; sourceTree = "<group>"; };
|
||||
A1A4997A189E744500E2A2E2 /* StreamingKitMacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StreamingKitMacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1A49982189E744500E2A2E2 /* StreamingKitMacTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "StreamingKitMacTests-Info.plist"; sourceTree = "<group>"; };
|
||||
A1A49984189E744500E2A2E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
A1A49986189E744500E2A2E2 /* StreamingKitMacTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StreamingKitMacTests.m; sourceTree = "<group>"; };
|
||||
A1A499E1189E769A00E2A2E2 /* ExampleAppMac.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ExampleAppMac.xcodeproj; path = ../ExampleAppMac/ExampleAppMac.xcodeproj; sourceTree = "<group>"; };
|
||||
A1A499F6189E79EA00E2A2E2 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
A1BF65D0189A6582004DD08C /* STKQueueEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKQueueEntry.h; sourceTree = "<group>"; };
|
||||
A1BF65D1189A6582004DD08C /* STKQueueEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKQueueEntry.m; sourceTree = "<group>"; };
|
||||
A1BF65D3189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+STKAudioPlayer.h"; sourceTree = "<group>"; };
|
||||
A1BF65D4189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+STKAudioPlayer.m"; sourceTree = "<group>"; };
|
||||
A1C9767618981BFE0057F881 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||
A1E7C4C8188D57F50010896F /* libStreamingKit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libStreamingKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1E7C4CB188D57F50010896F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
A1E7C4CF188D57F50010896F /* StreamingKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StreamingKit-Prefix.pch"; sourceTree = "<group>"; };
|
||||
@@ -56,28 +112,44 @@
|
||||
A1E7C4E7188D57F60010896F /* StreamingKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StreamingKitTests.m; sourceTree = "<group>"; };
|
||||
A1E7C4F1188D5E550010896F /* STKAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKAudioPlayer.h; sourceTree = "<group>"; };
|
||||
A1E7C4F2188D5E550010896F /* STKAudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKAudioPlayer.m; sourceTree = "<group>"; };
|
||||
A1E7C4F3188D5E550010896F /* STKAutoRecoveringHttpDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKAutoRecoveringHttpDataSource.h; sourceTree = "<group>"; };
|
||||
A1E7C4F4188D5E550010896F /* STKAutoRecoveringHttpDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKAutoRecoveringHttpDataSource.m; sourceTree = "<group>"; };
|
||||
A1E7C4F3188D5E550010896F /* STKAutoRecoveringHTTPDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKAutoRecoveringHTTPDataSource.h; sourceTree = "<group>"; };
|
||||
A1E7C4F4188D5E550010896F /* STKAutoRecoveringHTTPDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKAutoRecoveringHTTPDataSource.m; sourceTree = "<group>"; };
|
||||
A1E7C4F5188D5E550010896F /* STKCoreFoundationDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKCoreFoundationDataSource.h; sourceTree = "<group>"; };
|
||||
A1E7C4F6188D5E550010896F /* STKCoreFoundationDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKCoreFoundationDataSource.m; sourceTree = "<group>"; };
|
||||
A1E7C4F7188D5E550010896F /* STKDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKDataSource.h; sourceTree = "<group>"; };
|
||||
A1E7C4F8188D5E550010896F /* STKDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKDataSource.m; sourceTree = "<group>"; };
|
||||
A1E7C4F9188D5E550010896F /* STKDataSourceWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKDataSourceWrapper.h; sourceTree = "<group>"; };
|
||||
A1E7C4FA188D5E550010896F /* STKDataSourceWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKDataSourceWrapper.m; sourceTree = "<group>"; };
|
||||
A1E7C4FB188D5E550010896F /* STKHttpDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKHttpDataSource.h; sourceTree = "<group>"; };
|
||||
A1E7C4FC188D5E550010896F /* STKHttpDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKHttpDataSource.m; sourceTree = "<group>"; };
|
||||
A1E7C4FB188D5E550010896F /* STKHTTPDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKHTTPDataSource.h; sourceTree = "<group>"; };
|
||||
A1E7C4FC188D5E550010896F /* STKHTTPDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKHTTPDataSource.m; sourceTree = "<group>"; };
|
||||
A1E7C4FD188D5E550010896F /* STKLocalFileDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKLocalFileDataSource.h; sourceTree = "<group>"; };
|
||||
A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKLocalFileDataSource.m; sourceTree = "<group>"; };
|
||||
A1E7C507188D62D20010896F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
A1A49966189E744400E2A2E2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A4996B189E744400E2A2E2 /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1A49977189E744500E2A2E2 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A4997C189E744500E2A2E2 /* Cocoa.framework in Frameworks */,
|
||||
A1A4997B189E744500E2A2E2 /* XCTest.framework in Frameworks */,
|
||||
A1A4997F189E744500E2A2E2 /* libStreamingKitMac.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1E7C4C5188D57F50010896F /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1E7C508188D62D20010896F /* UIKit.framework in Frameworks */,
|
||||
A1E7C4CC188D57F50010896F /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -94,13 +166,71 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
A1A4996C189E744500E2A2E2 /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A4996D189E744500E2A2E2 /* Foundation.framework */,
|
||||
A1A4996E189E744500E2A2E2 /* CoreData.framework */,
|
||||
A1A4996F189E744500E2A2E2 /* AppKit.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A49970189E744500E2A2E2 /* StreamingKitMac */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A49973189E744500E2A2E2 /* StreamingKitMac.h */,
|
||||
A1A49974189E744500E2A2E2 /* StreamingKitMac.m */,
|
||||
A1A49971189E744500E2A2E2 /* Supporting Files */,
|
||||
);
|
||||
path = StreamingKitMac;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A49971189E744500E2A2E2 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A49972189E744500E2A2E2 /* StreamingKitMac-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A49980189E744500E2A2E2 /* StreamingKitMacTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A49986189E744500E2A2E2 /* StreamingKitMacTests.m */,
|
||||
A1A49981189E744500E2A2E2 /* Supporting Files */,
|
||||
);
|
||||
path = StreamingKitMacTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A49981189E744500E2A2E2 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A49982189E744500E2A2E2 /* StreamingKitMacTests-Info.plist */,
|
||||
A1A49983189E744500E2A2E2 /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1A499E2189E769A00E2A2E2 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499E7189E769A00E2A2E2 /* ExampleAppMac.app */,
|
||||
A1A499E9189E769A00E2A2E2 /* ExampleAppMacTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1E7C4BF188D57F50010896F = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1E7C4CD188D57F50010896F /* StreamingKit */,
|
||||
A1E7C4E1188D57F60010896F /* StreamingKitTests */,
|
||||
A1A49970189E744500E2A2E2 /* StreamingKitMac */,
|
||||
A1A49980189E744500E2A2E2 /* StreamingKitMacTests */,
|
||||
A1E7C4CA188D57F50010896F /* Frameworks */,
|
||||
A1E7C4C9188D57F50010896F /* Products */,
|
||||
A1A499E1189E769A00E2A2E2 /* ExampleAppMac.xcodeproj */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -109,6 +239,8 @@
|
||||
children = (
|
||||
A1E7C4C8188D57F50010896F /* libStreamingKit.a */,
|
||||
A1E7C4D8188D57F60010896F /* StreamingKitTests.xctest */,
|
||||
A1A49969189E744400E2A2E2 /* libStreamingKitMac.a */,
|
||||
A1A4997A189E744500E2A2E2 /* StreamingKitMacTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -116,9 +248,13 @@
|
||||
A1E7C4CA188D57F50010896F /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1A499F6189E79EA00E2A2E2 /* AudioToolbox.framework */,
|
||||
A1C9767618981BFE0057F881 /* AudioUnit.framework */,
|
||||
A1E7C507188D62D20010896F /* UIKit.framework */,
|
||||
A1E7C4CB188D57F50010896F /* Foundation.framework */,
|
||||
A1E7C4D9188D57F60010896F /* XCTest.framework */,
|
||||
A1A4996A189E744400E2A2E2 /* Cocoa.framework */,
|
||||
A1A4996C189E744500E2A2E2 /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -128,18 +264,22 @@
|
||||
children = (
|
||||
A1E7C4F1188D5E550010896F /* STKAudioPlayer.h */,
|
||||
A1E7C4F2188D5E550010896F /* STKAudioPlayer.m */,
|
||||
A1E7C4F3188D5E550010896F /* STKAutoRecoveringHttpDataSource.h */,
|
||||
A1E7C4F4188D5E550010896F /* STKAutoRecoveringHttpDataSource.m */,
|
||||
A1E7C4F3188D5E550010896F /* STKAutoRecoveringHTTPDataSource.h */,
|
||||
A1E7C4F4188D5E550010896F /* STKAutoRecoveringHTTPDataSource.m */,
|
||||
A1E7C4F5188D5E550010896F /* STKCoreFoundationDataSource.h */,
|
||||
A1E7C4F6188D5E550010896F /* STKCoreFoundationDataSource.m */,
|
||||
A1E7C4F7188D5E550010896F /* STKDataSource.h */,
|
||||
A1E7C4F8188D5E550010896F /* STKDataSource.m */,
|
||||
A1E7C4F9188D5E550010896F /* STKDataSourceWrapper.h */,
|
||||
A1E7C4FA188D5E550010896F /* STKDataSourceWrapper.m */,
|
||||
A1E7C4FB188D5E550010896F /* STKHttpDataSource.h */,
|
||||
A1E7C4FC188D5E550010896F /* STKHttpDataSource.m */,
|
||||
A1E7C4FB188D5E550010896F /* STKHTTPDataSource.h */,
|
||||
A1E7C4FC188D5E550010896F /* STKHTTPDataSource.m */,
|
||||
A1E7C4FD188D5E550010896F /* STKLocalFileDataSource.h */,
|
||||
A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */,
|
||||
A1BF65D0189A6582004DD08C /* STKQueueEntry.h */,
|
||||
A1BF65D1189A6582004DD08C /* STKQueueEntry.m */,
|
||||
A1BF65D3189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.h */,
|
||||
A1BF65D4189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m */,
|
||||
A1E7C4CE188D57F50010896F /* Supporting Files */,
|
||||
);
|
||||
path = StreamingKit;
|
||||
@@ -173,7 +313,52 @@
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
A1A49967189E744400E2A2E2 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
A1A49968189E744400E2A2E2 /* StreamingKitMac */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1A4998C189E744500E2A2E2 /* Build configuration list for PBXNativeTarget "StreamingKitMac" */;
|
||||
buildPhases = (
|
||||
A1A49965189E744400E2A2E2 /* Sources */,
|
||||
A1A49966189E744400E2A2E2 /* Frameworks */,
|
||||
A1A49967189E744400E2A2E2 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = StreamingKitMac;
|
||||
productName = StreamingKitMac;
|
||||
productReference = A1A49969189E744400E2A2E2 /* libStreamingKitMac.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
A1A49979189E744500E2A2E2 /* StreamingKitMacTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1A4998D189E744500E2A2E2 /* Build configuration list for PBXNativeTarget "StreamingKitMacTests" */;
|
||||
buildPhases = (
|
||||
A1A49976189E744500E2A2E2 /* Sources */,
|
||||
A1A49977189E744500E2A2E2 /* Frameworks */,
|
||||
A1A49978189E744500E2A2E2 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
A1A4997E189E744500E2A2E2 /* PBXTargetDependency */,
|
||||
);
|
||||
name = StreamingKitMacTests;
|
||||
productName = StreamingKitMacTests;
|
||||
productReference = A1A4997A189E744500E2A2E2 /* StreamingKitMacTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
A1E7C4C7188D57F50010896F /* StreamingKit */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1E7C4EB188D57F60010896F /* Build configuration list for PBXNativeTarget "StreamingKit" */;
|
||||
@@ -229,15 +414,48 @@
|
||||
mainGroup = A1E7C4BF188D57F50010896F;
|
||||
productRefGroup = A1E7C4C9188D57F50010896F /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = A1A499E2189E769A00E2A2E2 /* Products */;
|
||||
ProjectRef = A1A499E1189E769A00E2A2E2 /* ExampleAppMac.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
A1E7C4C7188D57F50010896F /* StreamingKit */,
|
||||
A1E7C4D7188D57F60010896F /* StreamingKitTests */,
|
||||
A1A49968189E744400E2A2E2 /* StreamingKitMac */,
|
||||
A1A49979189E744500E2A2E2 /* StreamingKitMacTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
A1A499E7189E769A00E2A2E2 /* ExampleAppMac.app */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.application;
|
||||
path = ExampleAppMac.app;
|
||||
remoteRef = A1A499E6189E769A00E2A2E2 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
A1A499E9189E769A00E2A2E2 /* ExampleAppMacTests.xctest */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
path = ExampleAppMacTests.xctest;
|
||||
remoteRef = A1A499E8189E769A00E2A2E2 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
A1A49978189E744500E2A2E2 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A49985189E744500E2A2E2 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1E7C4D6188D57F60010896F /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -249,6 +467,31 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
A1A49965189E744400E2A2E2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A4998F189E745C00E2A2E2 /* STKAutoRecoveringHTTPDataSource.m in Sources */,
|
||||
A1A49994189E746900E2A2E2 /* STKHTTPDataSource.m in Sources */,
|
||||
A1A49991189E746000E2A2E2 /* STKCoreFoundationDataSource.m in Sources */,
|
||||
A1A49995189E746B00E2A2E2 /* STKLocalFileDataSource.m in Sources */,
|
||||
A1A49997189E747000E2A2E2 /* NSMutableArray+STKAudioPlayer.m in Sources */,
|
||||
A1A4998E189E745900E2A2E2 /* STKAudioPlayer.m in Sources */,
|
||||
A1A49993189E746500E2A2E2 /* STKDataSourceWrapper.m in Sources */,
|
||||
A1A49992189E746300E2A2E2 /* STKDataSource.m in Sources */,
|
||||
A1A49975189E744500E2A2E2 /* StreamingKitMac.m in Sources */,
|
||||
A1A49996189E746E00E2A2E2 /* STKQueueEntry.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1A49976189E744500E2A2E2 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1A49987189E744500E2A2E2 /* StreamingKitMacTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1E7C4C4188D57F50010896F /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -256,10 +499,12 @@
|
||||
A1E7C501188D5E550010896F /* STKCoreFoundationDataSource.m in Sources */,
|
||||
A1E7C4FF188D5E550010896F /* STKAudioPlayer.m in Sources */,
|
||||
A1E7C505188D5E550010896F /* STKLocalFileDataSource.m in Sources */,
|
||||
A1E7C504188D5E550010896F /* STKHttpDataSource.m in Sources */,
|
||||
A1BF65D2189A6582004DD08C /* STKQueueEntry.m in Sources */,
|
||||
A1E7C504188D5E550010896F /* STKHTTPDataSource.m in Sources */,
|
||||
A1E7C503188D5E550010896F /* STKDataSourceWrapper.m in Sources */,
|
||||
A1E7C502188D5E550010896F /* STKDataSource.m in Sources */,
|
||||
A1E7C500188D5E550010896F /* STKAutoRecoveringHttpDataSource.m in Sources */,
|
||||
A1BF65D5189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m in Sources */,
|
||||
A1E7C500188D5E550010896F /* STKAutoRecoveringHTTPDataSource.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -274,6 +519,11 @@
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
A1A4997E189E744500E2A2E2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = A1A49968189E744400E2A2E2 /* StreamingKitMac */;
|
||||
targetProxy = A1A4997D189E744500E2A2E2 /* PBXContainerItemProxy */;
|
||||
};
|
||||
A1E7C4DF188D57F60010896F /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = A1E7C4C7188D57F50010896F /* StreamingKit */;
|
||||
@@ -282,6 +532,14 @@
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
A1A49983189E744500E2A2E2 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A1A49984189E744500E2A2E2 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1E7C4E4188D57F60010896F /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
@@ -293,6 +551,86 @@
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
A1A49988189E744500E2A2E2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1A49989189E744500E2A2E2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A1A4998A189E744500E2A2E2 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "StreamingKitMacTests/StreamingKitMacTests-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1A4998B189E744500E2A2E2 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch";
|
||||
INFOPLIST_FILE = "StreamingKitMacTests/StreamingKitMacTests-Info.plist";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = macosx;
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A1E7C4E9188D57F60010896F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -325,7 +663,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
@@ -357,7 +695,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
@@ -366,6 +704,7 @@
|
||||
A1E7C4EC188D57F60010896F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
DSTROOT = /tmp/StreamingKit.dst;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -382,6 +721,7 @@
|
||||
A1E7C4ED188D57F60010896F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
DSTROOT = /tmp/StreamingKit.dst;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -436,6 +776,22 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
A1A4998C189E744500E2A2E2 /* Build configuration list for PBXNativeTarget "StreamingKitMac" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1A49988189E744500E2A2E2 /* Debug */,
|
||||
A1A49989189E744500E2A2E2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
A1A4998D189E744500E2A2E2 /* Build configuration list for PBXNativeTarget "StreamingKitMacTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1A4998A189E744500E2A2E2 /* Debug */,
|
||||
A1A4998B189E744500E2A2E2 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
};
|
||||
A1E7C4C3188D57F50010896F /* Build configuration list for PBXProject "StreamingKit" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
@@ -452,6 +808,7 @@
|
||||
A1E7C4ED188D57F60010896F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A1E7C4EE188D57F60010896F /* Build configuration list for PBXNativeTarget "StreamingKitTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
@@ -460,6 +817,7 @@
|
||||
A1E7C4F0188D57F60010896F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// NSMutableArray+STKAudioPlayer.h
|
||||
// StreamingKit
|
||||
//
|
||||
// Created by Thong Nguyen on 30/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSMutableArray (STKAudioPlayer)
|
||||
-(void) enqueue:(id)obj;
|
||||
-(void) skipQueue:(id)obj;
|
||||
-(void) skipQueueWithQueue:(NSMutableArray*)queue;
|
||||
-(id) dequeue;
|
||||
-(id) peek;
|
||||
@end
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// NSMutableArray+STKAudioPlayer.m
|
||||
// StreamingKit
|
||||
//
|
||||
// Created by Thong Nguyen on 30/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSMutableArray+STKAudioPlayer.h"
|
||||
|
||||
@implementation NSMutableArray (STKAudioPlayer)
|
||||
|
||||
-(void) enqueue:(id)obj
|
||||
{
|
||||
[self insertObject:obj atIndex:0];
|
||||
}
|
||||
|
||||
-(void) skipQueue:(id)obj
|
||||
{
|
||||
[self addObject:obj];
|
||||
}
|
||||
|
||||
-(void) skipQueueWithQueue:(NSMutableArray*)queue
|
||||
{
|
||||
for (id item in queue)
|
||||
{
|
||||
[self addObject:item];
|
||||
}
|
||||
}
|
||||
|
||||
-(id) dequeue
|
||||
{
|
||||
if ([self count] == 0)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
id retval = [self lastObject];
|
||||
|
||||
[self removeLastObject];
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
-(id) peek
|
||||
{
|
||||
return [self lastObject];
|
||||
}
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,12 +2,12 @@
|
||||
AudioPlayer.m
|
||||
|
||||
Created by Thong Nguyen on 14/05/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
https://github.com/tumtumtum/StreamingKit
|
||||
|
||||
Inspired by Matt Gallagher's AudioStreamer:
|
||||
https://github.com/mattgallagher/AudioStreamer
|
||||
|
||||
Copyright (c) 2012 Thong Nguyen (tumtumtum@gmail.com). All rights reserved.
|
||||
Copyright (c) 2012-2014 Thong Nguyen (tumtumtum@gmail.com). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@@ -44,171 +44,170 @@
|
||||
#include "UIKit/UIApplication.h"
|
||||
#endif
|
||||
|
||||
#define AudioPlayerDefaultNumberOfAudioQueueBuffers (2 * 1024)
|
||||
typedef enum
|
||||
{
|
||||
STKAudioPlayerStateReady,
|
||||
STKAudioPlayerStateRunning = 1,
|
||||
STKAudioPlayerStatePlaying = (1 << 1) | STKAudioPlayerStateRunning,
|
||||
STKAudioPlayerStateBuffering = (1 << 2) | STKAudioPlayerStateRunning,
|
||||
STKAudioPlayerStatePaused = (1 << 3) | STKAudioPlayerStateRunning,
|
||||
STKAudioPlayerStateStopped = (1 << 4),
|
||||
STKAudioPlayerStateError = (1 << 5),
|
||||
STKAudioPlayerStateDisposed = (1 << 6)
|
||||
}
|
||||
STKAudioPlayerState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AudioPlayerInternalStateInitialised = 0,
|
||||
AudioPlayerInternalStateRunning = 1,
|
||||
AudioPlayerInternalStatePlaying = (1 << 1) | AudioPlayerInternalStateRunning,
|
||||
AudioPlayerInternalStateStartingThread = (1 << 2) | AudioPlayerInternalStateRunning,
|
||||
AudioPlayerInternalStateWaitingForData = (1 << 3) | AudioPlayerInternalStateRunning,
|
||||
AudioPlayerInternalStateWaitingForQueueToStart = (1 << 4) | AudioPlayerInternalStateRunning,
|
||||
AudioPlayerInternalStatePaused = (1 << 5) | AudioPlayerInternalStateRunning,
|
||||
AudioPlayerInternalStateRebuffering = (1 << 6) | AudioPlayerInternalStateRunning,
|
||||
AudioPlayerInternalStateStopping = (1 << 7),
|
||||
AudioPlayerInternalStateStopped = (1 << 8),
|
||||
AudioPlayerInternalStateDisposed = (1 << 9),
|
||||
AudioPlayerInternalStateError = (1 << 10)
|
||||
STKAudioPlayerStopReasonNone = 0,
|
||||
STKAudioPlayerStopReasonEof,
|
||||
STKAudioPlayerStopReasonUserAction,
|
||||
STKAudioPlayerStopReasonError = 0xffff
|
||||
}
|
||||
AudioPlayerInternalState;
|
||||
STKAudioPlayerStopReason;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AudioPlayerStateReady,
|
||||
AudioPlayerStateRunning = 1,
|
||||
AudioPlayerStatePlaying = (1 << 1) | AudioPlayerStateRunning,
|
||||
AudioPlayerStatePaused = (1 << 2) | AudioPlayerStateRunning,
|
||||
AudioPlayerStateStopped = (1 << 3),
|
||||
AudioPlayerStateError = (1 << 4),
|
||||
AudioPlayerStateDisposed = (1 << 5)
|
||||
STKAudioPlayerErrorNone = 0,
|
||||
STKAudioPlayerErrorDataSource,
|
||||
STKAudioPlayerErrorStreamParseBytesFailed,
|
||||
STKAudioPlayerErrorAudioSystemError,
|
||||
STKAudioPlayerErrorCodecError,
|
||||
STKAudioPlayerErrorDataNotFound,
|
||||
STKAudioPlayerErrorOther = 0xffff
|
||||
}
|
||||
AudioPlayerState;
|
||||
STKAudioPlayerErrorCode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AudioPlayerStopReasonNoStop = 0,
|
||||
AudioPlayerStopReasonEof,
|
||||
AudioPlayerStopReasonUserAction,
|
||||
AudioPlayerStopReasonUserActionFlushStop
|
||||
STKAudioPlayerOptionNone = 0,
|
||||
STKAudioPlayerOptionFlushQueueOnSeek = 1
|
||||
}
|
||||
AudioPlayerStopReason;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AudioPlayerErrorNone = 0,
|
||||
AudioPlayerErrorDataSource,
|
||||
AudioPlayerErrorStreamParseBytesFailed,
|
||||
AudioPlayerErrorDataNotFound,
|
||||
AudioPlayerErrorQueueStartFailed,
|
||||
AudioPlayerErrorQueuePauseFailed,
|
||||
AudioPlayerErrorUnknownBuffer,
|
||||
AudioPlayerErrorQueueStopFailed,
|
||||
AudioPlayerErrorOther
|
||||
}
|
||||
AudioPlayerErrorCode;
|
||||
STKAudioPlayerOptions;
|
||||
|
||||
@class STKAudioPlayer;
|
||||
|
||||
@protocol STKAudioPlayerDelegate <NSObject>
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(AudioPlayerState)state;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didEncounterError:(AudioPlayerErrorCode)errorCode;
|
||||
|
||||
/// Raised when an item has started playing
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didStartPlayingQueueItemId:(NSObject*)queueItemId;
|
||||
/// Raised when an item has finished buffering (may or may not be the currently playing item)
|
||||
/// This event may be raised multiple times for the same item if seek is invoked on the player
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishBufferingSourceWithQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(AudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration;
|
||||
/// Raised when the state of the player has changed
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state previousState:(STKAudioPlayerState)previousState;
|
||||
/// Raised when an item has finished playing
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(STKAudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration;
|
||||
/// Raised when an unexpected and possibly unrecoverable error has occured (usually best to recreate the STKAudioPlauyer)
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer unexpectedError:(STKAudioPlayerErrorCode)errorCode;
|
||||
@optional
|
||||
/// Optionally implemented to get logging information from the STKAudioPlayer (used internally for debugging)
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer logInfo:(NSString*)line;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer internalStateChanged:(AudioPlayerInternalState)state;
|
||||
-(void) audioPlayer: (STKAudioPlayer*)audioPlayer didCancelQueuedItems:(NSArray*)queuedItems;
|
||||
/// Raised when items queued items are cleared (usually because of a call to play, setDataSource or stop)
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didCancelQueuedItems:(NSArray*)queuedItems;
|
||||
|
||||
@end
|
||||
|
||||
@class QueueEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AudioQueueBufferRef ref;
|
||||
int bufferIndex;
|
||||
}
|
||||
AudioQueueBufferRefLookupEntry;
|
||||
typedef void(^STKFrameFilter)(UInt32 channelsPerFrame, UInt32 bytesPerFrame, UInt32 frameCount, void* frames);
|
||||
|
||||
@interface STKAudioPlayer : NSObject<STKDataSourceDelegate>
|
||||
{
|
||||
@private
|
||||
UInt8* readBuffer;
|
||||
int readBufferSize;
|
||||
|
||||
NSOperationQueue* fastApiQueue;
|
||||
|
||||
QueueEntry* currentlyPlayingEntry;
|
||||
QueueEntry* currentlyReadingEntry;
|
||||
|
||||
NSMutableArray* upcomingQueue;
|
||||
NSMutableArray* bufferingQueue;
|
||||
|
||||
AudioQueueBufferRef* audioQueueBuffer;
|
||||
AudioQueueBufferRefLookupEntry* audioQueueBufferLookup;
|
||||
unsigned int audioQueueBufferRefLookupCount;
|
||||
unsigned int audioQueueBufferCount;
|
||||
AudioStreamPacketDescription* packetDescs;
|
||||
bool* bufferUsed;
|
||||
int numberOfBuffersUsed;
|
||||
|
||||
AudioQueueRef audioQueue;
|
||||
AudioStreamBasicDescription currentAudioStreamBasicDescription;
|
||||
|
||||
NSThread* playbackThread;
|
||||
NSRunLoop* playbackThreadRunLoop;
|
||||
NSConditionLock* threadFinishedCondLock;
|
||||
|
||||
AudioFileStreamID audioFileStream;
|
||||
|
||||
BOOL discontinuous;
|
||||
|
||||
int bytesFilled;
|
||||
int packetsFilled;
|
||||
|
||||
int fillBufferIndex;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
UIBackgroundTaskIdentifier backgroundTaskId;
|
||||
#endif
|
||||
|
||||
AudioPlayerErrorCode errorCode;
|
||||
AudioPlayerStopReason stopReason;
|
||||
|
||||
int currentlyPlayingLock;
|
||||
pthread_mutex_t playerMutex;
|
||||
pthread_mutex_t queueBuffersMutex;
|
||||
pthread_cond_t queueBufferReadyCondition;
|
||||
|
||||
volatile BOOL waiting;
|
||||
volatile BOOL disposeWasRequested;
|
||||
volatile BOOL seekToTimeWasRequested;
|
||||
volatile BOOL newFileToPlay;
|
||||
volatile double requestedSeekTime;
|
||||
volatile BOOL audioQueueFlushing;
|
||||
volatile SInt64 audioPacketsReadCount;
|
||||
volatile SInt64 audioPacketsPlayedCount;
|
||||
|
||||
BOOL meteringEnabled;
|
||||
AudioQueueLevelMeterState* levelMeterState;
|
||||
NSInteger numberOfChannels;
|
||||
}
|
||||
|
||||
/// Gets or sets the player muted state
|
||||
@property (readwrite) BOOL muted;
|
||||
/// Gets the current item duration in seconds
|
||||
@property (readonly) double duration;
|
||||
/// Gets the current item progress in seconds
|
||||
@property (readonly) double progress;
|
||||
@property (readwrite) AudioPlayerState state;
|
||||
@property (readonly) AudioPlayerStopReason stopReason;
|
||||
@property (readwrite, unsafe_unretained) id<STKAudioPlayerDelegate> delegate;
|
||||
/// Enables or disables peak and average decibel meteting
|
||||
@property (readwrite) BOOL meteringEnabled;
|
||||
/// Returns an array of STKFrameFilterEntry objects representing the filters currently in use
|
||||
@property (readonly) NSArray* frameFilters;
|
||||
/// Returns the items pending to be played (includes buffering and upcoming items but does not include the current item)
|
||||
@property (readonly) NSArray* pendingQueue;
|
||||
/// The number of items pending to be played (includes buffering and upcoming items but does not include the current item)
|
||||
@property (readonly) NSUInteger pendingQueueCount;
|
||||
/// Gets the most recently queued item that is still pending to play
|
||||
@property (readonly) NSObject* mostRecentlyQueuedStillPendingItem;
|
||||
/// Gets the current state of the player
|
||||
@property (readwrite) STKAudioPlayerState state;
|
||||
/// Gets the options provided to the player on startup
|
||||
@property (readonly) STKAudioPlayerOptions options;
|
||||
/// Gets the reason why the player is stopped (if any)
|
||||
@property (readonly) STKAudioPlayerStopReason stopReason;
|
||||
/// Gets and sets the delegate used for receiving events from the STKAudioPlayer
|
||||
@property (readwrite, unsafe_unretained) id<STKAudioPlayerDelegate> delegate;
|
||||
|
||||
/// Creates a datasource from a given URL.
|
||||
/// URLs with FILE schemes will return an STKLocalFileDataSource.
|
||||
/// URLs with HTTP schemes will return an STKHTTPDataSource wrapped within an STKAutoRecoveringHTTPDataSource.
|
||||
/// URLs with unrecognised schemes will return nil.
|
||||
+(STKDataSource*) dataSourceFromURL:(NSURL*)url;
|
||||
|
||||
/// Initializes a new STKAudioPlayer with the default options
|
||||
-(id) init;
|
||||
-(id) initWithNumberOfAudioQueueBuffers:(int)numberOfAudioQueueBuffers andReadBufferSize:(int)readBufferSizeIn;
|
||||
-(STKDataSource*) dataSourceFromURL:(NSURL*)url;
|
||||
-(void) play:(NSURL*)url;
|
||||
|
||||
/// Initializes a new STKAudioPlayer with the given options
|
||||
-(id) initWithOptions:(STKAudioPlayerOptions)optionsIn;
|
||||
|
||||
/// Plays an item from the given URL (all pending queued items are removed)
|
||||
-(void) play:(NSString*)urlString;
|
||||
|
||||
/// Plays an item from the given URL (all pending queued items are removed)
|
||||
-(void) playWithURL:(NSURL*)url;
|
||||
|
||||
/// Plays the given item (all pending queued items are removed)
|
||||
-(void) playWithDataSource:(STKDataSource*)dataSource;
|
||||
|
||||
/// Queues a DataSource with te given Item ID for playback
|
||||
-(void) queueDataSource:(STKDataSource*)dataSource withQueueItemId:(NSObject*)queueItemId;
|
||||
|
||||
/// Plays the given item (all pending queued items are removed)
|
||||
-(void) setDataSource:(STKDataSource*)dataSourceIn withQueueItemId:(NSObject*)queueItemId;
|
||||
|
||||
/// Seeks to a specific time (in seconds)
|
||||
-(void) seekToTime:(double)value;
|
||||
|
||||
/// Clears any upcoming items already queued for playback (does not stop the current item).
|
||||
/// The didCancelItems event will be raised for the items removed from the queue.
|
||||
-(void) clearQueue;
|
||||
|
||||
/// Pauses playback
|
||||
-(void) pause;
|
||||
|
||||
/// Resumes playback from pause
|
||||
-(void) resume;
|
||||
|
||||
/// Stops playback of the current file, flushes all the buffers and removes any pending queued items
|
||||
-(void) stop;
|
||||
-(void) flushStop;
|
||||
|
||||
/// Mutes playback
|
||||
-(void) mute;
|
||||
|
||||
/// Unmutes playback
|
||||
-(void) unmute;
|
||||
|
||||
/// Disposes the STKAudioPlayer and frees up all resources before returning
|
||||
-(void) dispose;
|
||||
|
||||
/// The QueueItemId of the currently playing item
|
||||
-(NSObject*) currentlyPlayingQueueItemId;
|
||||
-(void) updateMeters;
|
||||
|
||||
/// Removes a frame filter with the given name
|
||||
-(void) removeFrameFilterWithName:(NSString*)name;
|
||||
|
||||
/// Appends a frame filter with the given name and filter block to the end of the filter chain
|
||||
-(void) appendFrameFilterWithName:(NSString*)name block:(STKFrameFilter)block;
|
||||
|
||||
/// Appends a frame filter with the given name and filter block just after the filter with the given name.
|
||||
/// If the given name is nil, the filter will be inserted at the beginning of the filter change
|
||||
-(void) addFrameFilterWithName:(NSString*)name afterFilterWithName:(NSString*)afterFilterWithName block:(STKFrameFilter)block;
|
||||
|
||||
/// Reads the peak power in decibals for the given channel (0 or 1).
|
||||
/// Return values are between -60 (low) and 0 (high).
|
||||
-(float) peakPowerInDecibelsForChannel:(NSUInteger)channelNumber;
|
||||
|
||||
/// Reads the average power in decibals for the given channel (0 or 1)
|
||||
/// Return values are between -60 (low) and 0 (high).
|
||||
-(float) averagePowerInDecibelsForChannel:(NSUInteger)channelNumber;
|
||||
|
||||
@end
|
||||
|
||||
+1810
-1509
File diff suppressed because it is too large
Load Diff
+5
-5
@@ -4,7 +4,7 @@
|
||||
Created by Thong Nguyen on 16/10/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 Thong Nguyen (tumtumtum@gmail.com). All rights reserved.
|
||||
Copyright (c) 2012-2014 Thong Nguyen (tumtumtum@gmail.com). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@@ -33,13 +33,13 @@
|
||||
**********************************************************************************/
|
||||
|
||||
#import "STKDataSource.h"
|
||||
#import "STKHttpDataSource.h"
|
||||
#import "STKHTTPDataSource.h"
|
||||
#import "STKDataSourceWrapper.h"
|
||||
|
||||
@interface STKAutoRecoveringHttpDataSource : STKDataSourceWrapper
|
||||
@interface STKAutoRecoveringHTTPDataSource : STKDataSourceWrapper
|
||||
|
||||
-(id) initWithHttpDataSource:(STKHttpDataSource*)innerDataSource;
|
||||
-(id) initWithHTTPDataSource:(STKHTTPDataSource*)innerDataSource;
|
||||
|
||||
@property (readonly) STKHttpDataSource* innerDataSource;
|
||||
@property (readonly) STKHTTPDataSource* innerDataSource;
|
||||
|
||||
@end
|
||||
+54
-28
@@ -4,7 +4,7 @@
|
||||
Created by Thong Nguyen on 16/10/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 Thong Nguyen (tumtumtum@gmail.com). All rights reserved.
|
||||
Copyright (c) 2012-2014 Thong Nguyen (tumtumtum@gmail.com). All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@@ -40,14 +40,14 @@
|
||||
#import <netdb.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#import "STKAutoRecoveringHttpDataSource.h"
|
||||
#import "STKAutoRecoveringHTTPDataSource.h"
|
||||
|
||||
#define MAX_IMMEDIATE_RECONNECT_ATTEMPTS (8)
|
||||
#define MAX_ATTEMPTS_WITH_SERVER_ERROR (MAX_IMMEDIATE_RECONNECT_ATTEMPTS + 2)
|
||||
#define MAX_IMMEDIATE_RECONNECT_ATTEMPTS (2)
|
||||
|
||||
@interface STKAutoRecoveringHttpDataSource()
|
||||
@interface STKAutoRecoveringHTTPDataSource()
|
||||
{
|
||||
int reconnectAttempts;
|
||||
int serial;
|
||||
int waitSeconds;
|
||||
BOOL waitingForNetwork;
|
||||
SCNetworkReachabilityRef reachabilityRef;
|
||||
}
|
||||
@@ -60,20 +60,25 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
STKAutoRecoveringHttpDataSource* dataSource = (__bridge STKAutoRecoveringHttpDataSource*)info;
|
||||
STKAutoRecoveringHTTPDataSource* dataSource = (__bridge STKAutoRecoveringHTTPDataSource*)info;
|
||||
|
||||
[dataSource reachabilityChanged];
|
||||
}
|
||||
}
|
||||
|
||||
@implementation STKAutoRecoveringHttpDataSource
|
||||
@implementation STKAutoRecoveringHTTPDataSource
|
||||
|
||||
-(STKHttpDataSource*) innerHttpDataSource
|
||||
-(STKHTTPDataSource*) innerHTTPDataSource
|
||||
{
|
||||
return (STKHttpDataSource*)self.innerDataSource;
|
||||
return (STKHTTPDataSource*)self.innerDataSource;
|
||||
}
|
||||
|
||||
-(id) initWithHttpDataSource:(STKHttpDataSource*)innerDataSourceIn
|
||||
-(id) initWithDataSource:(STKDataSource *)innerDataSource
|
||||
{
|
||||
return [self initWithHTTPDataSource:(STKHTTPDataSource*)innerDataSource];
|
||||
}
|
||||
|
||||
-(id) initWithHTTPDataSource:(STKHTTPDataSource*)innerDataSourceIn
|
||||
{
|
||||
if (self = [super initWithDataSource:innerDataSourceIn])
|
||||
{
|
||||
@@ -117,6 +122,8 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
|
||||
-(void) unregisterForEvents
|
||||
{
|
||||
[super unregisterForEvents];
|
||||
|
||||
[self stopNotifier];
|
||||
}
|
||||
|
||||
@@ -125,7 +132,7 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
if (reachabilityRef != NULL)
|
||||
{
|
||||
SCNetworkReachabilitySetCallback(reachabilityRef, NULL, NULL);
|
||||
SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, [self.innerDataSource.eventsRunLoop getCFRunLoop], kCFRunLoopDefaultMode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +150,8 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
|
||||
-(void) dealloc
|
||||
{
|
||||
NSLog(@"STKAutoRecoveringHTTPDataSource dealloc");
|
||||
|
||||
self.innerDataSource.delegate = nil;
|
||||
|
||||
[self stopNotifier];
|
||||
@@ -161,24 +170,35 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
{
|
||||
waitingForNetwork = NO;
|
||||
|
||||
[self attemptReconnect];
|
||||
[self attemptReconnectWithSerial:@(serial)];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) dataSourceDataAvailable:(STKDataSource*)dataSource
|
||||
{
|
||||
reconnectAttempts = 0;
|
||||
|
||||
serial++;
|
||||
waitSeconds = 1;
|
||||
|
||||
[super dataSourceDataAvailable:dataSource];
|
||||
}
|
||||
|
||||
-(void) attemptReconnect
|
||||
-(void) attemptReconnectWithSerial:(NSNumber*)serialIn
|
||||
{
|
||||
reconnectAttempts++;
|
||||
if (serialIn.intValue != self->serial)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"attemptReconnect %lld/%lld", self.position, self.length);
|
||||
|
||||
[self seekToOffset:self.position];
|
||||
}
|
||||
|
||||
-(void) attemptReconnectWithTimer:(NSTimer*)timer
|
||||
{
|
||||
[self attemptReconnectWithSerial:(NSNumber*)timer.userInfo];
|
||||
}
|
||||
|
||||
-(void) processRetryOnError
|
||||
{
|
||||
if (![self hasGotNetworkConnection])
|
||||
@@ -188,23 +208,29 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(self.innerDataSource.httpStatusCode >= 200 && self.innerDataSource.httpStatusCode <= 299) && reconnectAttempts >= MAX_ATTEMPTS_WITH_SERVER_ERROR)
|
||||
waitingForNetwork = NO;
|
||||
|
||||
NSRunLoop* runLoop = self.innerDataSource.eventsRunLoop;
|
||||
|
||||
if (runLoop == nil)
|
||||
{
|
||||
[super dataSourceErrorOccured:self];
|
||||
}
|
||||
else if (reconnectAttempts > MAX_IMMEDIATE_RECONNECT_ATTEMPTS)
|
||||
{
|
||||
[self performSelector:@selector(attemptReconnect) withObject:nil afterDelay:5];
|
||||
[self performSelector:@selector(attemptReconnectWithSerial:) withObject:@(serial) afterDelay:waitSeconds];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self attemptReconnect];
|
||||
NSTimer* timer = [NSTimer timerWithTimeInterval:waitSeconds target:self selector:@selector(attemptReconnectWithTimer:) userInfo:@(serial) repeats:NO];
|
||||
|
||||
[runLoop addTimer:timer forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
waitSeconds = MIN(waitSeconds + 1, 5);
|
||||
}
|
||||
|
||||
-(void) dataSourceEof:(STKDataSource*)dataSource
|
||||
{
|
||||
if ([self position] != [self length])
|
||||
NSLog(@"dataSourceEof");
|
||||
|
||||
if ([self position] < [self length])
|
||||
{
|
||||
[self processRetryOnError];
|
||||
|
||||
@@ -216,6 +242,8 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
|
||||
-(void) dataSourceErrorOccured:(STKDataSource*)dataSource
|
||||
{
|
||||
NSLog(@"dataSourceErrorOccured");
|
||||
|
||||
if (self.innerDataSource.httpStatusCode == 416 /* Range out of bounds */)
|
||||
{
|
||||
[super dataSourceEof:dataSource];
|
||||
@@ -224,13 +252,11 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
{
|
||||
[self processRetryOnError];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(NSString*) description
|
||||
{
|
||||
return [NSString stringWithFormat:@"Auto-recovering HTTP data source with file length: %lld and position: %lld", self.length, self.position];
|
||||
|
||||
return [NSString stringWithFormat:@"HTTP data source with file length: %lld and position: %lld", self.length, self.position];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -44,14 +44,19 @@
|
||||
@interface STKCoreFoundationDataSource : STKDataSource
|
||||
{
|
||||
@protected
|
||||
BOOL isInErrorState;
|
||||
CFReadStreamRef stream;
|
||||
NSRunLoop* eventsRunLoop;
|
||||
}
|
||||
|
||||
@property (readonly) BOOL isInErrorState;
|
||||
|
||||
-(BOOL) reregisterForEvents;
|
||||
|
||||
-(void) open;
|
||||
-(void) dataAvailable;
|
||||
-(void) eof;
|
||||
-(void) errorOccured;
|
||||
-(CFStreamStatus) status;
|
||||
|
||||
@end
|
||||
|
||||
@@ -60,6 +60,11 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
|
||||
@implementation STKCoreFoundationDataSource
|
||||
|
||||
-(BOOL) isInErrorState
|
||||
{
|
||||
return self->isInErrorState;
|
||||
}
|
||||
|
||||
-(void) dataAvailable
|
||||
{
|
||||
[self.delegate dataSourceDataAvailable:self];
|
||||
@@ -72,6 +77,8 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
|
||||
-(void) errorOccured
|
||||
{
|
||||
self->isInErrorState = YES;
|
||||
|
||||
[self.delegate dataSourceErrorOccured:self];
|
||||
}
|
||||
|
||||
@@ -79,7 +86,10 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
{
|
||||
if (stream)
|
||||
{
|
||||
[self unregisterForEvents];
|
||||
if (eventsRunLoop)
|
||||
{
|
||||
[self unregisterForEvents];
|
||||
}
|
||||
|
||||
[self close];
|
||||
|
||||
@@ -98,6 +108,10 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
}
|
||||
}
|
||||
|
||||
-(void) open
|
||||
{
|
||||
}
|
||||
|
||||
-(void) seekToOffset:(long long)offset
|
||||
{
|
||||
}
|
||||
@@ -133,19 +147,21 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
-(BOOL) registerForEvents:(NSRunLoop*)runLoop
|
||||
{
|
||||
eventsRunLoop = runLoop;
|
||||
|
||||
if (stream)
|
||||
{
|
||||
CFStreamClientContext context = {0, (__bridge void*)self, NULL, NULL, NULL};
|
||||
|
||||
CFReadStreamSetClient(stream, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, ReadStreamCallbackProc, &context);
|
||||
|
||||
CFReadStreamScheduleWithRunLoop(stream, [eventsRunLoop getCFRunLoop], kCFRunLoopCommonModes);
|
||||
|
||||
if (!stream)
|
||||
{
|
||||
[self open];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
CFStreamClientContext context = {0, (__bridge void*)self, NULL, NULL, NULL};
|
||||
|
||||
return NO;
|
||||
CFReadStreamSetClient(stream, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, ReadStreamCallbackProc, &context);
|
||||
|
||||
CFReadStreamScheduleWithRunLoop(stream, [eventsRunLoop getCFRunLoop], kCFRunLoopCommonModes);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(BOOL) hasBytesAvailable
|
||||
@@ -158,4 +174,14 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
return CFReadStreamHasBytesAvailable(stream);
|
||||
}
|
||||
|
||||
-(CFStreamStatus) status
|
||||
{
|
||||
if (stream)
|
||||
{
|
||||
return CFReadStreamGetStatus(stream);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+11
-11
@@ -34,21 +34,21 @@
|
||||
|
||||
#import "STKCoreFoundationDataSource.h"
|
||||
|
||||
@interface STKHttpDataSource : STKCoreFoundationDataSource
|
||||
{
|
||||
@private
|
||||
int seekStart;
|
||||
int relativePosition;
|
||||
long long fileLength;
|
||||
int discontinuous;
|
||||
NSDictionary* httpHeaders;
|
||||
AudioFileTypeID audioFileTypeHint;
|
||||
}
|
||||
@class STKHTTPDataSource;
|
||||
|
||||
@property (readwrite, retain) NSURL* url;
|
||||
typedef void(^STKURLBlock)(NSURL* url);
|
||||
typedef NSURL*(^STKURLProvider)();
|
||||
typedef void(^STKAsyncURLProvider)(STKHTTPDataSource* dataSource, BOOL forSeek, STKURLBlock callback);
|
||||
|
||||
@interface STKHTTPDataSource : STKCoreFoundationDataSource
|
||||
|
||||
@property (readonly, retain) NSURL* url;
|
||||
@property (readwrite) UInt32 httpStatusCode;
|
||||
|
||||
+(AudioFileTypeID) audioFileTypeHintFromMimeType:(NSString*)fileExtension;
|
||||
-(id) initWithURL:(NSURL*)url;
|
||||
-(id) initWithURLProvider:(STKURLProvider)urlProvider;
|
||||
-(id) initWithAsyncURLProvider:(STKAsyncURLProvider)asyncUrlProvider;
|
||||
-(NSRunLoop*) eventsRunLoop;
|
||||
|
||||
@end
|
||||
+188
-98
@@ -32,17 +32,43 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "STKHttpDataSource.h"
|
||||
#import "STKHTTPDataSource.h"
|
||||
#import "STKLocalFileDataSource.h"
|
||||
|
||||
@interface STKHttpDataSource()
|
||||
@interface STKHTTPDataSource()
|
||||
{
|
||||
@private
|
||||
long long seekStart;
|
||||
long long relativePosition;
|
||||
long long fileLength;
|
||||
int discontinuous;
|
||||
NSURL* currentUrl;
|
||||
STKAsyncURLProvider asyncUrlProvider;
|
||||
NSDictionary* httpHeaders;
|
||||
AudioFileTypeID audioFileTypeHint;
|
||||
}
|
||||
-(void) open;
|
||||
|
||||
@end
|
||||
|
||||
@implementation STKHttpDataSource
|
||||
@synthesize url;
|
||||
@implementation STKHTTPDataSource
|
||||
|
||||
-(id) initWithURL:(NSURL*)urlIn
|
||||
{
|
||||
return [self initWithURLProvider:^NSURL* { return urlIn; }];
|
||||
}
|
||||
|
||||
-(id) initWithURLProvider:(STKURLProvider)urlProviderIn
|
||||
{
|
||||
urlProviderIn = [urlProviderIn copy];
|
||||
|
||||
return [self initWithAsyncURLProvider:^(STKHTTPDataSource* dataSource, BOOL forSeek, STKURLBlock block)
|
||||
{
|
||||
block(urlProviderIn());
|
||||
}];
|
||||
}
|
||||
|
||||
-(id) initWithAsyncURLProvider:(STKAsyncURLProvider)asyncUrlProviderIn
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
@@ -50,16 +76,24 @@
|
||||
relativePosition = 0;
|
||||
fileLength = -1;
|
||||
|
||||
self.url = urlIn;
|
||||
self->asyncUrlProvider = [asyncUrlProviderIn copy];
|
||||
|
||||
[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;
|
||||
@@ -104,40 +138,61 @@
|
||||
|
||||
-(void) dataAvailable
|
||||
{
|
||||
if (fileLength < 0)
|
||||
{
|
||||
CFTypeRef response = CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader);
|
||||
if (self.httpStatusCode == 0)
|
||||
{
|
||||
CFTypeRef response = CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader);
|
||||
|
||||
httpHeaders = (__bridge_transfer NSDictionary*)CFHTTPMessageCopyAllHeaderFields((CFHTTPMessageRef)response);
|
||||
|
||||
self.httpStatusCode = CFHTTPMessageGetResponseStatusCode((CFHTTPMessageRef)response);
|
||||
|
||||
CFRelease(response);
|
||||
|
||||
if (self.httpStatusCode == 200)
|
||||
{
|
||||
if (seekStart == 0)
|
||||
{
|
||||
fileLength = (long long)[[httpHeaders objectForKey:@"Content-Length"] integerValue];
|
||||
}
|
||||
|
||||
NSString* contentType = [httpHeaders objectForKey:@"Content-Type"];
|
||||
AudioFileTypeID typeIdFromMimeType = [STKHttpDataSource audioFileTypeHintFromMimeType:contentType];
|
||||
|
||||
if (typeIdFromMimeType != 0)
|
||||
{
|
||||
audioFileTypeHint = typeIdFromMimeType;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self errorOccured];
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[super dataAvailable];
|
||||
|
||||
if (self.httpStatusCode == 200)
|
||||
{
|
||||
if (seekStart == 0)
|
||||
{
|
||||
fileLength = (long long)[[httpHeaders objectForKey:@"Content-Length"] integerValue];
|
||||
}
|
||||
|
||||
NSString* contentType = [httpHeaders objectForKey:@"Content-Type"];
|
||||
AudioFileTypeID typeIdFromMimeType = [STKHTTPDataSource audioFileTypeHintFromMimeType:contentType];
|
||||
|
||||
if (typeIdFromMimeType != 0)
|
||||
{
|
||||
audioFileTypeHint = typeIdFromMimeType;
|
||||
}
|
||||
}
|
||||
else if (self.httpStatusCode == 206)
|
||||
{
|
||||
NSString* contentRange = [httpHeaders objectForKey:@"Content-Range"];
|
||||
NSArray* components = [contentRange componentsSeparatedByString:@"/"];
|
||||
|
||||
if (components.count == 2)
|
||||
{
|
||||
fileLength = [[components objectAtIndex:1] integerValue];
|
||||
}
|
||||
}
|
||||
else if (self.httpStatusCode == 416)
|
||||
{
|
||||
if (self.length >= 0)
|
||||
{
|
||||
seekStart = self.length;
|
||||
}
|
||||
|
||||
[self eof];
|
||||
|
||||
return;
|
||||
}
|
||||
else if (self.httpStatusCode >= 300)
|
||||
{
|
||||
[self errorOccured];
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[super dataAvailable];
|
||||
}
|
||||
|
||||
-(long long) position
|
||||
@@ -162,13 +217,16 @@
|
||||
CFReadStreamClose(stream);
|
||||
CFRelease(stream);
|
||||
}
|
||||
|
||||
NSAssert([NSRunLoop currentRunLoop] == eventsRunLoop, @"Seek called on wrong thread");
|
||||
|
||||
stream = 0;
|
||||
relativePosition = 0;
|
||||
seekStart = (int)offset;
|
||||
seekStart = offset;
|
||||
|
||||
[self open];
|
||||
[self reregisterForEvents];
|
||||
self->isInErrorState = NO;
|
||||
|
||||
[self openForSeek:YES];
|
||||
}
|
||||
|
||||
-(int) readIntoBuffer:(UInt8*)buffer withSize:(int)size
|
||||
@@ -192,67 +250,99 @@
|
||||
|
||||
-(void) open
|
||||
{
|
||||
CFHTTPMessageRef message = CFHTTPMessageCreateRequest(NULL, (CFStringRef)@"GET", (__bridge CFURLRef)self.url, kCFHTTPVersion1_1);
|
||||
|
||||
if (seekStart > 0)
|
||||
{
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Range"), (__bridge CFStringRef)[NSString stringWithFormat:@"bytes=%d-", seekStart]);
|
||||
|
||||
discontinuous = YES;
|
||||
}
|
||||
|
||||
stream = CFReadStreamCreateForHTTPRequest(NULL, message);
|
||||
|
||||
if (stream == nil)
|
||||
{
|
||||
CFRelease(message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CFReadStreamSetProperty(stream, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue))
|
||||
{
|
||||
CFRelease(message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Proxy support
|
||||
|
||||
CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings();
|
||||
CFReadStreamSetProperty(stream, kCFStreamPropertyHTTPProxy, proxySettings);
|
||||
CFRelease(proxySettings);
|
||||
|
||||
// SSL support
|
||||
|
||||
if ([url.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame)
|
||||
{
|
||||
NSDictionary* sslSettings = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
(NSString*)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamSSLLevel,
|
||||
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
|
||||
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots,
|
||||
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
|
||||
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
|
||||
[NSNull null], kCFStreamSSLPeerName,
|
||||
nil];
|
||||
|
||||
CFReadStreamSetProperty(stream, kCFStreamPropertySSLSettings, (__bridge CFTypeRef)sslSettings);
|
||||
}
|
||||
|
||||
// Open
|
||||
|
||||
if (!CFReadStreamOpen(stream))
|
||||
{
|
||||
CFRelease(stream);
|
||||
CFRelease(message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CFRelease(message);
|
||||
return [self openForSeek:NO];
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
-(void) openForSeek:(BOOL)forSeek
|
||||
{
|
||||
asyncUrlProvider(self, forSeek, ^(NSURL* url)
|
||||
{
|
||||
self->currentUrl = url;
|
||||
|
||||
if (url == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CFHTTPMessageRef message = CFHTTPMessageCreateRequest(NULL, (CFStringRef)@"GET", (__bridge CFURLRef)self->currentUrl, kCFHTTPVersion1_1);
|
||||
|
||||
if (seekStart > 0)
|
||||
{
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Range"), (__bridge CFStringRef)[NSString stringWithFormat:@"bytes=%lld-", seekStart]);
|
||||
|
||||
discontinuous = YES;
|
||||
}
|
||||
|
||||
stream = CFReadStreamCreateForHTTPRequest(NULL, message);
|
||||
|
||||
if (stream == nil)
|
||||
{
|
||||
CFRelease(message);
|
||||
|
||||
[self errorOccured];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CFReadStreamSetProperty(stream, kCFStreamPropertyHTTPShouldAutoredirect, kCFBooleanTrue))
|
||||
{
|
||||
CFRelease(message);
|
||||
|
||||
[self errorOccured];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Proxy support
|
||||
|
||||
CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings();
|
||||
CFReadStreamSetProperty(stream, kCFStreamPropertyHTTPProxy, proxySettings);
|
||||
CFRelease(proxySettings);
|
||||
|
||||
// SSL support
|
||||
|
||||
if ([self->currentUrl.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame)
|
||||
{
|
||||
NSDictionary* sslSettings = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
(NSString*)kCFStreamSocketSecurityLevelNegotiatedSSL, kCFStreamSSLLevel,
|
||||
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
|
||||
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots,
|
||||
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
|
||||
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
|
||||
[NSNull null], kCFStreamSSLPeerName,
|
||||
nil];
|
||||
|
||||
CFReadStreamSetProperty(stream, kCFStreamPropertySSLSettings, (__bridge CFTypeRef)sslSettings);
|
||||
}
|
||||
|
||||
[self reregisterForEvents];
|
||||
|
||||
self.httpStatusCode = 0;
|
||||
|
||||
// Open
|
||||
|
||||
if (!CFReadStreamOpen(stream))
|
||||
{
|
||||
CFRelease(stream);
|
||||
CFRelease(message);
|
||||
|
||||
[self errorOccured];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self->isInErrorState = NO;
|
||||
|
||||
CFRelease(message);
|
||||
});
|
||||
}
|
||||
|
||||
-(NSRunLoop*) eventsRunLoop
|
||||
{
|
||||
return self->eventsRunLoop;
|
||||
}
|
||||
|
||||
-(NSString*) description
|
||||
{
|
||||
return [NSString stringWithFormat:@"HTTP data source with file length: %lld and position: %lld", self.length, self.position];
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -49,8 +53,6 @@
|
||||
{
|
||||
self.filePath = filePathIn;
|
||||
|
||||
[self open];
|
||||
|
||||
audioFileTypeHint = [STKLocalFileDataSource audioFileTypeHintFromFileExtension:filePathIn.pathExtension];
|
||||
}
|
||||
|
||||
@@ -103,6 +105,8 @@
|
||||
{
|
||||
if (stream)
|
||||
{
|
||||
[self unregisterForEvents];
|
||||
|
||||
CFReadStreamClose(stream);
|
||||
|
||||
stream = 0;
|
||||
@@ -111,26 +115,23 @@
|
||||
|
||||
-(void) open
|
||||
{
|
||||
NSURL* url = [[NSURL alloc] initFileURLWithPath:self.filePath];
|
||||
|
||||
if (stream)
|
||||
{
|
||||
[self unregisterForEvents];
|
||||
|
||||
CFReadStreamClose(stream);
|
||||
CFRelease(stream);
|
||||
|
||||
stream = 0;
|
||||
}
|
||||
|
||||
NSURL* url = [[NSURL alloc] initFileURLWithPath:self.filePath];
|
||||
|
||||
stream = CFReadStreamCreateWithFile(NULL, (__bridge CFURLRef)url);
|
||||
|
||||
NSError *fileError;
|
||||
|
||||
NSFileManager *manager = [[NSFileManager alloc] init];
|
||||
|
||||
NSString *path = [NSString stringWithUTF8String:[url fileSystemRepresentation]];
|
||||
|
||||
NSDictionary *attributes = [manager attributesOfItemAtPath:path
|
||||
error:&fileError];
|
||||
NSError* fileError;
|
||||
NSFileManager* manager = [[NSFileManager alloc] init];
|
||||
NSDictionary* attributes = [manager attributesOfItemAtPath:filePath error:&fileError];
|
||||
|
||||
if (fileError)
|
||||
{
|
||||
@@ -141,13 +142,14 @@
|
||||
}
|
||||
|
||||
NSNumber* number = [attributes objectForKey:@"NSFileSize"];
|
||||
|
||||
|
||||
if (number)
|
||||
{
|
||||
length = number.longLongValue;
|
||||
}
|
||||
|
||||
[self reregisterForEvents];
|
||||
|
||||
CFReadStreamOpen(stream);
|
||||
}
|
||||
|
||||
@@ -196,7 +198,6 @@
|
||||
|
||||
[self close];
|
||||
[self open];
|
||||
[self reregisterForEvents];
|
||||
}
|
||||
|
||||
if (CFReadStreamSetProperty(stream, kCFStreamPropertyFileCurrentOffset, (__bridge CFTypeRef)[NSNumber numberWithLongLong:offset]) != TRUE)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// STKQueueEntry.h
|
||||
// StreamingKit
|
||||
//
|
||||
// Created by Thong Nguyen on 30/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import "STKDataSource.h"
|
||||
#import "libkern/OSAtomic.h"
|
||||
#import "AudioToolbox/AudioToolbox.h"
|
||||
|
||||
@interface STKQueueEntry : NSObject
|
||||
{
|
||||
@public
|
||||
OSSpinLock spinLock;
|
||||
|
||||
BOOL parsedHeader;
|
||||
Float64 sampleRate;
|
||||
double packetDuration;
|
||||
UInt64 audioDataOffset;
|
||||
UInt64 audioDataByteCount;
|
||||
UInt32 packetBufferSize;
|
||||
volatile Float64 seekTime;
|
||||
volatile int64_t framesQueued;
|
||||
volatile int64_t framesPlayed;
|
||||
volatile int64_t lastFrameQueued;
|
||||
volatile int processedPacketsCount;
|
||||
volatile int processedPacketsSizeTotal;
|
||||
AudioStreamBasicDescription audioStreamBasicDescription;
|
||||
}
|
||||
|
||||
@property (readonly) UInt64 audioDataLengthInBytes;
|
||||
@property (readwrite, retain) NSObject* queueItemId;
|
||||
@property (readwrite, retain) STKDataSource* dataSource;
|
||||
|
||||
-(id) initWithDataSource:(STKDataSource*)dataSource andQueueItemId:(NSObject*)queueItemId;
|
||||
|
||||
-(void) reset;
|
||||
-(double) duration;
|
||||
-(Float64) progressInFrames;
|
||||
-(double) calculatedBitRate;
|
||||
-(void) updateAudioDataSource;
|
||||
-(BOOL) isDefinitelyCompatible:(AudioStreamBasicDescription*)basicDescription;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// STKQueueEntry.m
|
||||
// StreamingKit
|
||||
//
|
||||
// Created by Thong Nguyen on 30/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import "STKQueueEntry.h"
|
||||
#import "STKDataSource.h"
|
||||
|
||||
#define STK_BIT_RATE_ESTIMATION_MIN_PACKETS (64)
|
||||
|
||||
@implementation STKQueueEntry
|
||||
|
||||
-(id) initWithDataSource:(STKDataSource*)dataSourceIn andQueueItemId:(NSObject*)queueItemIdIn
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
self.dataSource = dataSourceIn;
|
||||
self.queueItemId = queueItemIdIn;
|
||||
self->lastFrameQueued = -1;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) reset
|
||||
{
|
||||
OSSpinLockLock(&self->spinLock);
|
||||
self->framesQueued = 0;
|
||||
self->framesPlayed = 0;
|
||||
self->lastFrameQueued = -1;
|
||||
OSSpinLockUnlock(&self->spinLock);
|
||||
}
|
||||
|
||||
-(double) calculatedBitRate
|
||||
{
|
||||
double retval;
|
||||
|
||||
if (packetDuration && processedPacketsCount > STK_BIT_RATE_ESTIMATION_MIN_PACKETS)
|
||||
{
|
||||
double averagePacketByteSize = processedPacketsSizeTotal / processedPacketsCount;
|
||||
|
||||
retval = averagePacketByteSize / packetDuration * 8;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = (audioStreamBasicDescription.mBytesPerFrame * audioStreamBasicDescription.mSampleRate) * 8;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
-(void) updateAudioDataSource
|
||||
{
|
||||
if ([self.dataSource conformsToProtocol:@protocol(AudioDataSource)])
|
||||
{
|
||||
double calculatedBitrate = [self calculatedBitRate];
|
||||
|
||||
id<AudioDataSource> audioDataSource = (id<AudioDataSource>)self.dataSource;
|
||||
|
||||
audioDataSource.averageBitRate = calculatedBitrate;
|
||||
audioDataSource.audioDataOffset = audioDataOffset;
|
||||
}
|
||||
}
|
||||
|
||||
-(double) duration
|
||||
{
|
||||
if (self->sampleRate <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
UInt64 audioDataLengthInBytes = [self audioDataLengthInBytes];
|
||||
|
||||
double calculatedBitRate = [self calculatedBitRate];
|
||||
|
||||
if (calculatedBitRate < 1.0 || self.dataSource.length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return audioDataLengthInBytes / (calculatedBitRate / 8);
|
||||
}
|
||||
|
||||
-(UInt64) audioDataLengthInBytes
|
||||
{
|
||||
if (audioDataByteCount)
|
||||
{
|
||||
return audioDataByteCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!self.dataSource.length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return self.dataSource.length - audioDataOffset;
|
||||
}
|
||||
}
|
||||
|
||||
-(BOOL) isDefinitelyCompatible:(AudioStreamBasicDescription*)basicDescription
|
||||
{
|
||||
if (self->audioStreamBasicDescription.mSampleRate == 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return (memcmp(&(self->audioStreamBasicDescription), basicDescription, sizeof(*basicDescription)) == 0);
|
||||
}
|
||||
|
||||
-(Float64) progressInFrames
|
||||
{
|
||||
OSSpinLockLock(&self->spinLock);
|
||||
Float64 retval = self->seekTime + self->framesPlayed;
|
||||
OSSpinLockUnlock(&self->spinLock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
-(NSString*) description
|
||||
{
|
||||
return [[self queueItemId] description];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// StreamingKitMac.h
|
||||
// StreamingKitMac
|
||||
//
|
||||
// Created by Thong Nguyen on 02/02/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface StreamingKitMac : NSObject
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// StreamingKitMac.m
|
||||
// StreamingKitMac
|
||||
//
|
||||
// Created by Thong Nguyen on 02/02/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import "StreamingKitMac.h"
|
||||
|
||||
@implementation StreamingKitMac
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.abstractpath.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// StreamingKitMacTests.m
|
||||
// StreamingKitMacTests
|
||||
//
|
||||
// Created by Thong Nguyen on 02/02/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface StreamingKitMacTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation StreamingKitMacTests
|
||||
|
||||
- (void)setUp
|
||||
{
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown
|
||||
{
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testExample
|
||||
{
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Localized versions of Info.plist keys */
|
||||
|
||||
Reference in New Issue
Block a user