Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 93e6f4b6d9 | |||
| 9ed755cda4 | |||
| 7cc3f85a59 | |||
| a93d6867c5 | |||
| 4660f0ce80 | |||
| 6f37a24d1d | |||
| 18fc7353f9 | |||
| 97ca05662f | |||
| 3780b2a2bd | |||
| 7af1dd38aa | |||
| eeab471c42 | |||
| d76c1c2160 | |||
| 8e90aed1a1 | |||
| 4a38a20c3a | |||
| 4a37599866 | |||
| d5e7f986ac | |||
| 6ac8851b9e | |||
| 062a320de6 | |||
| 05f50e11d0 | |||
| c213f8809a | |||
| 5baa7a07c2 | |||
| 01629e7fdf | |||
| 1283cb31cc | |||
| 1a0b463a32 | |||
| aeb1ee1b7c | |||
| ec8b82b28f | |||
| c84db3bcab | |||
| cf14a035f6 | |||
| 8da9ea9545 | |||
| ee387dc098 | |||
| c2d5d4000d | |||
| 65c1715269 | |||
| 05965388cc | |||
| ba4e44b8a2 | |||
| 08287bc6a7 | |||
| dd3bd913b5 | |||
| f8887b7ff1 | |||
| 6d2b656a58 |
@@ -1,480 +0,0 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
8AC7AD4816E55CD70069BDE7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B4E5157F80E700BD0084 /* Foundation.framework */; };
|
||||
8AC7AD5416E55D260069BDE7 /* AutoRecoveringHttpDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A16CB9AA162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m */; };
|
||||
8AC7AD5616E55D260069BDE7 /* DataSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A16CB9AC162EC4AB00CFD1E8 /* DataSourceWrapper.m */; };
|
||||
8AC7AD5816E55D260069BDE7 /* AudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B501157F813100BD0084 /* AudioPlayer.m */; };
|
||||
8AC7AD5A16E55D260069BDE7 /* CoreFoundationDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B503157F813100BD0084 /* CoreFoundationDataSource.m */; };
|
||||
8AC7AD5C16E55D260069BDE7 /* DataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B505157F813100BD0084 /* DataSource.m */; };
|
||||
8AC7AD5E16E55D260069BDE7 /* HttpDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B507157F813100BD0084 /* HttpDataSource.m */; };
|
||||
8AC7AD6016E55D260069BDE7 /* LocalFileDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B509157F813100BD0084 /* LocalFileDataSource.m */; };
|
||||
A16CB9AD162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A16CB9AA162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m */; };
|
||||
A16CB9AE162EC4AB00CFD1E8 /* DataSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A16CB9AC162EC4AB00CFD1E8 /* DataSourceWrapper.m */; };
|
||||
A16CB9B1162EC5E300CFD1E8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A16CB9B0162EC5E300CFD1E8 /* SystemConfiguration.framework */; };
|
||||
A16CB9B3162EC5E900CFD1E8 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A16CB9B2162EC5E900CFD1E8 /* Default-568h@2x.png */; };
|
||||
A186B4E4157F80E700BD0084 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B4E3157F80E700BD0084 /* UIKit.framework */; };
|
||||
A186B4E6157F80E700BD0084 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B4E5157F80E700BD0084 /* Foundation.framework */; };
|
||||
A186B4EE157F80E700BD0084 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A186B4EC157F80E700BD0084 /* InfoPlist.strings */; };
|
||||
A186B4F0157F80E700BD0084 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B4EF157F80E700BD0084 /* main.m */; };
|
||||
A186B4F4157F80E700BD0084 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B4F3157F80E700BD0084 /* AppDelegate.m */; };
|
||||
A186B50C157F813100BD0084 /* AudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B501157F813100BD0084 /* AudioPlayer.m */; };
|
||||
A186B50D157F813100BD0084 /* CoreFoundationDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B503157F813100BD0084 /* CoreFoundationDataSource.m */; };
|
||||
A186B50E157F813100BD0084 /* DataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B505157F813100BD0084 /* DataSource.m */; };
|
||||
A186B50F157F813100BD0084 /* HttpDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B507157F813100BD0084 /* HttpDataSource.m */; };
|
||||
A186B510157F813100BD0084 /* LocalFileDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B509157F813100BD0084 /* LocalFileDataSource.m */; };
|
||||
A186B511157F813100BD0084 /* AudioPlayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = A186B50B157F813100BD0084 /* AudioPlayerView.m */; };
|
||||
A186B514157F817500BD0084 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B513157F817500BD0084 /* AudioToolbox.framework */; };
|
||||
A186B518157F818900BD0084 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B517157F818900BD0084 /* CoreFoundation.framework */; };
|
||||
A186B51A157F819500BD0084 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B519157F819500BD0084 /* CFNetwork.framework */; };
|
||||
A186B51D157F825400BD0084 /* sample.m4a in Resources */ = {isa = PBXBuildFile; fileRef = A186B51C157F820F00BD0084 /* sample.m4a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
8AC7AD4516E55CD70069BDE7 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "include/${PRODUCT_NAME}";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
8AC7AD4716E55CD70069BDE7 /* libaudjustable.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libaudjustable.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A16CB9A9162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoRecoveringHttpDataSource.h; sourceTree = "<group>"; };
|
||||
A16CB9AA162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AutoRecoveringHttpDataSource.m; sourceTree = "<group>"; };
|
||||
A16CB9AB162EC4AB00CFD1E8 /* DataSourceWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSourceWrapper.h; sourceTree = "<group>"; };
|
||||
A16CB9AC162EC4AB00CFD1E8 /* DataSourceWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataSourceWrapper.m; sourceTree = "<group>"; };
|
||||
A16CB9B0162EC5E300CFD1E8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
||||
A16CB9B2162EC5E900CFD1E8 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||
A186B4DF157F80E600BD0084 /* Audjustable.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Audjustable.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A186B4E3157F80E700BD0084 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
A186B4E5157F80E700BD0084 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
A186B4E7157F80E700BD0084 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
A186B4EB157F80E700BD0084 /* Audjustable-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Audjustable-Info.plist"; sourceTree = "<group>"; };
|
||||
A186B4ED157F80E700BD0084 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
A186B4EF157F80E700BD0084 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
A186B4F1157F80E700BD0084 /* Audjustable-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Audjustable-Prefix.pch"; sourceTree = "<group>"; };
|
||||
A186B4F2157F80E700BD0084 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
A186B4F3157F80E700BD0084 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
A186B500157F813100BD0084 /* AudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioPlayer.h; sourceTree = "<group>"; };
|
||||
A186B501157F813100BD0084 /* AudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioPlayer.m; sourceTree = "<group>"; };
|
||||
A186B502157F813100BD0084 /* CoreFoundationDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreFoundationDataSource.h; sourceTree = "<group>"; };
|
||||
A186B503157F813100BD0084 /* CoreFoundationDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreFoundationDataSource.m; sourceTree = "<group>"; };
|
||||
A186B504157F813100BD0084 /* DataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSource.h; sourceTree = "<group>"; };
|
||||
A186B505157F813100BD0084 /* DataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataSource.m; sourceTree = "<group>"; };
|
||||
A186B506157F813100BD0084 /* HttpDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpDataSource.h; sourceTree = "<group>"; };
|
||||
A186B507157F813100BD0084 /* HttpDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpDataSource.m; sourceTree = "<group>"; };
|
||||
A186B508157F813100BD0084 /* LocalFileDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalFileDataSource.h; sourceTree = "<group>"; };
|
||||
A186B509157F813100BD0084 /* LocalFileDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocalFileDataSource.m; sourceTree = "<group>"; };
|
||||
A186B50A157F813100BD0084 /* AudioPlayerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioPlayerView.h; sourceTree = "<group>"; };
|
||||
A186B50B157F813100BD0084 /* AudioPlayerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioPlayerView.m; sourceTree = "<group>"; };
|
||||
A186B513157F817500BD0084 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
A186B517157F818900BD0084 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
|
||||
A186B519157F819500BD0084 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
|
||||
A186B51C157F820F00BD0084 /* sample.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = sample.m4a; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
8AC7AD4416E55CD70069BDE7 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8AC7AD4816E55CD70069BDE7 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A186B4DC157F80E600BD0084 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A16CB9B1162EC5E300CFD1E8 /* SystemConfiguration.framework in Frameworks */,
|
||||
A186B51A157F819500BD0084 /* CFNetwork.framework in Frameworks */,
|
||||
A186B518157F818900BD0084 /* CoreFoundation.framework in Frameworks */,
|
||||
A186B514157F817500BD0084 /* AudioToolbox.framework in Frameworks */,
|
||||
A186B4E4157F80E700BD0084 /* UIKit.framework in Frameworks */,
|
||||
A186B4E6157F80E700BD0084 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
A186B4D4157F80E600BD0084 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A186B4E9157F80E700BD0084 /* Audjustable */,
|
||||
A186B4E2157F80E700BD0084 /* Frameworks */,
|
||||
A186B4E0157F80E600BD0084 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A186B4E0157F80E600BD0084 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A186B4DF157F80E600BD0084 /* Audjustable.app */,
|
||||
8AC7AD4716E55CD70069BDE7 /* libaudjustable.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A186B4E2157F80E700BD0084 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A16CB9B0162EC5E300CFD1E8 /* SystemConfiguration.framework */,
|
||||
A186B519157F819500BD0084 /* CFNetwork.framework */,
|
||||
A186B517157F818900BD0084 /* CoreFoundation.framework */,
|
||||
A186B513157F817500BD0084 /* AudioToolbox.framework */,
|
||||
A186B4E3157F80E700BD0084 /* UIKit.framework */,
|
||||
A186B4E5157F80E700BD0084 /* Foundation.framework */,
|
||||
A186B4E7157F80E700BD0084 /* CoreGraphics.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A186B4E9157F80E700BD0084 /* Audjustable */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A186B4FE157F813100BD0084 /* Classes */,
|
||||
A186B4F2157F80E700BD0084 /* AppDelegate.h */,
|
||||
A186B4F3157F80E700BD0084 /* AppDelegate.m */,
|
||||
A186B4EA157F80E700BD0084 /* Supporting Files */,
|
||||
);
|
||||
path = Audjustable;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A186B4EA157F80E700BD0084 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A186B51B157F81D900BD0084 /* Resources */,
|
||||
A186B4EB157F80E700BD0084 /* Audjustable-Info.plist */,
|
||||
A186B4EC157F80E700BD0084 /* InfoPlist.strings */,
|
||||
A16CB9B2162EC5E900CFD1E8 /* Default-568h@2x.png */,
|
||||
A186B4EF157F80E700BD0084 /* main.m */,
|
||||
A186B4F1157F80E700BD0084 /* Audjustable-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A186B4FE157F813100BD0084 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A186B4FF157F813100BD0084 /* AudioPlayer */,
|
||||
A186B50A157F813100BD0084 /* AudioPlayerView.h */,
|
||||
A186B50B157F813100BD0084 /* AudioPlayerView.m */,
|
||||
);
|
||||
path = Classes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A186B4FF157F813100BD0084 /* AudioPlayer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A16CB9A9162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.h */,
|
||||
A16CB9AA162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m */,
|
||||
A16CB9AB162EC4AB00CFD1E8 /* DataSourceWrapper.h */,
|
||||
A16CB9AC162EC4AB00CFD1E8 /* DataSourceWrapper.m */,
|
||||
A186B500157F813100BD0084 /* AudioPlayer.h */,
|
||||
A186B501157F813100BD0084 /* AudioPlayer.m */,
|
||||
A186B502157F813100BD0084 /* CoreFoundationDataSource.h */,
|
||||
A186B503157F813100BD0084 /* CoreFoundationDataSource.m */,
|
||||
A186B504157F813100BD0084 /* DataSource.h */,
|
||||
A186B505157F813100BD0084 /* DataSource.m */,
|
||||
A186B506157F813100BD0084 /* HttpDataSource.h */,
|
||||
A186B507157F813100BD0084 /* HttpDataSource.m */,
|
||||
A186B508157F813100BD0084 /* LocalFileDataSource.h */,
|
||||
A186B509157F813100BD0084 /* LocalFileDataSource.m */,
|
||||
);
|
||||
path = AudioPlayer;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A186B51B157F81D900BD0084 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A186B51C157F820F00BD0084 /* sample.m4a */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8AC7AD4616E55CD70069BDE7 /* audjustable */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 8AC7AD5016E55CD70069BDE7 /* Build configuration list for PBXNativeTarget "audjustable" */;
|
||||
buildPhases = (
|
||||
8AC7AD4316E55CD70069BDE7 /* Sources */,
|
||||
8AC7AD4416E55CD70069BDE7 /* Frameworks */,
|
||||
8AC7AD4516E55CD70069BDE7 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = audjustable;
|
||||
productName = audjustable;
|
||||
productReference = 8AC7AD4716E55CD70069BDE7 /* libaudjustable.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
A186B4DE157F80E600BD0084 /* Audjustable */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A186B4F7157F80E700BD0084 /* Build configuration list for PBXNativeTarget "Audjustable" */;
|
||||
buildPhases = (
|
||||
A186B4DB157F80E600BD0084 /* Sources */,
|
||||
A186B4DC157F80E600BD0084 /* Frameworks */,
|
||||
A186B4DD157F80E600BD0084 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Audjustable;
|
||||
productName = Audjustable;
|
||||
productReference = A186B4DF157F80E600BD0084 /* Audjustable.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
A186B4D6157F80E600BD0084 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0460;
|
||||
};
|
||||
buildConfigurationList = A186B4D9157F80E600BD0084 /* Build configuration list for PBXProject "Audjustable" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = A186B4D4157F80E600BD0084;
|
||||
productRefGroup = A186B4E0157F80E600BD0084 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
A186B4DE157F80E600BD0084 /* Audjustable */,
|
||||
8AC7AD4616E55CD70069BDE7 /* audjustable */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
A186B4DD157F80E600BD0084 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A186B4EE157F80E700BD0084 /* InfoPlist.strings in Resources */,
|
||||
A186B51D157F825400BD0084 /* sample.m4a in Resources */,
|
||||
A16CB9B3162EC5E900CFD1E8 /* Default-568h@2x.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8AC7AD4316E55CD70069BDE7 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8AC7AD5416E55D260069BDE7 /* AutoRecoveringHttpDataSource.m in Sources */,
|
||||
8AC7AD5616E55D260069BDE7 /* DataSourceWrapper.m in Sources */,
|
||||
8AC7AD5816E55D260069BDE7 /* AudioPlayer.m in Sources */,
|
||||
8AC7AD5A16E55D260069BDE7 /* CoreFoundationDataSource.m in Sources */,
|
||||
8AC7AD5C16E55D260069BDE7 /* DataSource.m in Sources */,
|
||||
8AC7AD5E16E55D260069BDE7 /* HttpDataSource.m in Sources */,
|
||||
8AC7AD6016E55D260069BDE7 /* LocalFileDataSource.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A186B4DB157F80E600BD0084 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A186B4F0157F80E700BD0084 /* main.m in Sources */,
|
||||
A186B4F4157F80E700BD0084 /* AppDelegate.m in Sources */,
|
||||
A186B50C157F813100BD0084 /* AudioPlayer.m in Sources */,
|
||||
A186B50D157F813100BD0084 /* CoreFoundationDataSource.m in Sources */,
|
||||
A186B50E157F813100BD0084 /* DataSource.m in Sources */,
|
||||
A186B50F157F813100BD0084 /* HttpDataSource.m in Sources */,
|
||||
A186B510157F813100BD0084 /* LocalFileDataSource.m in Sources */,
|
||||
A186B511157F813100BD0084 /* AudioPlayerView.m in Sources */,
|
||||
A16CB9AD162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m in Sources */,
|
||||
A16CB9AE162EC4AB00CFD1E8 /* DataSourceWrapper.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
A186B4EC157F80E700BD0084 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A186B4ED157F80E700BD0084 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
8AC7AD5116E55CD70069BDE7 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DSTROOT = /tmp/audjustable.dst;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "audjustable/audjustable-Prefix.pch";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
8AC7AD5216E55CD70069BDE7 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
DSTROOT = /tmp/audjustable.dst;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "audjustable/audjustable-Prefix.pch";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A186B4F5157F80E700BD0084 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A186B4F6157F80E700BD0084 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
||||
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A186B4F8157F80E700BD0084 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Audjustable/Audjustable-Prefix.pch";
|
||||
INFOPLIST_FILE = "Audjustable/Audjustable-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A186B4F9157F80E700BD0084 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Audjustable/Audjustable-Prefix.pch";
|
||||
INFOPLIST_FILE = "Audjustable/Audjustable-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
8AC7AD5016E55CD70069BDE7 /* Build configuration list for PBXNativeTarget "audjustable" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
8AC7AD5116E55CD70069BDE7 /* Debug */,
|
||||
8AC7AD5216E55CD70069BDE7 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A186B4D9157F80E600BD0084 /* Build configuration list for PBXProject "Audjustable" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A186B4F5157F80E700BD0084 /* Debug */,
|
||||
A186B4F6157F80E700BD0084 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A186B4F7157F80E700BD0084 /* Build configuration list for PBXNativeTarget "Audjustable" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A186B4F8157F80E700BD0084 /* Debug */,
|
||||
A186B4F9157F80E700BD0084 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = A186B4D6157F80E600BD0084 /* Project object */;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Audjustable.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -1,86 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0460"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "A186B4DE157F80E600BD0084"
|
||||
BuildableName = "Audjustable.app"
|
||||
BlueprintName = "Audjustable"
|
||||
ReferencedContainer = "container:Audjustable.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "A186B4DE157F80E600BD0084"
|
||||
BuildableName = "Audjustable.app"
|
||||
BlueprintName = "Audjustable"
|
||||
ReferencedContainer = "container:Audjustable.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "A186B4DE157F80E600BD0084"
|
||||
BuildableName = "Audjustable.app"
|
||||
BlueprintName = "Audjustable"
|
||||
ReferencedContainer = "container:Audjustable.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "A186B4DE157F80E600BD0084"
|
||||
BuildableName = "Audjustable.app"
|
||||
BlueprintName = "Audjustable"
|
||||
ReferencedContainer = "container:Audjustable.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,59 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0460"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "8AC7AD4616E55CD70069BDE7"
|
||||
BuildableName = "libaudjustable.a"
|
||||
BlueprintName = "audjustable"
|
||||
ReferencedContainer = "container:Audjustable.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,50 +0,0 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// BlueCucumber-AudioPlayer
|
||||
//
|
||||
// Created by Thong Nguyen on 01/06/2012.
|
||||
// Copyright (c) 2012 Thong Nguyen All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "AudioPlayerView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@synthesize window = _window;
|
||||
|
||||
-(BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
|
||||
{
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
audioPlayer = [[AudioPlayer alloc] init];
|
||||
AudioPlayerView* audioPlayerView = [[AudioPlayerView alloc] initWithFrame:self.window.bounds];
|
||||
|
||||
audioPlayerView.delegate = self;
|
||||
audioPlayerView.audioPlayer = audioPlayer;
|
||||
|
||||
[self.window addSubview:audioPlayerView];
|
||||
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void) audioPlayerViewPlayFromHTTPSelected:(AudioPlayerView*)audioPlayerView
|
||||
{
|
||||
NSURL* url = [NSURL URLWithString:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"];
|
||||
|
||||
[audioPlayer setDataSource:[audioPlayer dataSourceFromURL:url] withQueueItemId:url];
|
||||
}
|
||||
|
||||
-(void) audioPlayerViewPlayFromLocalFileSelected:(AudioPlayerView*)audioPlayerView
|
||||
{
|
||||
NSString * path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"m4a"];
|
||||
NSURL* url = [NSURL fileURLWithPath:path];
|
||||
|
||||
[audioPlayer setDataSource:[audioPlayer dataSourceFromURL:url] withQueueItemId:url];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,197 +0,0 @@
|
||||
/**********************************************************************************
|
||||
AudioPlayer.m
|
||||
|
||||
Created by Thong Nguyen on 14/05/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Inspired by Matt Gallagher's AudioStreamer:
|
||||
https://github.com/mattgallagher/AudioStreamer
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <pthread.h>
|
||||
#import "DataSource.h"
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#define AudioPlayerDefaultNumberOfAudioQueueBuffers (2 * 1024)
|
||||
|
||||
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)
|
||||
}
|
||||
AudioPlayerInternalState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AudioPlayerStateReady,
|
||||
AudioPlayerStateRunning = 1,
|
||||
AudioPlayerStatePlaying = (1 << 1) | AudioPlayerStateRunning,
|
||||
AudioPlayerStatePaused = (1 << 2) | AudioPlayerStateRunning,
|
||||
AudioPlayerStateStopped = (1 << 3),
|
||||
AudioPlayerStateError = (1 << 4),
|
||||
AudioPlayerStateDisposed = (1 << 5)
|
||||
}
|
||||
AudioPlayerState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AudioPlayerStopReasonNoStop = 0,
|
||||
AudioPlayerStopReasonEof,
|
||||
AudioPlayerStopReasonUserAction,
|
||||
AudioPlayerStopReasonUserActionFlushStop
|
||||
}
|
||||
AudioPlayerStopReason;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AudioPlayerErrorNone = 0,
|
||||
AudioPlayerErrorDataSource,
|
||||
AudioPlayerErrorStreamParseBytesFailed,
|
||||
AudioPlayerErrorDataNotFound,
|
||||
AudioPlayerErrorQueueStartFailed,
|
||||
AudioPlayerErrorQueuePauseFailed,
|
||||
AudioPlayerErrorUnknownBuffer,
|
||||
AudioPlayerErrorQueueStopFailed,
|
||||
AudioPlayerErrorOther
|
||||
}
|
||||
AudioPlayerErrorCode;
|
||||
|
||||
@class AudioPlayer;
|
||||
|
||||
@protocol AudioPlayerDelegate <NSObject>
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer stateChanged:(AudioPlayerState)state;
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didEncounterError:(AudioPlayerErrorCode)errorCode;
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didStartPlayingQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didFinishBufferingSourceWithQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(AudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration;
|
||||
@optional
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer internalStateChanged:(AudioPlayerInternalState)state;
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didCancelQueuedItems:(NSArray*)queuedItems;
|
||||
@end
|
||||
|
||||
@class QueueEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AudioQueueBufferRef ref;
|
||||
int bufferIndex;
|
||||
}
|
||||
AudioQueueBufferRefLookupEntry;
|
||||
|
||||
@interface AudioPlayer : NSObject<DataSourceDelegate>
|
||||
{
|
||||
@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;
|
||||
|
||||
UIBackgroundTaskIdentifier backgroundTaskId;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@property (readonly) double duration;
|
||||
@property (readonly) double progress;
|
||||
@property (readwrite) AudioPlayerState state;
|
||||
@property (readonly) AudioPlayerStopReason stopReason;
|
||||
@property (readwrite, unsafe_unretained) id<AudioPlayerDelegate> delegate;
|
||||
|
||||
-(id) init;
|
||||
-(id) initWithNumberOfAudioQueueBuffers:(int)numberOfAudioQueueBuffers andReadBufferSize:(int)readBufferSizeIn;
|
||||
-(DataSource*) dataSourceFromURL:(NSURL*)url;
|
||||
-(void) play:(NSURL*)url;
|
||||
-(void) queueDataSource:(DataSource*)dataSource withQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) setDataSource:(DataSource*)dataSourceIn withQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) seekToTime:(double)value;
|
||||
-(void) pause;
|
||||
-(void) resume;
|
||||
-(void) stop;
|
||||
-(void) flushStop;
|
||||
-(void) dispose;
|
||||
-(NSObject*) currentlyPlayingQueueItemId;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,236 +0,0 @@
|
||||
/**********************************************************************************
|
||||
AudioPlayer.m
|
||||
|
||||
Created by Thong Nguyen on 14/05/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "HttpDataSource.h"
|
||||
#import "LocalFileDataSource.h"
|
||||
|
||||
@interface HttpDataSource()
|
||||
-(void) open;
|
||||
@end
|
||||
|
||||
@implementation HttpDataSource
|
||||
@synthesize url;
|
||||
|
||||
-(id) initWithURL:(NSURL*)urlIn
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
seekStart = 0;
|
||||
relativePosition = 0;
|
||||
fileLength = -1;
|
||||
|
||||
self.url = urlIn;
|
||||
|
||||
[self open];
|
||||
|
||||
audioFileTypeHint = [LocalFileDataSource audioFileTypeHintFromFileExtension:urlIn.pathExtension];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+(AudioFileTypeID) audioFileTypeHintFromMimeType:(NSString*)mimeType
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
static NSDictionary* fileTypesByMimeType;
|
||||
|
||||
dispatch_once(&onceToken, ^
|
||||
{
|
||||
fileTypesByMimeType =
|
||||
@{
|
||||
@"audio/mp3": @(kAudioFileMP3Type),
|
||||
@"audio/mpg": @(kAudioFileMP3Type),
|
||||
@"audio/mpeg": @(kAudioFileMP3Type),
|
||||
@"audio/wav": @(kAudioFileWAVEType),
|
||||
@"audio/aifc": @(kAudioFileAIFCType),
|
||||
@"audio/aiff": @(kAudioFileAIFFType),
|
||||
@"audio/x-m4a": @(kAudioFileM4AType),
|
||||
@"audio/x-mp4": @(kAudioFileMPEG4Type),
|
||||
@"audio/m4a": @(kAudioFileM4AType),
|
||||
@"audio/mp4": @(kAudioFileMPEG4Type),
|
||||
@"audio/caf": @(kAudioFileCAFType),
|
||||
@"audio/aac": @(kAudioFileAAC_ADTSType),
|
||||
@"audio/ac3": @(kAudioFileAC3Type),
|
||||
@"audio/3gp": @(kAudioFile3GPType)
|
||||
};
|
||||
});
|
||||
|
||||
NSNumber* number = [fileTypesByMimeType objectForKey:mimeType];
|
||||
|
||||
if (!number)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (AudioFileTypeID)number.intValue;
|
||||
}
|
||||
|
||||
-(AudioFileTypeID) audioFileTypeHint
|
||||
{
|
||||
return audioFileTypeHint;
|
||||
}
|
||||
|
||||
-(void) dataAvailable
|
||||
{
|
||||
if (fileLength < 0)
|
||||
{
|
||||
CFTypeRef copyPropertyMessage = CFReadStreamCopyProperty(stream, kCFStreamPropertyHTTPResponseHeader);
|
||||
|
||||
httpHeaders = (__bridge_transfer NSDictionary*)CFHTTPMessageCopyAllHeaderFields((CFHTTPMessageRef)copyPropertyMessage);
|
||||
|
||||
CFRelease(copyPropertyMessage);
|
||||
|
||||
if (seekStart == 0)
|
||||
{
|
||||
fileLength = [[httpHeaders objectForKey:@"Content-Length"] integerValue];
|
||||
}
|
||||
|
||||
NSString* contentType = [httpHeaders objectForKey:@"Content-Type"];
|
||||
AudioFileTypeID typeIdFromMimeType = [HttpDataSource audioFileTypeHintFromMimeType:contentType];
|
||||
|
||||
if (typeIdFromMimeType != 0)
|
||||
{
|
||||
audioFileTypeHint = typeIdFromMimeType;
|
||||
}
|
||||
}
|
||||
|
||||
[super dataAvailable];
|
||||
}
|
||||
|
||||
-(long long) position
|
||||
{
|
||||
return seekStart + relativePosition;
|
||||
}
|
||||
|
||||
-(long long) length
|
||||
{
|
||||
return fileLength >= 0 ? fileLength : 0;
|
||||
}
|
||||
|
||||
-(void) seekToOffset:(long long)offset
|
||||
{
|
||||
if (eventsRunLoop)
|
||||
{
|
||||
[self unregisterForEvents];
|
||||
}
|
||||
|
||||
if (stream)
|
||||
{
|
||||
CFReadStreamClose(stream);
|
||||
CFRelease(stream);
|
||||
}
|
||||
|
||||
stream = 0;
|
||||
relativePosition = 0;
|
||||
seekStart = offset;
|
||||
|
||||
[self open];
|
||||
[self reregisterForEvents];
|
||||
}
|
||||
|
||||
-(int) readIntoBuffer:(UInt8*)buffer withSize:(int)size
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read = CFReadStreamRead(stream, buffer, size);
|
||||
|
||||
if (read < 0)
|
||||
{
|
||||
return read;
|
||||
}
|
||||
|
||||
relativePosition += read;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
-(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 (!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);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,207 +0,0 @@
|
||||
/**********************************************************************************
|
||||
AudioPlayer.m
|
||||
|
||||
Created by Thong Nguyen on 14/05/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "AudioPlayerView.h"
|
||||
|
||||
@interface AudioPlayerView()
|
||||
-(void) setupTimer;
|
||||
-(void) updateControls;
|
||||
@end
|
||||
|
||||
@implementation AudioPlayerView
|
||||
@synthesize audioPlayer, delegate;
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
if (self)
|
||||
{
|
||||
CGSize size = CGSizeMake(180, 50);
|
||||
|
||||
playFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, 60, 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, 120, 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];
|
||||
|
||||
slider = [[UISlider alloc] initWithFrame:CGRectMake(20, 290, 280, 20)];
|
||||
slider.continuous = YES;
|
||||
[slider addTarget:self action:@selector(sliderChanged) forControlEvents:UIControlEventValueChanged];
|
||||
|
||||
[self addSubview:slider];
|
||||
[self addSubview:playButton];
|
||||
[self addSubview:playFromHTTPButton];
|
||||
[self addSubview:playFromLocalFileButton];
|
||||
|
||||
[self setupTimer];
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) sliderChanged
|
||||
{
|
||||
if (!audioPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"Slider Changed: %f", slider.value);
|
||||
|
||||
[audioPlayer seekToTime:slider.value];
|
||||
}
|
||||
|
||||
-(void) setupTimer
|
||||
{
|
||||
timer = [NSTimer timerWithTimeInterval:0.25 target:self selector:@selector(tick) userInfo:nil repeats:YES];
|
||||
|
||||
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
-(void) tick
|
||||
{
|
||||
if (!audioPlayer || audioPlayer.duration == 0)
|
||||
{
|
||||
slider.value = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
slider.minimumValue = 0;
|
||||
slider.maximumValue = audioPlayer.duration;
|
||||
|
||||
slider.value = audioPlayer.progress;
|
||||
}
|
||||
|
||||
-(void) playFromHTTPButtonTouched
|
||||
{
|
||||
[self.delegate audioPlayerViewPlayFromHTTPSelected:self];
|
||||
}
|
||||
|
||||
-(void) playFromLocalFileButtonTouched
|
||||
{
|
||||
[self.delegate audioPlayerViewPlayFromLocalFileSelected:self];
|
||||
}
|
||||
|
||||
-(void) playButtonPressed
|
||||
{
|
||||
if (!audioPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioPlayer.state == AudioPlayerStatePaused)
|
||||
{
|
||||
[audioPlayer resume];
|
||||
}
|
||||
else
|
||||
{
|
||||
[audioPlayer pause];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) updateControls
|
||||
{
|
||||
if (audioPlayer == nil)
|
||||
{
|
||||
[playButton setTitle:@"Play" forState:UIControlStateNormal];
|
||||
}
|
||||
else if (audioPlayer.state == AudioPlayerStatePaused)
|
||||
{
|
||||
[playButton setTitle:@"Resume" forState:UIControlStateNormal];
|
||||
}
|
||||
else if (audioPlayer.state == AudioPlayerStatePlaying)
|
||||
{
|
||||
[playButton setTitle:@"Pause" forState:UIControlStateNormal];
|
||||
}
|
||||
else
|
||||
{
|
||||
[playButton setTitle:@"Play" forState:UIControlStateNormal];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) setAudioPlayer:(AudioPlayer*)value
|
||||
{
|
||||
if (audioPlayer)
|
||||
{
|
||||
audioPlayer.delegate = nil;
|
||||
}
|
||||
|
||||
audioPlayer = value;
|
||||
audioPlayer.delegate = self;
|
||||
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(AudioPlayer*) audioPlayer
|
||||
{
|
||||
return audioPlayer;
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer stateChanged:(AudioPlayerState)state
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didEncounterError:(AudioPlayerErrorCode)errorCode
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didStartPlayingQueueItemId:(NSObject*)queueItemId
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didFinishBufferingSourceWithQueueItemId:(NSObject*)queueItemId
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(AudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(AudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,18 +0,0 @@
|
||||
//
|
||||
// main.m
|
||||
// Audjustable
|
||||
//
|
||||
// Created by Thong Nguyen on 06/06/2012.
|
||||
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,510 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
A1115935188D686000641365 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1115934188D686000641365 /* Foundation.framework */; };
|
||||
A1115937188D686000641365 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1115936188D686000641365 /* CoreGraphics.framework */; };
|
||||
A1115939188D686000641365 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1115938188D686000641365 /* UIKit.framework */; };
|
||||
A111593F188D686000641365 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A111593D188D686000641365 /* InfoPlist.strings */; };
|
||||
A1115941188D686000641365 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A1115940188D686000641365 /* main.m */; };
|
||||
A1115945188D686000641365 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A1115944188D686000641365 /* AppDelegate.m */; };
|
||||
A1115947188D686000641365 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A1115946188D686000641365 /* Images.xcassets */; };
|
||||
A111594E188D686000641365 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A111594D188D686000641365 /* XCTest.framework */; };
|
||||
A111594F188D686000641365 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1115934188D686000641365 /* Foundation.framework */; };
|
||||
A1115950188D686000641365 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1115938188D686000641365 /* UIKit.framework */; };
|
||||
A1115958188D686000641365 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1115956188D686000641365 /* InfoPlist.strings */; };
|
||||
A111595A188D686000641365 /* ExampleAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A1115959188D686000641365 /* ExampleAppTests.m */; };
|
||||
A1115964188D691500641365 /* libStreamingKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A1115963188D691500641365 /* libStreamingKit.a */; };
|
||||
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 */
|
||||
A1115951188D686000641365 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = A1115929188D686000641365 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = A1115930188D686000641365;
|
||||
remoteInfo = ExampleApp;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
A1115931188D686000641365 /* ExampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1115934188D686000641365 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
A1115936188D686000641365 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
A1115938188D686000641365 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
A111593C188D686000641365 /* ExampleApp-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleApp-Info.plist"; sourceTree = "<group>"; };
|
||||
A111593E188D686000641365 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
A1115940188D686000641365 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
A1115942188D686000641365 /* ExampleApp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleApp-Prefix.pch"; sourceTree = "<group>"; };
|
||||
A1115943188D686000641365 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
A1115944188D686000641365 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
A1115946188D686000641365 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
A111594C188D686000641365 /* ExampleAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A111594D188D686000641365 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
A1115955188D686000641365 /* ExampleAppTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleAppTests-Info.plist"; sourceTree = "<group>"; };
|
||||
A1115957188D686000641365 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
A1115959188D686000641365 /* ExampleAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleAppTests.m; sourceTree = "<group>"; };
|
||||
A1115963188D691500641365 /* libStreamingKit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libStreamingKit.a; path = "../../../Library/Developer/Xcode/DerivedData/StreamingKit-dabtccqthoyywldsgcvllbcjcmma/Build/Products/Debug-iphoneos/libStreamingKit.a"; sourceTree = "<group>"; };
|
||||
A1115965188D6AEE00641365 /* AudioPlayerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioPlayerView.h; sourceTree = "<group>"; };
|
||||
A1115966188D6AEE00641365 /* AudioPlayerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioPlayerView.m; sourceTree = "<group>"; };
|
||||
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 */
|
||||
A111592E188D686000641365 /* Frameworks */ = {
|
||||
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 */,
|
||||
A1115935188D686000641365 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1115949188D686000641365 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A111594E188D686000641365 /* XCTest.framework in Frameworks */,
|
||||
A1115950188D686000641365 /* UIKit.framework in Frameworks */,
|
||||
A111594F188D686000641365 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
A1115928188D686000641365 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A111593A188D686000641365 /* ExampleApp */,
|
||||
A1115953188D686000641365 /* ExampleAppTests */,
|
||||
A1115933188D686000641365 /* Frameworks */,
|
||||
A1115932188D686000641365 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1115932188D686000641365 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1115931188D686000641365 /* ExampleApp.app */,
|
||||
A111594C188D686000641365 /* ExampleAppTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1115933188D686000641365 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */,
|
||||
A1115963188D691500641365 /* libStreamingKit.a */,
|
||||
A1115934188D686000641365 /* Foundation.framework */,
|
||||
A1115936188D686000641365 /* CoreGraphics.framework */,
|
||||
A1115938188D686000641365 /* UIKit.framework */,
|
||||
A111594D188D686000641365 /* XCTest.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A111593A188D686000641365 /* ExampleApp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A111596A188D6C4B00641365 /* Resources */,
|
||||
A1115943188D686000641365 /* AppDelegate.h */,
|
||||
A1115944188D686000641365 /* AppDelegate.m */,
|
||||
A1115965188D6AEE00641365 /* AudioPlayerView.h */,
|
||||
A1115966188D6AEE00641365 /* AudioPlayerView.m */,
|
||||
A111596D188D6DB100641365 /* SampleQueueId.h */,
|
||||
A111596E188D6DB100641365 /* SampleQueueId.m */,
|
||||
A1115946188D686000641365 /* Images.xcassets */,
|
||||
A111593B188D686000641365 /* Supporting Files */,
|
||||
);
|
||||
path = ExampleApp;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A111593B188D686000641365 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A111593C188D686000641365 /* ExampleApp-Info.plist */,
|
||||
A111593D188D686000641365 /* InfoPlist.strings */,
|
||||
A1115940188D686000641365 /* main.m */,
|
||||
A1115942188D686000641365 /* ExampleApp-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1115953188D686000641365 /* ExampleAppTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1115959188D686000641365 /* ExampleAppTests.m */,
|
||||
A1115954188D686000641365 /* Supporting Files */,
|
||||
);
|
||||
path = ExampleAppTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1115954188D686000641365 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1115955188D686000641365 /* ExampleAppTests-Info.plist */,
|
||||
A1115956188D686000641365 /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A111596A188D6C4B00641365 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A142571C18907861005F0129 /* airplane.aac */,
|
||||
A111596B188D6C8100641365 /* sample.m4a */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
A1115930188D686000641365 /* ExampleApp */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A111595D188D686000641365 /* Build configuration list for PBXNativeTarget "ExampleApp" */;
|
||||
buildPhases = (
|
||||
A111592D188D686000641365 /* Sources */,
|
||||
A111592E188D686000641365 /* Frameworks */,
|
||||
A111592F188D686000641365 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ExampleApp;
|
||||
productName = ExampleApp;
|
||||
productReference = A1115931188D686000641365 /* ExampleApp.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
A111594B188D686000641365 /* ExampleAppTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1115960188D686000641365 /* Build configuration list for PBXNativeTarget "ExampleAppTests" */;
|
||||
buildPhases = (
|
||||
A1115948188D686000641365 /* Sources */,
|
||||
A1115949188D686000641365 /* Frameworks */,
|
||||
A111594A188D686000641365 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
A1115952188D686000641365 /* PBXTargetDependency */,
|
||||
);
|
||||
name = ExampleAppTests;
|
||||
productName = ExampleAppTests;
|
||||
productReference = A111594C188D686000641365 /* ExampleAppTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
A1115929188D686000641365 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Thong Nguyen";
|
||||
TargetAttributes = {
|
||||
A111594B188D686000641365 = {
|
||||
TestTargetID = A1115930188D686000641365;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = A111592C188D686000641365 /* Build configuration list for PBXProject "ExampleApp" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = A1115928188D686000641365;
|
||||
productRefGroup = A1115932188D686000641365 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
A1115930188D686000641365 /* ExampleApp */,
|
||||
A111594B188D686000641365 /* ExampleAppTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
A111592F188D686000641365 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A111593F188D686000641365 /* InfoPlist.strings in Resources */,
|
||||
A111596C188D6C8100641365 /* sample.m4a in Resources */,
|
||||
A1115947188D686000641365 /* Images.xcassets in Resources */,
|
||||
A142571D189079BE005F0129 /* airplane.aac in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A111594A188D686000641365 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1115958188D686000641365 /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
A111592D188D686000641365 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1115945188D686000641365 /* AppDelegate.m in Sources */,
|
||||
A1115941188D686000641365 /* main.m in Sources */,
|
||||
A111596F188D6DB100641365 /* SampleQueueId.m in Sources */,
|
||||
A1115967188D6AEE00641365 /* AudioPlayerView.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1115948188D686000641365 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A111595A188D686000641365 /* ExampleAppTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
A1115952188D686000641365 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = A1115930188D686000641365 /* ExampleApp */;
|
||||
targetProxy = A1115951188D686000641365 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
A111593D188D686000641365 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A111593E188D686000641365 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1115956188D686000641365 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A1115957188D686000641365 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
A111595B188D686000641365 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
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;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
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;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../StreamingKit/StreamingKit",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A111595C188D686000641365 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
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;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
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;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../StreamingKit/StreamingKit",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
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;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
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;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A1115961188D686000641365 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ExampleApp.app/ExampleApp";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "ExampleApp/ExampleApp-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "ExampleAppTests/ExampleAppTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1115962188D686000641365 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ExampleApp.app/ExampleApp";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "ExampleApp/ExampleApp-Prefix.pch";
|
||||
INFOPLIST_FILE = "ExampleAppTests/ExampleAppTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUNDLE_LOADER)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
A111592C188D686000641365 /* Build configuration list for PBXProject "ExampleApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A111595B188D686000641365 /* Debug */,
|
||||
A111595C188D686000641365 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A111595D188D686000641365 /* Build configuration list for PBXNativeTarget "ExampleApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A111595E188D686000641365 /* Debug */,
|
||||
A111595F188D686000641365 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A1115960188D686000641365 /* Build configuration list for PBXNativeTarget "ExampleAppTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1115961188D686000641365 /* Debug */,
|
||||
A1115962188D686000641365 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = A1115929188D686000641365 /* Project object */;
|
||||
}
|
||||
@@ -1,19 +1,16 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// BlueCucumber-AudioPlayer
|
||||
// ExampleApp
|
||||
//
|
||||
// Created by Thong Nguyen on 01/06/2012.
|
||||
// Copyright (c) 2012 Thong Nguyen All rights reserved.
|
||||
// Created by Thong Nguyen on 20/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "STKAudioPlayer.h"
|
||||
#import "AudioPlayerView.h"
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate, AudioPlayerViewDelegate>
|
||||
{
|
||||
@private
|
||||
AudioPlayer* audioPlayer;
|
||||
}
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// ExampleApp
|
||||
//
|
||||
// Created by Thong Nguyen on 20/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "STKAudioPlayer.h"
|
||||
#import "AudioPlayerView.h"
|
||||
#import "STKAutoRecoveringHTTPDataSource.h"
|
||||
#import "SampleQueueId.h"
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
@interface AppDelegate()
|
||||
{
|
||||
STKAudioPlayer* audioPlayer;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
|
||||
-(BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
|
||||
{
|
||||
NSError* error;
|
||||
|
||||
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
audioPlayer = [[STKAudioPlayer alloc] init];
|
||||
AudioPlayerView* audioPlayerView = [[AudioPlayerView alloc] initWithFrame:self.window.bounds];
|
||||
|
||||
audioPlayerView.delegate = self;
|
||||
audioPlayerView.audioPlayer = audioPlayer;
|
||||
|
||||
[self.window addSubview:audioPlayerView];
|
||||
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void) audioPlayerViewPlayFromHTTPSelected:(AudioPlayerView*)audioPlayerView
|
||||
{
|
||||
NSURL* url = [NSURL URLWithString:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"];
|
||||
|
||||
STKAutoRecoveringHTTPDataSource* dataSource = [[STKAutoRecoveringHTTPDataSource alloc] initWithHTTPDataSource:(STKHTTPDataSource*)[audioPlayer 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];
|
||||
|
||||
[audioPlayer queueDataSource:[audioPlayer dataSourceFromURL:url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:url andCount:0]];
|
||||
}
|
||||
|
||||
-(void) audioPlayerViewPlayFromLocalFileSelected:(AudioPlayerView*)audioPlayerView
|
||||
{
|
||||
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]];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -15,15 +15,15 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
@@ -33,26 +33,32 @@
|
||||
**********************************************************************************/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AudioPlayer.h"
|
||||
#import "STKAudioPlayer.h"
|
||||
|
||||
@class AudioPlayerView;
|
||||
|
||||
@protocol AudioPlayerViewDelegate<NSObject>
|
||||
-(void) audioPlayerViewPlayFromHTTPSelected:(AudioPlayerView*)audioPlayerView;
|
||||
-(void) audioPlayerViewQueueShortFileSelected:(AudioPlayerView*)audioPlayerView;
|
||||
-(void) audioPlayerViewPlayFromLocalFileSelected:(AudioPlayerView*)audioPlayerView;
|
||||
@end
|
||||
|
||||
@interface AudioPlayerView : UIView<AudioPlayerDelegate>
|
||||
@interface AudioPlayerView : UIView<STKAudioPlayerDelegate>
|
||||
{
|
||||
@private
|
||||
NSTimer* timer;
|
||||
UILabel* label;
|
||||
UILabel* statusLabel;
|
||||
UISlider* slider;
|
||||
UISwitch* repeatSwitch;
|
||||
UIButton* playButton;
|
||||
UIButton* disposeButton;
|
||||
UIButton* playFromHTTPButton;
|
||||
UIButton* queueShortFileButton;
|
||||
UIButton* playFromLocalFileButton;
|
||||
}
|
||||
|
||||
@property (readwrite, retain) AudioPlayer* audioPlayer;
|
||||
@property (readwrite, retain) STKAudioPlayer* audioPlayer;
|
||||
@property (readwrite, unsafe_unretained) id<AudioPlayerViewDelegate> delegate;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,306 @@
|
||||
/**********************************************************************************
|
||||
AudioPlayer.m
|
||||
|
||||
Created by Thong Nguyen on 14/05/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "AudioPlayerView.h"
|
||||
#import "SampleQueueId.h"
|
||||
|
||||
///
|
||||
/// This sample media player will play a local or an HTTP stream in repeat (gapless)
|
||||
///
|
||||
|
||||
@interface AudioPlayerView()
|
||||
-(void) setupTimer;
|
||||
-(void) updateControls;
|
||||
@end
|
||||
|
||||
@implementation AudioPlayerView
|
||||
@synthesize audioPlayer, delegate;
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
|
||||
if (self)
|
||||
{
|
||||
CGSize size = CGSizeMake(180, 50);
|
||||
|
||||
playFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.15, 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 addTarget:self action:@selector(playFromLocalFileButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[playFromLocalFileButton setTitle:@"Play from Local File" forState:UIControlStateNormal];
|
||||
|
||||
queueShortFileButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
queueShortFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.15 + 100, size.width, size.height);
|
||||
[queueShortFileButton addTarget:self action:@selector(queueShortFileButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[queueShortFileButton setTitle:@"Queue short file" forState:UIControlStateNormal];
|
||||
|
||||
playButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playButton.frame = CGRectMake(30, 380, size.width, size.height);
|
||||
[playButton addTarget:self action:@selector(playButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
disposeButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
disposeButton.frame = CGRectMake((320 - size.width) - 30, 380, size.width, size.height);
|
||||
[disposeButton addTarget:self action:@selector(disposeButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
||||
[disposeButton setTitle:@"Dispose" 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 + 170, size.width, size.height)];
|
||||
|
||||
label = [[UILabel alloc] initWithFrame:CGRectMake(0, slider.frame.origin.y + slider.frame.size.height, frame.size.width, 50)];
|
||||
|
||||
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;
|
||||
|
||||
[self addSubview:slider];
|
||||
[self addSubview:playButton];
|
||||
[self addSubview:playFromHTTPButton];
|
||||
[self addSubview:playFromLocalFileButton];
|
||||
[self addSubview:queueShortFileButton];
|
||||
[self addSubview:repeatSwitch];
|
||||
[self addSubview:label];
|
||||
[self addSubview:statusLabel];
|
||||
[self addSubview:disposeButton];
|
||||
|
||||
[self setupTimer];
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) sliderChanged
|
||||
{
|
||||
if (!audioPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"Slider Changed: %f", slider.value);
|
||||
|
||||
[audioPlayer seekToTime:slider.value];
|
||||
}
|
||||
|
||||
-(void) setupTimer
|
||||
{
|
||||
timer = [NSTimer timerWithTimeInterval:0.05 target:self selector:@selector(tick) userInfo:nil repeats:YES];
|
||||
|
||||
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
-(void) tick
|
||||
{
|
||||
if (!audioPlayer)
|
||||
{
|
||||
slider.value = 0;
|
||||
label.text = @"";
|
||||
statusLabel.text = @"";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
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" : @"";
|
||||
}
|
||||
|
||||
-(void) playFromHTTPButtonTouched
|
||||
{
|
||||
[self.delegate audioPlayerViewPlayFromHTTPSelected:self];
|
||||
}
|
||||
|
||||
-(void) playFromLocalFileButtonTouched
|
||||
{
|
||||
[self.delegate audioPlayerViewPlayFromLocalFileSelected:self];
|
||||
}
|
||||
|
||||
-(void) queueShortFileButtonTouched
|
||||
{
|
||||
[self.delegate audioPlayerViewQueueShortFileSelected:self];
|
||||
}
|
||||
|
||||
-(void) disposeButtonPressed
|
||||
{
|
||||
[audioPlayer dispose];
|
||||
audioPlayer = nil;
|
||||
}
|
||||
|
||||
-(void) playButtonPressed
|
||||
{
|
||||
if (!audioPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[audioPlayer dispose];
|
||||
|
||||
return;
|
||||
|
||||
if (audioPlayer.state == STKAudioPlayerStatePaused)
|
||||
{
|
||||
[audioPlayer resume];
|
||||
}
|
||||
else
|
||||
{
|
||||
[audioPlayer pause];
|
||||
}
|
||||
}
|
||||
|
||||
-(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:@"" forState:UIControlStateNormal];
|
||||
}
|
||||
else if (audioPlayer.state == STKAudioPlayerStatePaused)
|
||||
{
|
||||
[playButton setTitle:@"Resume" forState:UIControlStateNormal];
|
||||
}
|
||||
else if (audioPlayer.state & STKAudioPlayerStatePlaying)
|
||||
{
|
||||
[playButton setTitle:@"Pause" forState:UIControlStateNormal];
|
||||
}
|
||||
else
|
||||
{
|
||||
[playButton setTitle:@"" forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
[self tick];
|
||||
}
|
||||
|
||||
-(void) setAudioPlayer:(STKAudioPlayer*)value
|
||||
{
|
||||
if (audioPlayer)
|
||||
{
|
||||
audioPlayer.delegate = nil;
|
||||
}
|
||||
|
||||
audioPlayer = value;
|
||||
audioPlayer.delegate = self;
|
||||
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(STKAudioPlayer*) audioPlayer
|
||||
{
|
||||
return audioPlayer;
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didEncounterError:(STKAudioPlayerErrorCode)errorCode
|
||||
{
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didStartPlayingQueueItemId:(NSObject*)queueItemId
|
||||
{
|
||||
SampleQueueId* queueId = (SampleQueueId*)queueItemId;
|
||||
|
||||
NSLog(@"Started: %@", [queueId.url description]);
|
||||
|
||||
[self updateControls];
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishBufferingSourceWithQueueItemId:(NSObject*)queueItemId
|
||||
{
|
||||
[self updateControls];
|
||||
|
||||
// This queues on the currently playing track to be buffered and played immediately after (gapless)
|
||||
|
||||
if (repeatSwitch.on)
|
||||
{
|
||||
SampleQueueId* queueId = (SampleQueueId*)queueItemId;
|
||||
|
||||
NSLog(@"Requeuing: %@", [queueId.url description]);
|
||||
|
||||
[self->audioPlayer queueDataSource:[self->audioPlayer dataSourceFromURL:queueId.url] withQueueItemId:[[SampleQueueId alloc] initWithUrl:queueId.url andCount:queueId.count + 1]];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(STKAudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration
|
||||
{
|
||||
[self updateControls];
|
||||
|
||||
SampleQueueId* queueId = (SampleQueueId*)queueItemId;
|
||||
|
||||
NSLog(@"Finished: %@", [queueId.url description]);
|
||||
}
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer *)audioPlayer logInfo:(NSString *)line
|
||||
{
|
||||
NSLog(@"%@", line);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>AbstractPath.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<string>abstractpath.com.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
@@ -24,6 +24,10 @@
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
@@ -1,5 +1,7 @@
|
||||
//
|
||||
// Prefix header for all source files of the 'Audjustable' target in the 'Audjustable' project
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#import <Availability.h>
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "iphone",
|
||||
"subtype" : "retina4",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"orientation" : "portrait",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "ipad",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "7.0",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// SampleQueueId.h
|
||||
// ExampleApp
|
||||
//
|
||||
// Created by Thong Nguyen on 20/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface SampleQueueId : NSObject
|
||||
@property (readwrite) int count;
|
||||
@property (readwrite) NSURL* url;
|
||||
|
||||
-(id) initWithUrl:(NSURL*)url andCount:(int)count;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// SampleQueueId.m
|
||||
// ExampleApp
|
||||
//
|
||||
// Created by Thong Nguyen on 20/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SampleQueueId.h"
|
||||
|
||||
@implementation SampleQueueId
|
||||
|
||||
-(id) initWithUrl:(NSURL*)url andCount:(int)count
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
self.url = url;
|
||||
self.count = count;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(BOOL) isEqual:(id)object
|
||||
{
|
||||
if (object == nil)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([object class] != [SampleQueueId class])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
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,19 @@
|
||||
//
|
||||
// main.m
|
||||
// ExampleApp
|
||||
//
|
||||
// Created by Thong Nguyen on 20/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
@@ -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>abstractpath.com.${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 @@
|
||||
//
|
||||
// ExampleAppTests.m
|
||||
// ExampleAppTests
|
||||
//
|
||||
// Created by Thong Nguyen on 20/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface ExampleAppTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation ExampleAppTests
|
||||
|
||||
- (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 */
|
||||
|
||||
@@ -1,48 +1,41 @@
|
||||
### Audjustable Audio Streamer
|
||||
## StreamingKit
|
||||
|
||||
[Homepage](http://tumtumtum.github.com/audjustable)
|
||||
StreamingKit (formally Audjustable) is an audio streaming library for iOS and OSX. StreamingKit uses CoreAudio to decompress and playback audio whilst providing a clean and simple object-oriented API.
|
||||
|
||||
Audjustable is audio streaming class for iOS and OSX. Audjustable uses CoreAudio to decompress and playback audio whilst providing a clean and simple object-oriented API.
|
||||
The primary motivation of this project was to decouple the input data sources from the actual player logic in order to allow advanced customizable input handling such as HTTP streaming, encryption/decryption, auto-recovery, dynamic-buffering. Along the way other features such as gapless playback were added.
|
||||
|
||||
The primary motivation of this project was to decouple the input (DataSource/InputStreams) from the actual player logic in order to allow advanced customizable input handling such as: HTTP streaming, encryption, auto-recovery, dynamic-buffering. Along the way other features such as gapless playback were added as the opportunity arose.
|
||||
|
||||
## Features
|
||||
## Main Features
|
||||
|
||||
* Simple OOP API
|
||||
* Easy to read source
|
||||
* Adjustable audio buffering
|
||||
* Mostly asynchronous API
|
||||
* Buffered and gapless playback
|
||||
* Easy to implement audio data sources (HTTP and local file system DataSources provided)
|
||||
* Easy to extend DataSource to support adaptive buffering, encryption etc
|
||||
* 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
|
||||
|
||||
## Usage
|
||||
## Installation
|
||||
|
||||
Download the [source](https://github.com/tumtumtum/audjustable/zipball/master) which includes a simple audio player project that streams audio over HTTP or locally using the `HttpDataSource` or `LocalFileDataSource` classes respectively.
|
||||
StreamingKit is also available as a [Cocoapod](http://cocoapods.org/?q=StreamingKit) and a static lib. You can also simply manually copy all the source files located inside StreamingKit/StreamingKit/* into your project.
|
||||
|
||||
If you would like to integrate the AudioPlayer directly into your project you only need to copy the files inside the `/Audjustable/Classes/AudioPlayer` [directory](https://github.com/tumtumtum/audjustable/tree/master/Audjustable/Classes/AudioPlayer) into your project.
|
||||
## Example
|
||||
|
||||
## Code
|
||||
|
||||
There are two main classes. The `DataSource` class which is the abstract base class for the various compressed audio data sources (HTTP, local file are provided). The `AudioPlayer` 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
|
||||
|
||||
AudioPlayer* audioPlayer = [[AudioPlayer alloc] init];
|
||||
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 play:@"http://fs.bloom.fm/oss/audiosamples/sample.mp3"];
|
||||
|
||||
[audioPlayer setDataSource:[audioPlayer dataSourceFromURL:@"https://github.com/downloads/tumtumtum/audjustable/sample.m4a"] withQueueItemId:@"item1"];
|
||||
|
||||
```
|
||||
|
||||
## Other
|
||||
## More
|
||||
|
||||
Background playback on iOS is easily added to your application by calling the `AudioSessionInitialize` in your AppDelegate.
|
||||
More documentation is available on the project [wiki](https://github.com/tumtumtum/StreamingKit/wiki)
|
||||
|
||||
### Authors and Contributors
|
||||
Copyright 2012, Thong Nguyen (@tumtumtum)
|
||||
Copyright (c) 2012-2014, Thong Nguyen (@tumtumtum)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "Audjustable"
|
||||
s.version = "0.0.4"
|
||||
s.name = "StreamingKit"
|
||||
s.version = "0.0.0"
|
||||
s.summary = "A fast and extensible audio streamer for iOS and OSX with support for gapless playback and custom (non-HTTP) sources."
|
||||
s.homepage = "http://tumtumtum.github.com/audjustable/"
|
||||
s.homepage = "https://github.com/tumtumtum/StreamingKit/"
|
||||
s.license = 'MIT'
|
||||
s.author = { "Thong Nguyen" => "tumtumtum@gmail.com" }
|
||||
s.source = { :git => "https://github.com/tumtumtum/audjustable.git", :tag => s.version.to_s}
|
||||
s.source = { :git => "https://github.com/tumtumtum/StreamingKit.git"}
|
||||
s.platform = :ios
|
||||
s.requires_arc = true
|
||||
s.source_files = 'Audjustable/Classes/AudioPlayer/*.{h,m}'
|
||||
s.source_files = 'StreamingKit/StreamingKit/*.{h,m}'
|
||||
s.frameworks = 'AVFoundation', 'SystemConfiguration', 'CFNetwork', 'CoreFoundation', 'AudioToolbox'
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "StreamingKit"
|
||||
s.version = "0.0.13"
|
||||
s.summary = "A fast and extensible audio streamer for iOS and OSX with support for gapless playback and custom (non-HTTP) sources."
|
||||
s.homepage = "https://github.com/tumtumtum/StreamingKit/"
|
||||
s.license = 'MIT'
|
||||
s.author = { "Thong Nguyen" => "tumtumtum@gmail.com" }
|
||||
s.source = { :git => "https://github.com/tumtumtum/StreamingKit.git", :tag => s.version.to_s}
|
||||
s.platform = :ios
|
||||
s.requires_arc = true
|
||||
s.source_files = 'StreamingKit/StreamingKit/*.{h,m}'
|
||||
s.frameworks = 'AVFoundation', 'SystemConfiguration', 'CFNetwork', 'CoreFoundation', 'AudioToolbox'
|
||||
end
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:ExampleApp/ExampleApp.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:StreamingKit/StreamingKit.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -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>64C9BE2D-7DAD-476A-B9AC-1C4603CD4124</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>StreamingKit</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>StreamingKit.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,471 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
A1E7C4CC188D57F50010896F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E7C4CB188D57F50010896F /* Foundation.framework */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
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 */
|
||||
A1E7C4DE188D57F60010896F /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = A1E7C4C0188D57F50010896F /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = A1E7C4C7188D57F50010896F;
|
||||
remoteInfo = StreamingKit;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
A1E7C4C6188D57F50010896F /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "include/$(PRODUCT_NAME)";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
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>"; };
|
||||
A1E7C4D8188D57F60010896F /* StreamingKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StreamingKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1E7C4D9188D57F60010896F /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
A1E7C4E3188D57F60010896F /* StreamingKitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "StreamingKitTests-Info.plist"; sourceTree = "<group>"; };
|
||||
A1E7C4E5188D57F60010896F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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 */
|
||||
A1E7C4C5188D57F50010896F /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1E7C508188D62D20010896F /* UIKit.framework in Frameworks */,
|
||||
A1E7C4CC188D57F50010896F /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1E7C4D5188D57F60010896F /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1E7C4DA188D57F60010896F /* XCTest.framework in Frameworks */,
|
||||
A1E7C4E0188D57F60010896F /* libStreamingKit.a in Frameworks */,
|
||||
A1E7C4DB188D57F60010896F /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
A1E7C4BF188D57F50010896F = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1E7C4CD188D57F50010896F /* StreamingKit */,
|
||||
A1E7C4E1188D57F60010896F /* StreamingKitTests */,
|
||||
A1E7C4CA188D57F50010896F /* Frameworks */,
|
||||
A1E7C4C9188D57F50010896F /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1E7C4C9188D57F50010896F /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1E7C4C8188D57F50010896F /* libStreamingKit.a */,
|
||||
A1E7C4D8188D57F60010896F /* StreamingKitTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1E7C4CA188D57F50010896F /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1E7C507188D62D20010896F /* UIKit.framework */,
|
||||
A1E7C4CB188D57F50010896F /* Foundation.framework */,
|
||||
A1E7C4D9188D57F60010896F /* XCTest.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1E7C4CD188D57F50010896F /* StreamingKit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1E7C4F1188D5E550010896F /* STKAudioPlayer.h */,
|
||||
A1E7C4F2188D5E550010896F /* STKAudioPlayer.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 */,
|
||||
A1E7C4FD188D5E550010896F /* STKLocalFileDataSource.h */,
|
||||
A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */,
|
||||
A1E7C4CE188D57F50010896F /* Supporting Files */,
|
||||
);
|
||||
path = StreamingKit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1E7C4CE188D57F50010896F /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1E7C4CF188D57F50010896F /* StreamingKit-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1E7C4E1188D57F60010896F /* StreamingKitTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1E7C4E7188D57F60010896F /* StreamingKitTests.m */,
|
||||
A1E7C4E2188D57F60010896F /* Supporting Files */,
|
||||
);
|
||||
path = StreamingKitTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1E7C4E2188D57F60010896F /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A1E7C4E3188D57F60010896F /* StreamingKitTests-Info.plist */,
|
||||
A1E7C4E4188D57F60010896F /* InfoPlist.strings */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
A1E7C4C7188D57F50010896F /* StreamingKit */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1E7C4EB188D57F60010896F /* Build configuration list for PBXNativeTarget "StreamingKit" */;
|
||||
buildPhases = (
|
||||
A1E7C4C4188D57F50010896F /* Sources */,
|
||||
A1E7C4C5188D57F50010896F /* Frameworks */,
|
||||
A1E7C4C6188D57F50010896F /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = StreamingKit;
|
||||
productName = StreamingKit;
|
||||
productReference = A1E7C4C8188D57F50010896F /* libStreamingKit.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
A1E7C4D7188D57F60010896F /* StreamingKitTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1E7C4EE188D57F60010896F /* Build configuration list for PBXNativeTarget "StreamingKitTests" */;
|
||||
buildPhases = (
|
||||
A1E7C4D4188D57F60010896F /* Sources */,
|
||||
A1E7C4D5188D57F60010896F /* Frameworks */,
|
||||
A1E7C4D6188D57F60010896F /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
A1E7C4DF188D57F60010896F /* PBXTargetDependency */,
|
||||
);
|
||||
name = StreamingKitTests;
|
||||
productName = StreamingKitTests;
|
||||
productReference = A1E7C4D8188D57F60010896F /* StreamingKitTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
A1E7C4C0188D57F50010896F /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
CLASSPREFIX = STK;
|
||||
LastUpgradeCheck = 0500;
|
||||
ORGANIZATIONNAME = "Thong Nguyen";
|
||||
};
|
||||
buildConfigurationList = A1E7C4C3188D57F50010896F /* Build configuration list for PBXProject "StreamingKit" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = A1E7C4BF188D57F50010896F;
|
||||
productRefGroup = A1E7C4C9188D57F50010896F /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
A1E7C4C7188D57F50010896F /* StreamingKit */,
|
||||
A1E7C4D7188D57F60010896F /* StreamingKitTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
A1E7C4D6188D57F60010896F /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1E7C4E6188D57F60010896F /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
A1E7C4C4188D57F50010896F /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1E7C501188D5E550010896F /* STKCoreFoundationDataSource.m in Sources */,
|
||||
A1E7C4FF188D5E550010896F /* STKAudioPlayer.m in Sources */,
|
||||
A1E7C505188D5E550010896F /* STKLocalFileDataSource.m in Sources */,
|
||||
A1E7C504188D5E550010896F /* STKHTTPDataSource.m in Sources */,
|
||||
A1E7C503188D5E550010896F /* STKDataSourceWrapper.m in Sources */,
|
||||
A1E7C502188D5E550010896F /* STKDataSource.m in Sources */,
|
||||
A1E7C500188D5E550010896F /* STKAutoRecoveringHTTPDataSource.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1E7C4D4188D57F60010896F /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1E7C4E8188D57F60010896F /* StreamingKitTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
A1E7C4DF188D57F60010896F /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = A1E7C4C7188D57F50010896F /* StreamingKit */;
|
||||
targetProxy = A1E7C4DE188D57F60010896F /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
A1E7C4E4188D57F60010896F /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
A1E7C4E5188D57F60010896F /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
A1E7C4E9188D57F60010896F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
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_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;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1E7C4EA188D57F60010896F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
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;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
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;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A1E7C4EC188D57F60010896F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
DSTROOT = /tmp/StreamingKit.dst;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "StreamingKit/StreamingKit-Prefix.pch";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1E7C4ED188D57F60010896F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
DSTROOT = /tmp/StreamingKit.dst;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "StreamingKit/StreamingKit-Prefix.pch";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A1E7C4EF188D57F60010896F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "StreamingKit/StreamingKit-Prefix.pch";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = "StreamingKitTests/StreamingKitTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1E7C4F0188D57F60010896F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "StreamingKit/StreamingKit-Prefix.pch";
|
||||
INFOPLIST_FILE = "StreamingKitTests/StreamingKitTests-Info.plist";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = xctest;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
A1E7C4C3188D57F50010896F /* Build configuration list for PBXProject "StreamingKit" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1E7C4E9188D57F60010896F /* Debug */,
|
||||
A1E7C4EA188D57F60010896F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A1E7C4EB188D57F60010896F /* Build configuration list for PBXNativeTarget "StreamingKit" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1E7C4EC188D57F60010896F /* Debug */,
|
||||
A1E7C4ED188D57F60010896F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A1E7C4EE188D57F60010896F /* Build configuration list for PBXNativeTarget "StreamingKitTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1E7C4EF188D57F60010896F /* Debug */,
|
||||
A1E7C4F0188D57F60010896F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = A1E7C4C0188D57F50010896F /* Project object */;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,150 @@
|
||||
/**********************************************************************************
|
||||
AudioPlayer.m
|
||||
|
||||
Created by Thong Nguyen on 14/05/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Inspired by Matt Gallagher's AudioStreamer:
|
||||
https://github.com/mattgallagher/AudioStreamer
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <pthread.h>
|
||||
#import "STKDataSource.h"
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#include "UIKit/UIApplication.h"
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STKAudioPlayerInternalStateInitialised = 0,
|
||||
STKAudioPlayerInternalStateRunning = 1,
|
||||
STKAudioPlayerInternalStatePlaying = (1 << 1) | STKAudioPlayerInternalStateRunning,
|
||||
STKAudioPlayerInternalStateRebuffering = (1 << 2) | STKAudioPlayerInternalStateRunning,
|
||||
STKAudioPlayerInternalStateStartingThread = (1 << 3) | STKAudioPlayerInternalStateRunning,
|
||||
STKAudioPlayerInternalStateWaitingForData = (1 << 4) | STKAudioPlayerInternalStateRunning,
|
||||
/* Same as STKAudioPlayerInternalStateWaitingForData but isn't immediately raised as a buffering event */
|
||||
STKAudioPlayerInternalStateWaitingForDataAfterSeek = (1 << 5) | STKAudioPlayerInternalStateRunning,
|
||||
STKAudioPlayerInternalStatePaused = (1 << 6) | STKAudioPlayerInternalStateRunning,
|
||||
STKAudioPlayerInternalStateFlushingAndStoppingButStillPlaying = (1 << 7) | STKAudioPlayerInternalStateRunning,
|
||||
STKAudioPlayerInternalStateStopping = (1 << 8),
|
||||
STKAudioPlayerInternalStateStopped = (1 << 9),
|
||||
STKAudioPlayerInternalStateDisposed = (1 << 10),
|
||||
STKAudioPlayerInternalStateError = (1 << 31)
|
||||
}
|
||||
STKAudioPlayerInternalState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STKAudioPlayerStateReady,
|
||||
STKAudioPlayerStateRunning = 1,
|
||||
STKAudioPlayerStatePlaying = (1 << 1) | STKAudioPlayerStateRunning,
|
||||
STKAudioPlayerStateBuffering = (1 << 2) | STKAudioPlayerStatePlaying,
|
||||
STKAudioPlayerStatePaused = (1 << 3) | STKAudioPlayerStateRunning,
|
||||
STKAudioPlayerStateStopped = (1 << 4),
|
||||
STKAudioPlayerStateError = (1 << 5),
|
||||
STKAudioPlayerStateDisposed = (1 << 6)
|
||||
}
|
||||
STKAudioPlayerState;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AudioPlayerStopReasonNoStop = 0,
|
||||
AudioPlayerStopReasonEof,
|
||||
AudioPlayerStopReasonUserAction,
|
||||
AudioPlayerStopReasonUserActionFlushStop
|
||||
}
|
||||
STKAudioPlayerStopReason;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STKAudioPlayerErrorNone = 0,
|
||||
STKAudioPlayerErrorDataSource,
|
||||
STKAudioPlayerErrorStreamParseBytesFailed,
|
||||
STKAudioPlayerErrorDataNotFound,
|
||||
STKAudioPlayerErrorQueueStartFailed,
|
||||
STKAudioPlayerErrorQueuePauseFailed,
|
||||
STKAudioPlayerErrorUnknownBuffer,
|
||||
STKAudioPlayerErrorQueueStopFailed,
|
||||
STKAudioPlayerErrorQueueCreationFailed,
|
||||
STKAudioPlayerErrorOther = -1
|
||||
}
|
||||
STKAudioPlayerErrorCode;
|
||||
|
||||
@class STKAudioPlayer;
|
||||
|
||||
@protocol STKAudioPlayerDelegate <NSObject>
|
||||
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didEncounterError:(STKAudioPlayerErrorCode)errorCode;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didStartPlayingQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishBufferingSourceWithQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(STKAudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration;
|
||||
@optional
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer logInfo:(NSString*)line;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer internalStateChanged:(STKAudioPlayerInternalState)state;
|
||||
-(void) audioPlayer:(STKAudioPlayer*)audioPlayer didCancelQueuedItems:(NSArray*)queuedItems;
|
||||
|
||||
@end
|
||||
|
||||
@interface STKAudioPlayer : NSObject<STKDataSourceDelegate>
|
||||
|
||||
@property (readonly) double duration;
|
||||
@property (readonly) double progress;
|
||||
@property (readwrite) STKAudioPlayerState state;
|
||||
@property (readonly) STKAudioPlayerStopReason stopReason;
|
||||
@property (readwrite, unsafe_unretained) id<STKAudioPlayerDelegate> delegate;
|
||||
@property (readwrite) BOOL meteringEnabled;
|
||||
|
||||
-(id) init;
|
||||
-(id) initWithNumberOfAudioQueueBuffers:(int)numberOfAudioQueueBuffers andReadBufferSize:(int)readBufferSizeIn;
|
||||
-(STKDataSource*) dataSourceFromURL:(NSURL*)url;
|
||||
-(void) play:(NSString*)urlString;
|
||||
-(void) playWithURL:(NSURL*)url;
|
||||
-(void) playWithDataSource:(STKDataSource*)dataSource;
|
||||
-(void) queueDataSource:(STKDataSource*)dataSource withQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) setDataSource:(STKDataSource*)dataSourceIn withQueueItemId:(NSObject*)queueItemId;
|
||||
-(void) seekToTime:(double)value;
|
||||
-(void) clearQueue;
|
||||
-(void) pause;
|
||||
-(void) resume;
|
||||
-(void) stop;
|
||||
-(void) flushStop;
|
||||
-(void) mute;
|
||||
-(void) unmute;
|
||||
-(void) dispose;
|
||||
-(NSObject*) currentlyPlayingQueueItemId;
|
||||
-(void) updateMeters;
|
||||
-(float) peakPowerInDecibelsForChannel:(NSUInteger)channelNumber;
|
||||
-(float) averagePowerInDecibelsForChannel:(NSUInteger)channelNumber;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
+12
-12
@@ -5,7 +5,7 @@
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
@@ -15,15 +15,15 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
@@ -32,14 +32,14 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "DataSource.h"
|
||||
#import "HttpDataSource.h"
|
||||
#import "DataSourceWrapper.h"
|
||||
#import "STKDataSource.h"
|
||||
#import "STKHTTPDataSource.h"
|
||||
#import "STKDataSourceWrapper.h"
|
||||
|
||||
@interface AutoRecoveringHttpDataSource : DataSourceWrapper
|
||||
@interface STKAutoRecoveringHTTPDataSource : STKDataSourceWrapper
|
||||
|
||||
-(id) initWithHttpDataSource:(HttpDataSource*)innerDataSource;
|
||||
-(id) initWithHTTPDataSource:(STKHTTPDataSource*)innerDataSource;
|
||||
|
||||
@property (readonly) HttpDataSource* innerDataSource;
|
||||
@property (readonly) STKHTTPDataSource* innerDataSource;
|
||||
|
||||
@end
|
||||
+83
-27
@@ -1,11 +1,11 @@
|
||||
/**********************************************************************************
|
||||
AudioPlayer.m
|
||||
|
||||
|
||||
Created by Thong Nguyen on 16/10/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
@@ -15,12 +15,12 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
@@ -40,13 +40,14 @@
|
||||
#import <netdb.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
#import "AutoRecoveringHttpDataSource.h"
|
||||
#import "STKAutoRecoveringHTTPDataSource.h"
|
||||
|
||||
#define MAX_IMMEDIATE_RECONNECT_ATTEMPTS (8)
|
||||
#define MAX_IMMEDIATE_RECONNECT_ATTEMPTS (2)
|
||||
|
||||
@interface AutoRecoveringHttpDataSource()
|
||||
@interface STKAutoRecoveringHTTPDataSource()
|
||||
{
|
||||
int reconnectAttempts;
|
||||
int serial;
|
||||
int waitSeconds;
|
||||
BOOL waitingForNetwork;
|
||||
SCNetworkReachabilityRef reachabilityRef;
|
||||
}
|
||||
@@ -59,20 +60,25 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
AutoRecoveringHttpDataSource* dataSource = (__bridge AutoRecoveringHttpDataSource*)info;
|
||||
STKAutoRecoveringHTTPDataSource* dataSource = (__bridge STKAutoRecoveringHTTPDataSource*)info;
|
||||
|
||||
[dataSource reachabilityChanged];
|
||||
}
|
||||
}
|
||||
|
||||
@implementation AutoRecoveringHttpDataSource
|
||||
@implementation STKAutoRecoveringHTTPDataSource
|
||||
|
||||
-(HttpDataSource*) innerHttpDataSource
|
||||
-(STKHTTPDataSource*) innerHTTPDataSource
|
||||
{
|
||||
return (HttpDataSource*)self.innerDataSource;
|
||||
return (STKHTTPDataSource*)self.innerDataSource;
|
||||
}
|
||||
|
||||
-(id) initWithHttpDataSource:(HttpDataSource*)innerDataSourceIn
|
||||
-(id) initWithDataSource:(STKDataSource *)innerDataSource
|
||||
{
|
||||
return [self initWithHTTPDataSource:(STKHTTPDataSource*)innerDataSource];
|
||||
}
|
||||
|
||||
-(id) initWithHTTPDataSource:(STKHTTPDataSource*)innerDataSourceIn
|
||||
{
|
||||
if (self = [super initWithDataSource:innerDataSourceIn])
|
||||
{
|
||||
@@ -124,7 +130,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +148,8 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
|
||||
-(void) dealloc
|
||||
{
|
||||
NSLog(@"STKAutoRecoveringHTTPDataSource dealloc");
|
||||
|
||||
self.innerDataSource.delegate = nil;
|
||||
|
||||
[self stopNotifier];
|
||||
@@ -160,25 +168,36 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
{
|
||||
waitingForNetwork = NO;
|
||||
|
||||
[self attemptReconnect];
|
||||
[self attemptReconnectWithSerial:@(serial)];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) dataSourceDataAvailable:(DataSource*)dataSource
|
||||
-(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) dataSourceErrorOccured:(DataSource*)dataSource
|
||||
-(void) attemptReconnectWithTimer:(NSTimer*)timer
|
||||
{
|
||||
[self attemptReconnectWithSerial:(NSNumber*)timer.userInfo];
|
||||
}
|
||||
|
||||
-(void) processRetryOnError
|
||||
{
|
||||
if (![self hasGotNetworkConnection])
|
||||
{
|
||||
@@ -187,14 +206,51 @@ static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReach
|
||||
return;
|
||||
}
|
||||
|
||||
if (reconnectAttempts > MAX_IMMEDIATE_RECONNECT_ATTEMPTS)
|
||||
NSRunLoop* runLoop = self.innerDataSource.eventsRunLoop;
|
||||
|
||||
if (runLoop == nil)
|
||||
{
|
||||
[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])
|
||||
{
|
||||
[self processRetryOnError];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
[self.delegate dataSourceEof:self];
|
||||
}
|
||||
|
||||
-(void) dataSourceErrorOccured:(STKDataSource*)dataSource
|
||||
{
|
||||
NSLog(@"dataSourceErrorOccured");
|
||||
|
||||
if (self.innerDataSource.httpStatusCode == 416 /* Range out of bounds */)
|
||||
{
|
||||
[super dataSourceEof:dataSource];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self processRetryOnError];
|
||||
}
|
||||
}
|
||||
|
||||
-(NSString*) description
|
||||
{
|
||||
return [NSString stringWithFormat:@"HTTP data source with file length: %lld and position: %lld", self.length, self.position];
|
||||
}
|
||||
|
||||
@end
|
||||
+13
-8
@@ -15,15 +15,15 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
@@ -32,26 +32,31 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "DataSource.h"
|
||||
#import "STKDataSource.h"
|
||||
|
||||
@class CoreFoundationDataSource;
|
||||
@class STKCoreFoundationDataSource;
|
||||
|
||||
@interface CoreFoundationDataSourceClientInfo : NSObject
|
||||
@property (readwrite) CFReadStreamRef readStreamRef;
|
||||
@property (readwrite, retain) CoreFoundationDataSource* datasource;
|
||||
@property (readwrite, retain) STKCoreFoundationDataSource* datasource;
|
||||
@end
|
||||
|
||||
@interface CoreFoundationDataSource : DataSource
|
||||
@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
|
||||
+40
-17
@@ -15,15 +15,15 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
@@ -32,11 +32,11 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "CoreFoundationDataSource.h"
|
||||
#import "STKCoreFoundationDataSource.h"
|
||||
|
||||
static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eventType, void* inClientInfo)
|
||||
{
|
||||
CoreFoundationDataSource* datasource = (__bridge CoreFoundationDataSource*)inClientInfo;
|
||||
STKCoreFoundationDataSource* datasource = (__bridge STKCoreFoundationDataSource*)inClientInfo;
|
||||
|
||||
switch (eventType)
|
||||
{
|
||||
@@ -58,7 +58,12 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
@synthesize readStreamRef, datasource;
|
||||
@end
|
||||
|
||||
@implementation CoreFoundationDataSource
|
||||
@implementation STKCoreFoundationDataSource
|
||||
|
||||
-(BOOL) isInErrorState
|
||||
{
|
||||
return self->isInErrorState;
|
||||
}
|
||||
|
||||
-(void) dataAvailable
|
||||
{
|
||||
@@ -72,6 +77,8 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
|
||||
-(void) errorOccured
|
||||
{
|
||||
self->isInErrorState = YES;
|
||||
|
||||
[self.delegate dataSourceErrorOccured:self];
|
||||
}
|
||||
|
||||
@@ -98,13 +105,17 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
}
|
||||
}
|
||||
|
||||
-(void) open
|
||||
{
|
||||
}
|
||||
|
||||
-(void) seekToOffset:(long long)offset
|
||||
{
|
||||
}
|
||||
|
||||
-(int) readIntoBuffer:(UInt8*)buffer withSize:(int)size
|
||||
{
|
||||
return CFReadStreamRead(stream, buffer, size);
|
||||
return (int)CFReadStreamRead(stream, buffer, size);
|
||||
}
|
||||
|
||||
-(void) unregisterForEvents
|
||||
@@ -133,19 +144,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 +171,14 @@ static void ReadStreamCallbackProc(CFReadStreamRef stream, CFStreamEventType eve
|
||||
return CFReadStreamHasBytesAvailable(stream);
|
||||
}
|
||||
|
||||
-(CFStreamStatus) status
|
||||
{
|
||||
if (stream)
|
||||
{
|
||||
return CFReadStreamGetStatus(stream);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
||||
+11
-11
@@ -15,15 +15,15 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
@@ -35,12 +35,12 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
@class DataSource;
|
||||
@class STKDataSource;
|
||||
|
||||
@protocol DataSourceDelegate<NSObject>
|
||||
-(void) dataSourceDataAvailable:(DataSource*)dataSource;
|
||||
-(void) dataSourceErrorOccured:(DataSource*)dataSource;
|
||||
-(void) dataSourceEof:(DataSource*)dataSource;
|
||||
@protocol STKDataSourceDelegate<NSObject>
|
||||
-(void) dataSourceDataAvailable:(STKDataSource*)dataSource;
|
||||
-(void) dataSourceErrorOccured:(STKDataSource*)dataSource;
|
||||
-(void) dataSourceEof:(STKDataSource*)dataSource;
|
||||
@end
|
||||
|
||||
@protocol AudioDataSource<NSObject>
|
||||
@@ -48,12 +48,12 @@
|
||||
@property (readwrite) long long audioDataOffset;
|
||||
@end
|
||||
|
||||
@interface DataSource : NSObject
|
||||
@interface STKDataSource : NSObject
|
||||
|
||||
@property (readonly) long long position;
|
||||
@property (readonly) long long length;
|
||||
@property (readonly) BOOL hasBytesAvailable;
|
||||
@property (readwrite, unsafe_unretained) id<DataSourceDelegate> delegate;
|
||||
@property (readwrite, unsafe_unretained) id<STKDataSourceDelegate> delegate;
|
||||
|
||||
-(BOOL) registerForEvents:(NSRunLoop*)runLoop;
|
||||
-(void) unregisterForEvents;
|
||||
+6
-6
@@ -15,15 +15,15 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
@@ -32,9 +32,9 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "DataSource.h"
|
||||
#import "STKDataSource.h"
|
||||
|
||||
@implementation DataSource
|
||||
@implementation STKDataSource
|
||||
@synthesize delegate;
|
||||
|
||||
-(long long) length
|
||||
+9
-9
@@ -5,7 +5,7 @@
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
@@ -15,12 +15,12 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
@@ -32,12 +32,12 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "DataSource.h"
|
||||
#import "STKDataSource.h"
|
||||
|
||||
@interface DataSourceWrapper : DataSource<DataSourceDelegate>
|
||||
@interface STKDataSourceWrapper : STKDataSource<STKDataSourceDelegate>
|
||||
|
||||
-(id) initWithDataSource:(DataSource*)innerDataSource;
|
||||
-(id) initWithDataSource:(STKDataSource*)innerDataSource;
|
||||
|
||||
@property (readonly) DataSource* innerDataSource;
|
||||
@property (readonly) STKDataSource* innerDataSource;
|
||||
|
||||
@end
|
||||
+13
-13
@@ -5,7 +5,7 @@
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
@@ -15,12 +15,12 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
@@ -32,15 +32,15 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "DataSourceWrapper.h"
|
||||
#import "STKDataSourceWrapper.h"
|
||||
|
||||
@interface DataSourceWrapper()
|
||||
@property (readwrite) DataSource* innerDataSource;
|
||||
@interface STKDataSourceWrapper()
|
||||
@property (readwrite) STKDataSource* innerDataSource;
|
||||
@end
|
||||
|
||||
@implementation DataSourceWrapper
|
||||
@implementation STKDataSourceWrapper
|
||||
|
||||
-(id) initWithDataSource:(DataSource*)innerDataSourceIn
|
||||
-(id) initWithDataSource:(STKDataSource*)innerDataSourceIn
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
@@ -102,17 +102,17 @@
|
||||
return self.innerDataSource.hasBytesAvailable;
|
||||
}
|
||||
|
||||
-(void) dataSourceDataAvailable:(DataSource*)dataSource
|
||||
-(void) dataSourceDataAvailable:(STKDataSource*)dataSource
|
||||
{
|
||||
[self.delegate dataSourceDataAvailable:self];
|
||||
}
|
||||
|
||||
-(void) dataSourceErrorOccured:(DataSource*)dataSource
|
||||
-(void) dataSourceErrorOccured:(STKDataSource*)dataSource
|
||||
{
|
||||
[self.delegate dataSourceErrorOccured:self];
|
||||
}
|
||||
|
||||
-(void) dataSourceEof:(DataSource*)dataSource
|
||||
-(void) dataSourceEof:(STKDataSource*)dataSource
|
||||
{
|
||||
[self.delegate dataSourceEof:self];
|
||||
}
|
||||
+18
-17
@@ -15,39 +15,40 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
**********************************************************************************/
|
||||
|
||||
#import "CoreFoundationDataSource.h"
|
||||
#import "STKCoreFoundationDataSource.h"
|
||||
|
||||
@interface HttpDataSource : CoreFoundationDataSource
|
||||
{
|
||||
@private
|
||||
int seekStart;
|
||||
int relativePosition;
|
||||
int 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
|
||||
@@ -0,0 +1,327 @@
|
||||
/**********************************************************************************
|
||||
AudioPlayer.m
|
||||
|
||||
Created by Thong Nguyen on 14/05/2012.
|
||||
https://github.com/tumtumtum/audjustable
|
||||
|
||||
Copyright (c) 2012 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:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "STKHTTPDataSource.h"
|
||||
#import "STKLocalFileDataSource.h"
|
||||
|
||||
@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
|
||||
|
||||
-(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])
|
||||
{
|
||||
seekStart = 0;
|
||||
relativePosition = 0;
|
||||
fileLength = -1;
|
||||
|
||||
self->asyncUrlProvider = [asyncUrlProviderIn copy];
|
||||
|
||||
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;
|
||||
static NSDictionary* fileTypesByMimeType;
|
||||
|
||||
dispatch_once(&onceToken, ^
|
||||
{
|
||||
fileTypesByMimeType =
|
||||
@{
|
||||
@"audio/mp3": @(kAudioFileMP3Type),
|
||||
@"audio/mpg": @(kAudioFileMP3Type),
|
||||
@"audio/mpeg": @(kAudioFileMP3Type),
|
||||
@"audio/wav": @(kAudioFileWAVEType),
|
||||
@"audio/aifc": @(kAudioFileAIFCType),
|
||||
@"audio/aiff": @(kAudioFileAIFFType),
|
||||
@"audio/x-m4a": @(kAudioFileM4AType),
|
||||
@"audio/x-mp4": @(kAudioFileMPEG4Type),
|
||||
@"audio/aacp": @(kAudioFileAAC_ADTSType),
|
||||
@"audio/m4a": @(kAudioFileM4AType),
|
||||
@"audio/mp4": @(kAudioFileMPEG4Type),
|
||||
@"audio/caf": @(kAudioFileCAFType),
|
||||
@"audio/aac": @(kAudioFileAAC_ADTSType),
|
||||
@"audio/ac3": @(kAudioFileAC3Type),
|
||||
@"audio/3gp": @(kAudioFile3GPType)
|
||||
};
|
||||
});
|
||||
|
||||
NSNumber* number = [fileTypesByMimeType objectForKey:mimeType];
|
||||
|
||||
if (!number)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (AudioFileTypeID)number.intValue;
|
||||
}
|
||||
|
||||
-(AudioFileTypeID) audioFileTypeHint
|
||||
{
|
||||
return audioFileTypeHint;
|
||||
}
|
||||
|
||||
-(void) dataAvailable
|
||||
{
|
||||
if (fileLength < 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];
|
||||
}
|
||||
|
||||
-(long long) position
|
||||
{
|
||||
return seekStart + relativePosition;
|
||||
}
|
||||
|
||||
-(long long) length
|
||||
{
|
||||
return fileLength >= 0 ? fileLength : 0;
|
||||
}
|
||||
|
||||
-(void) seekToOffset:(long long)offset
|
||||
{
|
||||
if (eventsRunLoop)
|
||||
{
|
||||
[self unregisterForEvents];
|
||||
}
|
||||
|
||||
if (stream)
|
||||
{
|
||||
CFReadStreamClose(stream);
|
||||
CFRelease(stream);
|
||||
}
|
||||
|
||||
NSAssert([NSRunLoop currentRunLoop] == eventsRunLoop, @"Seek called on wrong thread");
|
||||
|
||||
stream = 0;
|
||||
relativePosition = 0;
|
||||
seekStart = offset;
|
||||
|
||||
self->isInErrorState = NO;
|
||||
|
||||
[self openForSeek:YES];
|
||||
}
|
||||
|
||||
-(int) readIntoBuffer:(UInt8*)buffer withSize:(int)size
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read = (int)CFReadStreamRead(stream, buffer, size);
|
||||
|
||||
if (read < 0)
|
||||
{
|
||||
return read;
|
||||
}
|
||||
|
||||
relativePosition += read;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
-(void) open
|
||||
{
|
||||
return [self openForSeek:NO];
|
||||
}
|
||||
|
||||
-(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];
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
@end
|
||||
+6
-14
@@ -15,15 +15,15 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
@@ -32,20 +32,12 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "CoreFoundationDataSource.h"
|
||||
#import "STKCoreFoundationDataSource.h"
|
||||
|
||||
@interface LocalFileDataSource : CoreFoundationDataSource
|
||||
{
|
||||
@private
|
||||
long long position;
|
||||
long long length;
|
||||
AudioFileTypeID audioFileTypeHint;
|
||||
}
|
||||
@interface STKLocalFileDataSource : STKCoreFoundationDataSource
|
||||
|
||||
+(AudioFileTypeID) audioFileTypeHintFromFileExtension:(NSString*)fileExtension;
|
||||
|
||||
@property (readonly, copy) NSString* filePath;
|
||||
|
||||
-(id) initWithFilePath:(NSString*)filePath;
|
||||
|
||||
@end
|
||||
+35
-18
@@ -15,15 +15,15 @@
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
This product includes software developed by the <organization>.
|
||||
4. Neither the name of the <organization> nor the
|
||||
This product includes software developed by Thong Nguyen (tumtumtum@gmail.com)
|
||||
4. Neither the name of Thong Nguyen nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY
|
||||
THIS SOFTWARE IS PROVIDED BY Thong Nguyen ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL THONG NGUYEN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
@@ -32,15 +32,19 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**********************************************************************************/
|
||||
|
||||
#import "LocalFileDataSource.h"
|
||||
#import "STKLocalFileDataSource.h"
|
||||
|
||||
@interface LocalFileDataSource()
|
||||
@interface STKLocalFileDataSource()
|
||||
{
|
||||
long long position;
|
||||
long long length;
|
||||
AudioFileTypeID audioFileTypeHint;
|
||||
}
|
||||
@property (readwrite, copy) NSString* filePath;
|
||||
|
||||
-(void) open;
|
||||
@end
|
||||
|
||||
@implementation LocalFileDataSource
|
||||
@implementation STKLocalFileDataSource
|
||||
@synthesize filePath;
|
||||
|
||||
-(id) initWithFilePath:(NSString*)filePathIn
|
||||
@@ -49,9 +53,7 @@
|
||||
{
|
||||
self.filePath = filePathIn;
|
||||
|
||||
[self open];
|
||||
|
||||
audioFileTypeHint = [LocalFileDataSource audioFileTypeHintFromFileExtension:filePathIn.pathExtension];
|
||||
audioFileTypeHint = [STKLocalFileDataSource audioFileTypeHintFromFileExtension:filePathIn.pathExtension];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -103,6 +105,8 @@
|
||||
{
|
||||
if (stream)
|
||||
{
|
||||
[self unregisterForEvents];
|
||||
|
||||
CFReadStreamClose(stream);
|
||||
|
||||
stream = 0;
|
||||
@@ -111,27 +115,41 @@
|
||||
|
||||
-(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);
|
||||
|
||||
SInt32 errorCode;
|
||||
|
||||
NSNumber* number = (__bridge_transfer NSNumber*)CFURLCreatePropertyFromResource(NULL, (__bridge CFURLRef)url, kCFURLFileLength, &errorCode);
|
||||
NSError* fileError;
|
||||
NSFileManager* manager = [[NSFileManager alloc] init];
|
||||
NSDictionary* attributes = [manager attributesOfItemAtPath:filePath error:&fileError];
|
||||
|
||||
if (fileError)
|
||||
{
|
||||
CFReadStreamClose(stream);
|
||||
CFRelease(stream);
|
||||
stream = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
NSNumber* number = [attributes objectForKey:@"NSFileSize"];
|
||||
|
||||
if (number)
|
||||
{
|
||||
length = number.longLongValue;
|
||||
}
|
||||
|
||||
[self reregisterForEvents];
|
||||
|
||||
CFReadStreamOpen(stream);
|
||||
}
|
||||
|
||||
@@ -147,7 +165,7 @@
|
||||
|
||||
-(int) readIntoBuffer:(UInt8*)buffer withSize:(int)size
|
||||
{
|
||||
int retval = CFReadStreamRead(stream, buffer, size);
|
||||
int retval = (int)CFReadStreamRead(stream, buffer, size);
|
||||
|
||||
if (retval > 0)
|
||||
{
|
||||
@@ -180,7 +198,6 @@
|
||||
|
||||
[self close];
|
||||
[self open];
|
||||
[self reregisterForEvents];
|
||||
}
|
||||
|
||||
if (CFReadStreamSetProperty(stream, kCFStreamPropertyFileCurrentOffset, (__bridge CFTypeRef)[NSNumber numberWithLongLong:offset]) != TRUE)
|
||||
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Prefix header
|
||||
//
|
||||
// The contents of this file are implicitly included at the beginning of every source file.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
||||
@@ -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>abstractpath.com.${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 @@
|
||||
//
|
||||
// StreamingKitTests.m
|
||||
// StreamingKitTests
|
||||
//
|
||||
// Created by Thong Nguyen on 20/01/2014.
|
||||
// Copyright (c) 2014 Thong Nguyen. All rights reserved.
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface StreamingKitTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation StreamingKitTests
|
||||
|
||||
- (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