diff --git a/ExampleApp/ExampleApp/AppDelegate.m b/ExampleApp/ExampleApp/AppDelegate.m index 1bba755..495753b 100644 --- a/ExampleApp/ExampleApp/AppDelegate.m +++ b/ExampleApp/ExampleApp/AppDelegate.m @@ -32,7 +32,7 @@ self.window.backgroundColor = [UIColor whiteColor]; - audioPlayer = [[STKAudioPlayer alloc] init]; + audioPlayer = [[STKAudioPlayer alloc] initWithOptions:STKAudioPlayerOptionFlushQueueOnSeek]; audioPlayer.meteringEnabled = YES; AudioPlayerView* audioPlayerView = [[AudioPlayerView alloc] initWithFrame:self.window.bounds]; diff --git a/ExampleApp/ExampleApp/AudioPlayerView.m b/ExampleApp/ExampleApp/AudioPlayerView.m index 6ac44ac..28ab1a7 100644 --- a/ExampleApp/ExampleApp/AudioPlayerView.m +++ b/ExampleApp/ExampleApp/AudioPlayerView.m @@ -292,7 +292,7 @@ return audioPlayer; } --(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state +-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state previousState:(STKAudioPlayerState)previousState { [self updateControls]; } diff --git a/StreamingKit/StreamingKit.xcodeproj/project.pbxproj b/StreamingKit/StreamingKit.xcodeproj/project.pbxproj index 0fabf5d..5b1c441 100644 --- a/StreamingKit/StreamingKit.xcodeproj/project.pbxproj +++ b/StreamingKit/StreamingKit.xcodeproj/project.pbxproj @@ -7,6 +7,22 @@ objects = { /* Begin PBXBuildFile section */ + A1A4996B189E744400E2A2E2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A4996A189E744400E2A2E2 /* Cocoa.framework */; }; + A1A49975189E744500E2A2E2 /* StreamingKitMac.m in Sources */ = {isa = PBXBuildFile; fileRef = A1A49974189E744500E2A2E2 /* StreamingKitMac.m */; }; + A1A4997B189E744500E2A2E2 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1E7C4D9188D57F60010896F /* XCTest.framework */; }; + A1A4997C189E744500E2A2E2 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A4996A189E744400E2A2E2 /* Cocoa.framework */; }; + A1A4997F189E744500E2A2E2 /* libStreamingKitMac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A1A49969189E744400E2A2E2 /* libStreamingKitMac.a */; }; + A1A49985189E744500E2A2E2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A1A49983189E744500E2A2E2 /* InfoPlist.strings */; }; + A1A49987189E744500E2A2E2 /* StreamingKitMacTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A1A49986189E744500E2A2E2 /* StreamingKitMacTests.m */; }; + A1A4998E189E745900E2A2E2 /* STKAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F2188D5E550010896F /* STKAudioPlayer.m */; }; + A1A4998F189E745C00E2A2E2 /* STKAutoRecoveringHTTPDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F4188D5E550010896F /* STKAutoRecoveringHTTPDataSource.m */; }; + A1A49991189E746000E2A2E2 /* STKCoreFoundationDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F6188D5E550010896F /* STKCoreFoundationDataSource.m */; }; + A1A49992189E746300E2A2E2 /* STKDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4F8188D5E550010896F /* STKDataSource.m */; }; + A1A49993189E746500E2A2E2 /* STKDataSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FA188D5E550010896F /* STKDataSourceWrapper.m */; }; + A1A49994189E746900E2A2E2 /* STKHTTPDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FC188D5E550010896F /* STKHTTPDataSource.m */; }; + A1A49995189E746B00E2A2E2 /* STKLocalFileDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */; }; + A1A49996189E746E00E2A2E2 /* STKQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BF65D1189A6582004DD08C /* STKQueueEntry.m */; }; + A1A49997189E747000E2A2E2 /* NSMutableArray+STKAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BF65D4189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m */; }; A1BF65D2189A6582004DD08C /* STKQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BF65D1189A6582004DD08C /* STKQueueEntry.m */; }; A1BF65D5189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A1BF65D4189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.m */; }; A1C9767718981BFE0057F881 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1C9767618981BFE0057F881 /* AudioUnit.framework */; }; @@ -27,6 +43,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + A1A4997D189E744500E2A2E2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = A1E7C4C0188D57F50010896F /* Project object */; + proxyType = 1; + remoteGlobalIDString = A1A49968189E744400E2A2E2; + remoteInfo = StreamingKitMac; + }; A1E7C4DE188D57F60010896F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = A1E7C4C0188D57F50010896F /* Project object */; @@ -49,6 +72,18 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + A1A49969189E744400E2A2E2 /* libStreamingKitMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libStreamingKitMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A1A4996A189E744400E2A2E2 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; + A1A4996D189E744500E2A2E2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + A1A4996E189E744500E2A2E2 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + A1A4996F189E744500E2A2E2 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + A1A49972189E744500E2A2E2 /* StreamingKitMac-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StreamingKitMac-Prefix.pch"; sourceTree = ""; }; + A1A49973189E744500E2A2E2 /* StreamingKitMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StreamingKitMac.h; sourceTree = ""; }; + A1A49974189E744500E2A2E2 /* StreamingKitMac.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StreamingKitMac.m; sourceTree = ""; }; + A1A4997A189E744500E2A2E2 /* StreamingKitMacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StreamingKitMacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + A1A49982189E744500E2A2E2 /* StreamingKitMacTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "StreamingKitMacTests-Info.plist"; sourceTree = ""; }; + A1A49984189E744500E2A2E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + A1A49986189E744500E2A2E2 /* StreamingKitMacTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StreamingKitMacTests.m; sourceTree = ""; }; A1BF65D0189A6582004DD08C /* STKQueueEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKQueueEntry.h; sourceTree = ""; }; A1BF65D1189A6582004DD08C /* STKQueueEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKQueueEntry.m; sourceTree = ""; }; A1BF65D3189A65C6004DD08C /* NSMutableArray+STKAudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+STKAudioPlayer.h"; sourceTree = ""; }; @@ -80,6 +115,24 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + A1A49966189E744400E2A2E2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A1A4996B189E744400E2A2E2 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A1A49977189E744500E2A2E2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A1A4997C189E744500E2A2E2 /* Cocoa.framework in Frameworks */, + A1A4997B189E744500E2A2E2 /* XCTest.framework in Frameworks */, + A1A4997F189E744500E2A2E2 /* libStreamingKitMac.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A1E7C4C5188D57F50010896F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -103,11 +156,59 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + A1A4996C189E744500E2A2E2 /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + A1A4996D189E744500E2A2E2 /* Foundation.framework */, + A1A4996E189E744500E2A2E2 /* CoreData.framework */, + A1A4996F189E744500E2A2E2 /* AppKit.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + A1A49970189E744500E2A2E2 /* StreamingKitMac */ = { + isa = PBXGroup; + children = ( + A1A49973189E744500E2A2E2 /* StreamingKitMac.h */, + A1A49974189E744500E2A2E2 /* StreamingKitMac.m */, + A1A49971189E744500E2A2E2 /* Supporting Files */, + ); + path = StreamingKitMac; + sourceTree = ""; + }; + A1A49971189E744500E2A2E2 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + A1A49972189E744500E2A2E2 /* StreamingKitMac-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + A1A49980189E744500E2A2E2 /* StreamingKitMacTests */ = { + isa = PBXGroup; + children = ( + A1A49986189E744500E2A2E2 /* StreamingKitMacTests.m */, + A1A49981189E744500E2A2E2 /* Supporting Files */, + ); + path = StreamingKitMacTests; + sourceTree = ""; + }; + A1A49981189E744500E2A2E2 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + A1A49982189E744500E2A2E2 /* StreamingKitMacTests-Info.plist */, + A1A49983189E744500E2A2E2 /* InfoPlist.strings */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; A1E7C4BF188D57F50010896F = { isa = PBXGroup; children = ( A1E7C4CD188D57F50010896F /* StreamingKit */, A1E7C4E1188D57F60010896F /* StreamingKitTests */, + A1A49970189E744500E2A2E2 /* StreamingKitMac */, + A1A49980189E744500E2A2E2 /* StreamingKitMacTests */, A1E7C4CA188D57F50010896F /* Frameworks */, A1E7C4C9188D57F50010896F /* Products */, ); @@ -118,6 +219,8 @@ children = ( A1E7C4C8188D57F50010896F /* libStreamingKit.a */, A1E7C4D8188D57F60010896F /* StreamingKitTests.xctest */, + A1A49969189E744400E2A2E2 /* libStreamingKitMac.a */, + A1A4997A189E744500E2A2E2 /* StreamingKitMacTests.xctest */, ); name = Products; sourceTree = ""; @@ -129,6 +232,8 @@ A1E7C507188D62D20010896F /* UIKit.framework */, A1E7C4CB188D57F50010896F /* Foundation.framework */, A1E7C4D9188D57F60010896F /* XCTest.framework */, + A1A4996A189E744400E2A2E2 /* Cocoa.framework */, + A1A4996C189E744500E2A2E2 /* Other Frameworks */, ); name = Frameworks; sourceTree = ""; @@ -187,7 +292,52 @@ }; /* End PBXGroup section */ +/* Begin PBXHeadersBuildPhase section */ + A1A49967189E744400E2A2E2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + /* Begin PBXNativeTarget section */ + A1A49968189E744400E2A2E2 /* StreamingKitMac */ = { + isa = PBXNativeTarget; + buildConfigurationList = A1A4998C189E744500E2A2E2 /* Build configuration list for PBXNativeTarget "StreamingKitMac" */; + buildPhases = ( + A1A49965189E744400E2A2E2 /* Sources */, + A1A49966189E744400E2A2E2 /* Frameworks */, + A1A49967189E744400E2A2E2 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = StreamingKitMac; + productName = StreamingKitMac; + productReference = A1A49969189E744400E2A2E2 /* libStreamingKitMac.a */; + productType = "com.apple.product-type.library.static"; + }; + A1A49979189E744500E2A2E2 /* StreamingKitMacTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = A1A4998D189E744500E2A2E2 /* Build configuration list for PBXNativeTarget "StreamingKitMacTests" */; + buildPhases = ( + A1A49976189E744500E2A2E2 /* Sources */, + A1A49977189E744500E2A2E2 /* Frameworks */, + A1A49978189E744500E2A2E2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + A1A4997E189E744500E2A2E2 /* PBXTargetDependency */, + ); + name = StreamingKitMacTests; + productName = StreamingKitMacTests; + productReference = A1A4997A189E744500E2A2E2 /* StreamingKitMacTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; A1E7C4C7188D57F50010896F /* StreamingKit */ = { isa = PBXNativeTarget; buildConfigurationList = A1E7C4EB188D57F60010896F /* Build configuration list for PBXNativeTarget "StreamingKit" */; @@ -247,11 +397,21 @@ targets = ( A1E7C4C7188D57F50010896F /* StreamingKit */, A1E7C4D7188D57F60010896F /* StreamingKitTests */, + A1A49968189E744400E2A2E2 /* StreamingKitMac */, + A1A49979189E744500E2A2E2 /* StreamingKitMacTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + A1A49978189E744500E2A2E2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A1A49985189E744500E2A2E2 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A1E7C4D6188D57F60010896F /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -263,6 +423,31 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + A1A49965189E744400E2A2E2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A1A4998F189E745C00E2A2E2 /* STKAutoRecoveringHTTPDataSource.m in Sources */, + A1A49994189E746900E2A2E2 /* STKHTTPDataSource.m in Sources */, + A1A49991189E746000E2A2E2 /* STKCoreFoundationDataSource.m in Sources */, + A1A49995189E746B00E2A2E2 /* STKLocalFileDataSource.m in Sources */, + A1A49997189E747000E2A2E2 /* NSMutableArray+STKAudioPlayer.m in Sources */, + A1A4998E189E745900E2A2E2 /* STKAudioPlayer.m in Sources */, + A1A49993189E746500E2A2E2 /* STKDataSourceWrapper.m in Sources */, + A1A49992189E746300E2A2E2 /* STKDataSource.m in Sources */, + A1A49975189E744500E2A2E2 /* StreamingKitMac.m in Sources */, + A1A49996189E746E00E2A2E2 /* STKQueueEntry.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A1A49976189E744500E2A2E2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A1A49987189E744500E2A2E2 /* StreamingKitMacTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A1E7C4C4188D57F50010896F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -290,6 +475,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + A1A4997E189E744500E2A2E2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = A1A49968189E744400E2A2E2 /* StreamingKitMac */; + targetProxy = A1A4997D189E744500E2A2E2 /* PBXContainerItemProxy */; + }; A1E7C4DF188D57F60010896F /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = A1E7C4C7188D57F50010896F /* StreamingKit */; @@ -298,6 +488,14 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + A1A49983189E744500E2A2E2 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + A1A49984189E744500E2A2E2 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; A1E7C4E4188D57F60010896F /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -309,6 +507,86 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + A1A49988189E744500E2A2E2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Debug; + }; + A1A49989189E744500E2A2E2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch"; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Release; + }; + A1A4998A189E744500E2A2E2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "StreamingKitMacTests/StreamingKitMacTests-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + WRAPPER_EXTENSION = xctest; + }; + name = Debug; + }; + A1A4998B189E744500E2A2E2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "StreamingKitMac/StreamingKitMac-Prefix.pch"; + INFOPLIST_FILE = "StreamingKitMacTests/StreamingKitMacTests-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + WRAPPER_EXTENSION = xctest; + }; + name = Release; + }; A1E7C4E9188D57F60010896F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -454,6 +732,22 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + A1A4998C189E744500E2A2E2 /* Build configuration list for PBXNativeTarget "StreamingKitMac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A1A49988189E744500E2A2E2 /* Debug */, + A1A49989189E744500E2A2E2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; + A1A4998D189E744500E2A2E2 /* Build configuration list for PBXNativeTarget "StreamingKitMacTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A1A4998A189E744500E2A2E2 /* Debug */, + A1A4998B189E744500E2A2E2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; A1E7C4C3188D57F50010896F /* Build configuration list for PBXProject "StreamingKit" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.h b/StreamingKit/StreamingKit/STKAudioPlayer.h index 2f7a43c..a09a63f 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.h +++ b/StreamingKit/StreamingKit/STKAudioPlayer.h @@ -7,7 +7,7 @@ Inspired by Matt Gallagher's AudioStreamer: https://github.com/mattgallagher/AudioStreamer - Copyright (c) 2012 Thong Nguyen (tumtumtum@gmail.com). All rights reserved. + Copyright (c) 2012-2014 Thong Nguyen (tumtumtum@gmail.com). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -44,30 +44,12 @@ #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, - STKAudioPlayerInternalStateStopped = (1 << 9), - STKAudioPlayerInternalStatePendingNext = (1 << 10), - STKAudioPlayerInternalStateDisposed = (1 << 30), - STKAudioPlayerInternalStateError = (1 << 31) -} -STKAudioPlayerInternalState; - typedef enum { STKAudioPlayerStateReady, STKAudioPlayerStateRunning = 1, STKAudioPlayerStatePlaying = (1 << 1) | STKAudioPlayerStateRunning, - STKAudioPlayerStateBuffering = (1 << 2) | STKAudioPlayerStatePlaying, + STKAudioPlayerStateBuffering = (1 << 2) | STKAudioPlayerStateRunning, STKAudioPlayerStatePaused = (1 << 3) | STKAudioPlayerStateRunning, STKAudioPlayerStateStopped = (1 << 4), STKAudioPlayerStateError = (1 << 5), @@ -77,9 +59,10 @@ STKAudioPlayerState; typedef enum { - STKAudioPlayerStopReasonNoStop = 0, + STKAudioPlayerStopReasonNone = 0, STKAudioPlayerStopReasonEof, - STKAudioPlayerStopReasonUserAction + STKAudioPlayerStopReasonUserAction, + STKAudioPlayerStopReasonError = 0xffff } STKAudioPlayerStopReason; @@ -91,14 +74,14 @@ typedef enum STKAudioPlayerErrorAudioSystemError, STKAudioPlayerErrorCodecError, STKAudioPlayerErrorDataNotFound, - STKAudioPlayerErrorOther = -1 + STKAudioPlayerErrorOther = 0xffff } STKAudioPlayerErrorCode; typedef enum { STKAudioPlayerOptionNone = 0, - STKAudioPlayerOptionDontFlushQueueOnSeek = 1 + STKAudioPlayerOptionFlushQueueOnSeek = 1 } STKAudioPlayerOptions; @@ -106,14 +89,21 @@ STKAudioPlayerOptions; @protocol STKAudioPlayerDelegate --(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state; --(void) audioPlayer:(STKAudioPlayer*)audioPlayer unexpectedError:(STKAudioPlayerErrorCode)errorCode; +/// Raised when an item has started playing -(void) audioPlayer:(STKAudioPlayer*)audioPlayer didStartPlayingQueueItemId:(NSObject*)queueItemId; +/// Raised when an item has finished buffering (may or may not be the currently playing item) +/// This event may be raised multiple times for the same item if seek is invoked on the player -(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishBufferingSourceWithQueueItemId:(NSObject*)queueItemId; +/// Raised when the state of the player has changed +-(void) audioPlayer:(STKAudioPlayer*)audioPlayer stateChanged:(STKAudioPlayerState)state previousState:(STKAudioPlayerState)previousState; +/// Raised when an item has finished playing -(void) audioPlayer:(STKAudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(STKAudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration; +/// Raised when an unexpected and possibly unrecoverable error has occured (usually best to recreate the STKAudioPlauyer) +-(void) audioPlayer:(STKAudioPlayer*)audioPlayer unexpectedError:(STKAudioPlayerErrorCode)errorCode; @optional +/// Optionally implemented to get logging information from the STKAudioPlayer (used internally for debugging) -(void) audioPlayer:(STKAudioPlayer*)audioPlayer logInfo:(NSString*)line; --(void) audioPlayer:(STKAudioPlayer*)audioPlayer internalStateChanged:(STKAudioPlayerInternalState)state; +/// Raised when items queued items are cleared (usually because of a call to play, setDataSource or stop) -(void) audioPlayer:(STKAudioPlayer*)audioPlayer didCancelQueuedItems:(NSArray*)queuedItems; @end @@ -122,58 +112,100 @@ typedef void(^STKFrameFilter)(UInt32 channelsPerFrame, UInt32 bytesPerFrame, UIn @interface STKAudioPlayer : NSObject +/// Gets or sets the player muted state @property (readwrite) BOOL muted; +/// Gets the current item duration in seconds @property (readonly) double duration; +/// Gets the current item progress in seconds @property (readonly) double progress; +/// Enables or disables peak and average decibel meteting @property (readwrite) BOOL meteringEnabled; +/// Returns an array of STKFrameFilterEntry objects representing the filters currently in use @property (readonly) NSArray* frameFilters; +/// Returns the items pending to be played (includes buffering and upcoming items but does not include the current item) +@property (readonly) NSArray* pendingQueue; +/// The number of items pending to be played (includes buffering and upcoming items but does not include the current item) +@property (readonly) NSUInteger pendingQueueCount; +/// Gets the most recently queued item that is still pending to play +@property (readonly) NSObject* mostRecentlyQueuedStillPendingItem; +/// Gets the current state of the player @property (readwrite) STKAudioPlayerState state; +/// Gets the options provided to the player on startup @property (readonly) STKAudioPlayerOptions options; +/// Gets the reason why the player is stopped (if any) @property (readonly) STKAudioPlayerStopReason stopReason; +/// Gets and sets the delegate used for receiving events from the STKAudioPlayer @property (readwrite, unsafe_unretained) id delegate; --(id) init; --(id) initWithReadBufferSize:(int)readBufferSizeIn andOptions:(STKAudioPlayerOptions)options; - -/// Creates a datasource from a given URL -/// URLs with FILE schemes will return an STKLocalFileDataSource -/// URLs with HTTP schemes will return an STKHTTPDataSource wrapped within an STKAutoRecoveringHTTPDataSource -/// URLs with unrecognised schemes will return nil +/// Creates a datasource from a given URL. +/// URLs with FILE schemes will return an STKLocalFileDataSource. +/// URLs with HTTP schemes will return an STKHTTPDataSource wrapped within an STKAutoRecoveringHTTPDataSource. +/// URLs with unrecognised schemes will return nil. +(STKDataSource*) dataSourceFromURL:(NSURL*)url; + +/// Initializes a new STKAudioPlayer with the default options +-(id) init; + +/// Initializes a new STKAudioPlayer with the given options +-(id) initWithOptions:(STKAudioPlayerOptions)optionsIn; + /// Plays an item from the given URL (all pending queued items are removed) -(void) play:(NSString*)urlString; + /// Plays an item from the given URL (all pending queued items are removed) -(void) playWithURL:(NSURL*)url; + /// Plays the given item (all pending queued items are removed) -(void) playWithDataSource:(STKDataSource*)dataSource; -/// Queues a DataSource with the given Item ID for playback + +/// Queues a DataSource with te given Item ID for playback -(void) queueDataSource:(STKDataSource*)dataSource withQueueItemId:(NSObject*)queueItemId; + /// Plays the given item (all pending queued items are removed) -(void) setDataSource:(STKDataSource*)dataSourceIn withQueueItemId:(NSObject*)queueItemId; + /// Seeks to a specific time (in seconds) -(void) seekToTime:(double)value; -/// Clears any upcoming items already queued for playback (does not stop the current item) + +/// Clears any upcoming items already queued for playback (does not stop the current item). +/// The didCancelItems event will be raised for the items removed from the queue. -(void) clearQueue; + /// Pauses playback -(void) pause; + /// Resumes playback from pause -(void) resume; + /// Stops playback of the current file, flushes all the buffers and removes any pending queued items -(void) stop; + /// Mutes playback -(void) mute; + /// Unmutes playback -(void) unmute; + /// Disposes the STKAudioPlayer and frees up all resources before returning -(void) dispose; + /// The QueueItemId of the currently playing item -(NSObject*) currentlyPlayingQueueItemId; +/// Removes a frame filter with the given name -(void) removeFrameFilterWithName:(NSString*)name; + +/// Appends a frame filter with the given name and filter block to the end of the filter chain -(void) appendFrameFilterWithName:(NSString*)name block:(STKFrameFilter)block; + +/// Appends a frame filter with the given name and filter block just after the filter with the given name. +/// If the given name is nil, the filter will be inserted at the beginning of the filter change -(void) addFrameFilterWithName:(NSString*)name afterFilterWithName:(NSString*)afterFilterWithName block:(STKFrameFilter)block; +/// Reads the peak power in decibals for the given channel (0 or 1) -(float) peakPowerInDecibelsForChannel:(NSUInteger)channelNumber; + +/// Reads the average power in decibals for the given channel (0 or 1) -(float) averagePowerInDecibelsForChannel:(NSUInteger)channelNumber; @end diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.m b/StreamingKit/StreamingKit/STKAudioPlayer.m index 201449e..e72af96 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.m +++ b/StreamingKit/StreamingKit/STKAudioPlayer.m @@ -41,6 +41,9 @@ #import "NSMutableArray+STKAudioPlayer.h" #import "libkern/OSAtomic.h" +#define kOutputBus 0 +#define kInputBus 1 + #define STK_DBMIN (-60) #define STK_DBOFFSET (-74.0) #define STK_LOWPASSFILTERTIMESLICE (0.0005) @@ -48,19 +51,33 @@ #define STK_DEFAULT_PCM_BUFFER_SIZE_IN_SECONDS (10) #define STK_DEFAULT_SECONDS_REQUIRED_TO_START_PLAYING (0.1) #define STK_MAX_COMPRESSED_PACKETS_FOR_BITRATE_CALCULATION (2048) - -#define STK_BUFFERS_NEEDED_TO_START (32) -#define STK_BUFFERS_NEEDED_WHEN_UNDERUNNING (128) #define STK_DEFAULT_READ_BUFFER_SIZE (64 * 1024) #define STK_DEFAULT_PACKET_BUFFER_SIZE (2048) -#define STK_FRAMES_MISSED_BEFORE_CONSIDERED_UNDERRUN (1024) #define LOGINFO(x) [self logInfo:[NSString stringWithFormat:@"%s %@", sel_getName(_cmd), x]]; +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, + STKAudioPlayerInternalStateStopped = (1 << 9), + STKAudioPlayerInternalStatePendingNext = (1 << 10), + STKAudioPlayerInternalStateDisposed = (1 << 30), + STKAudioPlayerInternalStateError = (1 << 31) +} +STKAudioPlayerInternalState; + @interface STKFrameFilterEntry : NSObject { @public - NSString* name; + const NSString* name; STKFrameFilter filter; } @end @@ -186,20 +203,13 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn internalState = value; - if ([self.delegate respondsToSelector:@selector(audioPlayer:internalStateChanged:)]) - { - dispatch_async(dispatch_get_main_queue(), ^ - { - [self.delegate audioPlayer:self internalStateChanged:internalState]; - }); - } - STKAudioPlayerState newState; switch (internalState) { case STKAudioPlayerInternalStateInitialised: newState = STKAudioPlayerStateReady; + stopReason = STKAudioPlayerStopReasonNone; break; case STKAudioPlayerInternalStateRunning: case STKAudioPlayerInternalStatePendingNext: @@ -207,32 +217,39 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn case STKAudioPlayerInternalStatePlaying: case STKAudioPlayerInternalStateWaitingForDataAfterSeek: newState = STKAudioPlayerStatePlaying; + stopReason = STKAudioPlayerStopReasonNone; break; case STKAudioPlayerInternalStateRebuffering: case STKAudioPlayerInternalStateWaitingForData: newState = STKAudioPlayerStateBuffering; + stopReason = STKAudioPlayerStopReasonNone; break; case STKAudioPlayerInternalStateStopped: newState = STKAudioPlayerStateStopped; break; case STKAudioPlayerInternalStatePaused: newState = STKAudioPlayerStatePaused; + stopReason = STKAudioPlayerStopReasonNone; break; case STKAudioPlayerInternalStateDisposed: newState = STKAudioPlayerStateDisposed; + stopReason = STKAudioPlayerStopReasonUserAction; break; case STKAudioPlayerInternalStateError: newState = STKAudioPlayerStateError; + stopReason = STKAudioPlayerStopReasonError; break; } - if (newState != self.state) + STKAudioPlayerState previousState = self.state; + + if (newState != previousState) { self.state = newState; dispatch_async(dispatch_get_main_queue(), ^ { - [self.delegate audioPlayer:self stateChanged:self.state]; + [self.delegate audioPlayer:self stateChanged:self.state previousState:previousState]; }); } } @@ -265,6 +282,11 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn return [self initWithReadBufferSize:STK_DEFAULT_READ_BUFFER_SIZE andOptions:STKAudioPlayerOptionNone]; } +-(id) initWithOptions:(STKAudioPlayerOptions)optionsIn +{ + return [self initWithReadBufferSize:STK_DEFAULT_READ_BUFFER_SIZE andOptions:optionsIn]; +} + -(id) initWithReadBufferSize:(int)readBufferSizeIn andOptions:(STKAudioPlayerOptions)optionsIn { if (self = [super init]) @@ -313,9 +335,8 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn upcomingQueue = [[NSMutableArray alloc] init]; bufferingQueue = [[NSMutableArray alloc] init]; - + [self resetPcmBuffers]; - [self createAudioUnit]; [self createPlaybackThread]; } @@ -423,29 +444,18 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn { NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:bufferingQueue.count + upcomingQueue.count]; - STKQueueEntry* entry = [bufferingQueue dequeue]; - - if (entry && entry != currentlyPlayingEntry) - { - [array addObject:[entry queueItemId]]; - } - - while (bufferingQueue.count > 0) - { - id queueItemId = [[bufferingQueue dequeue] queueItemId]; - - if (queueItemId != nil) - { - [array addObject:queueItemId]; - } - } - for (STKQueueEntry* entry in upcomingQueue) { [array addObject:entry.queueItemId]; } + + for (STKQueueEntry* entry in bufferingQueue) + { + [array addObject:entry.queueItemId]; + } [upcomingQueue removeAllObjects]; + [bufferingQueue removeAllObjects]; if (array.count > 0) { @@ -507,6 +517,8 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn { pthread_mutex_lock(&playerMutex); { + [self startSystemBackgroundTask]; + [upcomingQueue enqueue:[[STKQueueEntry alloc] initWithDataSource:dataSourceIn andQueueItemId:queueItemId]]; } pthread_mutex_unlock(&playerMutex); @@ -1046,18 +1058,18 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn [currentlyReadingEntry.dataSource unregisterForEvents]; } - if (self->options & STKAudioPlayerOptionDontFlushQueueOnSeek) + if (self->options & STKAudioPlayerOptionFlushQueueOnSeek) + { + self.internalState = STKAudioPlayerInternalStateWaitingForDataAfterSeek; + [self setCurrentlyReadingEntry:currentlyPlayingEntry andStartPlaying:YES clearQueue:YES]; + } + else { [self requeueBufferingEntries]; self.internalState = STKAudioPlayerInternalStateWaitingForDataAfterSeek; [self setCurrentlyReadingEntry:currentlyPlayingEntry andStartPlaying:YES clearQueue:NO]; } - else - { - self.internalState = STKAudioPlayerInternalStateWaitingForDataAfterSeek; - [self setCurrentlyReadingEntry:currentlyPlayingEntry andStartPlaying:YES clearQueue:YES]; - } } else if (currentlyReadingEntry == nil) { @@ -1557,13 +1569,11 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn return retval; } -#define kOutputBus 0 -#define kInputBus 1 - static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* classDesc) { +#if TARGET_OS_IPHONE UInt32 size; - + if (AudioFormatGetPropertyInfo(kAudioFormatProperty_Decoders, sizeof(formatId), &formatId, &size) != 0) { return NO; @@ -1586,6 +1596,7 @@ static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* cl return YES; } } +#endif return NO; } @@ -1666,7 +1677,11 @@ static BOOL GetHardwareCodecClassDesc(UInt32 formatId, AudioClassDescription* cl AudioComponentDescription desc; desc.componentType = kAudioUnitType_Output; +#if TARGET_OS_IPHONE desc.componentSubType = kAudioUnitSubType_RemoteIO; +#else + desc.componentSubType = kAudioUnitSubType_DefaultOutput; +#endif desc.componentFlags = 0; desc.componentFlagsMask = 0; desc.componentManufacturer = kAudioUnitManufacturer_Apple; @@ -2289,6 +2304,61 @@ static OSStatus OutputRenderCallback(void* inRefCon, AudioUnitRenderActionFlags* return 0; } +-(NSArray*) pendingQueue +{ + pthread_mutex_lock(&playerMutex); + + NSArray* retval; + NSMutableArray* mutableArray = [[NSMutableArray alloc] initWithCapacity:upcomingQueue.count + bufferingQueue.count]; + + [mutableArray skipQueueWithQueue:upcomingQueue]; + [mutableArray skipQueueWithQueue:bufferingQueue]; + + retval = [NSArray arrayWithArray:mutableArray]; + + pthread_mutex_unlock(&playerMutex); + + return retval; +} + +-(NSUInteger) pendingQueueCount +{ + pthread_mutex_lock(&playerMutex); + + NSUInteger retval = upcomingQueue.count + bufferingQueue.count; + + pthread_mutex_unlock(&playerMutex); + + return retval; +} + +-(NSObject*) mostRecentlyQueuedStillPendingItem +{ + pthread_mutex_lock(&playerMutex); + + if (upcomingQueue.count > 0) + { + NSObject* retval = [upcomingQueue objectAtIndex:0]; + + pthread_mutex_unlock(&playerMutex); + + return retval; + } + + if (bufferingQueue.count > 0) + { + NSObject* retval = [bufferingQueue objectAtIndex:0]; + + pthread_mutex_unlock(&playerMutex); + + return retval; + } + + pthread_mutex_unlock(&playerMutex); + + return nil; +} + -(float) peakPowerInDecibelsForChannel:(NSUInteger)channelNumber { if (channelNumber >= canonicalAudioStreamBasicDescription.mChannelsPerFrame) diff --git a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.h b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.h index e08f767..45cc2bc 100644 --- a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.h +++ b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.h @@ -4,7 +4,7 @@ Created by Thong Nguyen on 16/10/2012. https://github.com/tumtumtum/audjustable - Copyright (c) 2012 Thong Nguyen (tumtumtum@gmail.com). All rights reserved. + Copyright (c) 2012-2014 Thong Nguyen (tumtumtum@gmail.com). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m index 87db858..d8c11a0 100644 --- a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m +++ b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m @@ -4,7 +4,7 @@ Created by Thong Nguyen on 16/10/2012. https://github.com/tumtumtum/audjustable - Copyright (c) 2012 Thong Nguyen (tumtumtum@gmail.com). All rights reserved. + Copyright (c) 2012-2014 Thong Nguyen (tumtumtum@gmail.com). All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/StreamingKit/StreamingKitMac/StreamingKitMac-Prefix.pch b/StreamingKit/StreamingKitMac/StreamingKitMac-Prefix.pch new file mode 100644 index 0000000..926a42b --- /dev/null +++ b/StreamingKit/StreamingKitMac/StreamingKitMac-Prefix.pch @@ -0,0 +1,9 @@ +// +// Prefix header +// +// The contents of this file are implicitly included at the beginning of every source file. +// + +#ifdef __OBJC__ + #import +#endif diff --git a/StreamingKit/StreamingKitMac/StreamingKitMac.h b/StreamingKit/StreamingKitMac/StreamingKitMac.h new file mode 100644 index 0000000..5fd9917 --- /dev/null +++ b/StreamingKit/StreamingKitMac/StreamingKitMac.h @@ -0,0 +1,13 @@ +// +// StreamingKitMac.h +// StreamingKitMac +// +// Created by Thong Nguyen on 02/02/2014. +// Copyright (c) 2014 Thong Nguyen. All rights reserved. +// + +#import + +@interface StreamingKitMac : NSObject + +@end diff --git a/StreamingKit/StreamingKitMac/StreamingKitMac.m b/StreamingKit/StreamingKitMac/StreamingKitMac.m new file mode 100644 index 0000000..9247514 --- /dev/null +++ b/StreamingKit/StreamingKitMac/StreamingKitMac.m @@ -0,0 +1,13 @@ +// +// StreamingKitMac.m +// StreamingKitMac +// +// Created by Thong Nguyen on 02/02/2014. +// Copyright (c) 2014 Thong Nguyen. All rights reserved. +// + +#import "StreamingKitMac.h" + +@implementation StreamingKitMac + +@end diff --git a/StreamingKit/StreamingKitMacTests/StreamingKitMacTests-Info.plist b/StreamingKit/StreamingKitMacTests/StreamingKitMacTests-Info.plist new file mode 100644 index 0000000..552d5b1 --- /dev/null +++ b/StreamingKit/StreamingKitMacTests/StreamingKitMacTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + com.abstractpath.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/StreamingKit/StreamingKitMacTests/StreamingKitMacTests.m b/StreamingKit/StreamingKitMacTests/StreamingKitMacTests.m new file mode 100644 index 0000000..f0656ae --- /dev/null +++ b/StreamingKit/StreamingKitMacTests/StreamingKitMacTests.m @@ -0,0 +1,34 @@ +// +// StreamingKitMacTests.m +// StreamingKitMacTests +// +// Created by Thong Nguyen on 02/02/2014. +// Copyright (c) 2014 Thong Nguyen. All rights reserved. +// + +#import + +@interface StreamingKitMacTests : XCTestCase + +@end + +@implementation StreamingKitMacTests + +- (void)setUp +{ + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown +{ + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample +{ + XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); +} + +@end diff --git a/StreamingKit/StreamingKitMacTests/en.lproj/InfoPlist.strings b/StreamingKit/StreamingKitMacTests/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/StreamingKit/StreamingKitMacTests/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ +