Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d9bb98aed | |||
| 31368a54c1 | |||
| d3b563c7cd | |||
| a416cc8e92 | |||
| f36ca68faa | |||
| 2f3c7912e8 | |||
| 548d599628 | |||
| 17f532556a | |||
| 00bd6cd81b |
@@ -1,19 +0,0 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'AudioStreaming'
|
||||
s.version = '1.2.6'
|
||||
s.license = 'MIT'
|
||||
s.summary = 'An AudioPlayer/Streaming library for iOS written in Swift using AVAudioEngine.'
|
||||
s.homepage = 'https://github.com/dimitris-c/AudioStreaming'
|
||||
s.authors = { 'Dimitris C.' => 'dimmdesign@gmail.com' }
|
||||
s.source = { :git => 'https://github.com/dimitris-c/AudioStreaming.git', :tag => s.version }
|
||||
|
||||
s.ios.deployment_target = '13.0'
|
||||
|
||||
s.swift_versions = ['5.1', '5.2', '5.3']
|
||||
|
||||
s.source_files = 'AudioStreaming/**/*.swift'
|
||||
|
||||
s.pod_target_xcconfig = {
|
||||
'SWIFT_INSTALL_OBJC_HEADER' => 'NO'
|
||||
}
|
||||
end
|
||||
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 52;
|
||||
objectVersion = 55;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@@ -54,7 +54,7 @@
|
||||
B59D0B6F255C904900D6CCE5 /* FileAudioSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59D0B6E255C904900D6CCE5 /* FileAudioSource.swift */; };
|
||||
B59DF10424916FD50043C498 /* DispatchQueue+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59DF10324916FD50043C498 /* DispatchQueue+Helpers.swift */; };
|
||||
B59DF1A32493E90C0043C498 /* AudioFileStream+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59DF1A22493E90C0043C498 /* AudioFileStream+Helpers.swift */; };
|
||||
B5AEDBB824744153007D8101 /* AudioStreaming.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5AEDBAE24744153007D8101 /* AudioStreaming.framework */; };
|
||||
B5AEDBB824744153007D8101 /* AudioStreaming.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5AEDBAE24744153007D8101 /* AudioStreaming.framework */; platformFilters = (ios, tvos, ); };
|
||||
B5AEDBBF24744153007D8101 /* AudioStreaming.h in Headers */ = {isa = PBXBuildFile; fileRef = B5AEDBB124744153007D8101 /* AudioStreaming.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B5B36E432655A32200DC96F5 /* FrameFilterProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B36E422655A32200DC96F5 /* FrameFilterProcessor.swift */; };
|
||||
B5B3B7CC248647ED00656828 /* AudioPlayerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B3B7CB248647ED00656828 /* AudioPlayerState.swift */; };
|
||||
@@ -528,8 +528,9 @@
|
||||
B5AEDBA524744153007D8101 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = YES;
|
||||
LastSwiftUpdateCheck = 1140;
|
||||
LastUpgradeCheck = 1200;
|
||||
LastUpgradeCheck = 1620;
|
||||
ORGANIZATIONNAME = Decimal;
|
||||
TargetAttributes = {
|
||||
B5AEDBAD24744153007D8101 = {
|
||||
@@ -587,6 +588,7 @@
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
B583864B2545858E0087A712 /* SwiftLint */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
@@ -683,6 +685,10 @@
|
||||
/* Begin PBXTargetDependency section */
|
||||
B5AEDBBA24744153007D8101 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
platformFilters = (
|
||||
ios,
|
||||
tvos,
|
||||
);
|
||||
target = B5AEDBAD24744153007D8101 /* AudioStreaming */;
|
||||
targetProxy = B5AEDBB924744153007D8101 /* PBXContainerItemProxy */;
|
||||
};
|
||||
@@ -727,6 +733,7 @@
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
@@ -743,7 +750,7 @@
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.2.6;
|
||||
MARKETING_VERSION = 1.2.7;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
@@ -793,6 +800,7 @@
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
@@ -803,7 +811,7 @@
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.2.6;
|
||||
MARKETING_VERSION = 1.2.7;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -819,12 +827,14 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_MODULE_VERIFIER = YES;
|
||||
INFOPLIST_FILE = AudioStreaming/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
@@ -833,17 +843,18 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.6;
|
||||
MARKETING_VERSION = 1.2.7;
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.decimal.AudioStreaming;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
||||
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -851,12 +862,14 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_MODULE_VERIFIER = YES;
|
||||
INFOPLIST_FILE = AudioStreaming/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
@@ -865,23 +878,23 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.6;
|
||||
MARKETING_VERSION = 1.2.7;
|
||||
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++14";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.decimal.AudioStreaming;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
|
||||
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
B5AEDBC624744153007D8101 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
INFOPLIST_FILE = AudioStreamingTests/Info.plist;
|
||||
@@ -893,16 +906,17 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.decimal.AudioStreamingTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B5AEDBC724744153007D8101 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
INFOPLIST_FILE = AudioStreamingTests/Info.plist;
|
||||
@@ -914,8 +928,10 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.decimal.AudioStreamingTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1200"
|
||||
LastUpgradeVersion = "1620"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import AVFoundation
|
||||
|
||||
public enum AudioConverterError: CustomDebugStringConvertible {
|
||||
public enum AudioConverterError: CustomDebugStringConvertible, Sendable {
|
||||
case badPropertySizeError
|
||||
case formatNotSupported
|
||||
case inputSampleRateOutOfRange
|
||||
|
||||
@@ -29,7 +29,7 @@ func fileStreamGetPropertyInfo(fileStream streamId: AudioFileStreamID, propertyI
|
||||
///
|
||||
/// Reference:
|
||||
/// [Audio File Stream Errors](https://developer.apple.com/documentation/audiotoolbox/1391572-audio_file_stream_errors?language=objc)
|
||||
public enum AudioFileStreamError: CustomDebugStringConvertible {
|
||||
public enum AudioFileStreamError: CustomDebugStringConvertible, Sendable {
|
||||
case badPropertySize
|
||||
case dataUnavailable
|
||||
case discontinuityCantRecover
|
||||
|
||||
@@ -37,6 +37,11 @@ class AudioEntry {
|
||||
return seekTime + (Double(framesState.played) / outputAudioFormat.sampleRate)
|
||||
}
|
||||
|
||||
var framesPlayed: Int {
|
||||
lock.lock(); defer { lock.unlock() }
|
||||
return framesState.played
|
||||
}
|
||||
|
||||
var audioStreamFormat = AudioStreamBasicDescription()
|
||||
|
||||
/// Hold the seek time, if a seek was requested
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import AVFoundation
|
||||
|
||||
protocol AudioEntryProviding {
|
||||
func provideAudioEntry(url: URL, httpMethod: String?, httpBody: Data?, headers: [String: String]) -> AudioEntry
|
||||
func provideAudioEntry(url: URL, headers: [String: String]) -> AudioEntry
|
||||
func provideAudioEntry(url: URL) -> AudioEntry
|
||||
}
|
||||
@@ -25,7 +26,14 @@ final class AudioEntryProvider: AudioEntryProviding {
|
||||
}
|
||||
|
||||
func provideAudioEntry(url: URL, headers: [String: String]) -> AudioEntry {
|
||||
let source = self.source(for: url, headers: headers)
|
||||
let source = self.source(for: url, httpMethod: nil, httpBody: nil, headers: headers)
|
||||
return AudioEntry(source: source,
|
||||
entryId: AudioEntryId(id: url.absoluteString),
|
||||
outputAudioFormat: outputAudioFormat)
|
||||
}
|
||||
|
||||
func provideAudioEntry(url: URL, httpMethod: String?, httpBody: Data?, headers: [String: String]) -> AudioEntry {
|
||||
let source = self.source(for: url, httpMethod: httpMethod, httpBody: httpBody, headers: headers)
|
||||
return AudioEntry(source: source,
|
||||
entryId: AudioEntryId(id: url.absoluteString),
|
||||
outputAudioFormat: outputAudioFormat)
|
||||
@@ -34,10 +42,12 @@ final class AudioEntryProvider: AudioEntryProviding {
|
||||
func provideAudioEntry(url: URL) -> AudioEntry {
|
||||
provideAudioEntry(url: url, headers: [:])
|
||||
}
|
||||
|
||||
func provideAudioSource(url: URL, headers: [String: String]) -> AudioStreamSource {
|
||||
|
||||
func provideAudioSource(url: URL, httpMethod: String?, httpBody: Data?, headers: [String: String]) -> AudioStreamSource {
|
||||
RemoteAudioSource(networking: networkingClient,
|
||||
url: url,
|
||||
httpMethod: httpMethod,
|
||||
httpBody: httpBody,
|
||||
underlyingQueue: underlyingQueue,
|
||||
httpHeaders: headers)
|
||||
}
|
||||
@@ -46,10 +56,10 @@ final class AudioEntryProvider: AudioEntryProviding {
|
||||
FileAudioSource(url: url, underlyingQueue: underlyingQueue)
|
||||
}
|
||||
|
||||
func source(for url: URL, headers: [String: String]) -> CoreAudioStreamSource {
|
||||
func source(for url: URL, httpMethod: String?, httpBody: Data?, headers: [String: String]) -> CoreAudioStreamSource {
|
||||
guard !url.isFileURL else {
|
||||
return provideFileAudioSource(url: url)
|
||||
}
|
||||
return provideAudioSource(url: url, headers: headers)
|
||||
return provideAudioSource(url: url, httpMethod: httpMethod, httpBody: httpBody, headers: headers)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ public class RemoteAudioSource: AudioStreamSource {
|
||||
}
|
||||
|
||||
private let url: URL
|
||||
private let httpMethod: String?
|
||||
private let httpBody: Data?
|
||||
private let networkingClient: NetworkingClient
|
||||
private var streamRequest: NetworkDataStream?
|
||||
|
||||
@@ -61,12 +63,16 @@ public class RemoteAudioSource: AudioStreamSource {
|
||||
netStatusProvider: NetStatusProvider,
|
||||
retrier: Retrier,
|
||||
url: URL,
|
||||
httpMethod: String?,
|
||||
httpBody: Data?,
|
||||
underlyingQueue: DispatchQueue,
|
||||
httpHeaders: [String: String])
|
||||
{
|
||||
networkingClient = networking
|
||||
metadataStreamProcessor = metadataStreamSource
|
||||
self.url = url
|
||||
self.httpMethod = httpMethod
|
||||
self.httpBody = httpBody
|
||||
additionalRequestHeaders = httpHeaders
|
||||
relativePosition = 0
|
||||
seekOffset = 0
|
||||
@@ -83,9 +89,11 @@ public class RemoteAudioSource: AudioStreamSource {
|
||||
mp4Restructure = RemoteMp4Restructure(url: url, networking: networkingClient)
|
||||
startNetworkService()
|
||||
}
|
||||
|
||||
|
||||
convenience init(networking: NetworkingClient,
|
||||
url: URL,
|
||||
httpMethod: String?,
|
||||
httpBody: Data?,
|
||||
underlyingQueue: DispatchQueue,
|
||||
httpHeaders: [String: String])
|
||||
{
|
||||
@@ -100,6 +108,21 @@ public class RemoteAudioSource: AudioStreamSource {
|
||||
netStatusProvider: netStatusProvider,
|
||||
retrier: retrierTimeout,
|
||||
url: url,
|
||||
httpMethod: httpMethod,
|
||||
httpBody: httpBody,
|
||||
underlyingQueue: underlyingQueue,
|
||||
httpHeaders: httpHeaders)
|
||||
}
|
||||
|
||||
convenience init(networking: NetworkingClient,
|
||||
url: URL,
|
||||
underlyingQueue: DispatchQueue,
|
||||
httpHeaders: [String: String])
|
||||
{
|
||||
self.init(networking: networking,
|
||||
url: url,
|
||||
httpMethod: nil,
|
||||
httpBody: nil,
|
||||
underlyingQueue: underlyingQueue,
|
||||
httpHeaders: httpHeaders)
|
||||
}
|
||||
@@ -347,6 +370,8 @@ public class RemoteAudioSource: AudioStreamSource {
|
||||
urlRequest.networkServiceType = .avStreaming
|
||||
urlRequest.cachePolicy = .reloadIgnoringLocalCacheData
|
||||
urlRequest.timeoutInterval = 60
|
||||
urlRequest.httpMethod = httpMethod
|
||||
urlRequest.httpBody = httpBody
|
||||
|
||||
for header in additionalRequestHeaders {
|
||||
urlRequest.addValue(header.value, forHTTPHeaderField: header.key)
|
||||
@@ -366,6 +391,8 @@ public class RemoteAudioSource: AudioStreamSource {
|
||||
urlRequest.networkServiceType = .avStreaming
|
||||
urlRequest.cachePolicy = .reloadIgnoringLocalCacheData
|
||||
urlRequest.timeoutInterval = 60
|
||||
urlRequest.httpMethod = httpMethod
|
||||
urlRequest.httpBody = httpBody
|
||||
|
||||
for header in additionalRequestHeaders {
|
||||
urlRequest.addValue(header.value, forHTTPHeaderField: header.key)
|
||||
|
||||
@@ -81,6 +81,16 @@ open class AudioPlayer {
|
||||
return entry.progress
|
||||
}
|
||||
|
||||
/// The number of audio frames that have been played
|
||||
public var framesPlayed: Int {
|
||||
guard playerContext.internalState != .pendingNext else { return 0 }
|
||||
playerContext.entriesLock.lock()
|
||||
let playingEntry = playerContext.audioPlayingEntry
|
||||
playerContext.entriesLock.unlock()
|
||||
guard let entry = playingEntry else { return 0 }
|
||||
return entry.framesPlayed
|
||||
}
|
||||
|
||||
public private(set) var customAttachedNodes = [AVAudioNode]()
|
||||
|
||||
/// The current configuration of the player.
|
||||
@@ -192,6 +202,17 @@ open class AudioPlayer {
|
||||
let audioEntry = entryProvider.provideAudioEntry(url: url, headers: headers)
|
||||
play(audioEntry: audioEntry)
|
||||
}
|
||||
|
||||
/// Starts the audio playback for the given URL
|
||||
///
|
||||
/// - parameter url: A `URL` specifying the audio context to be played.
|
||||
/// - parameter httpMethod: A `String` specifying the HTTP method to use (e.g. "GET", "POST").
|
||||
/// - parameter httpBody: A "Data" specifying the HTTP request body, if any.
|
||||
/// - parameter headers: A `Dictionary` specifying any additional headers to be pass to the network request.
|
||||
public func play(url: URL, httpMethod: String?, httpBody: Data?, headers: [String: String]) {
|
||||
let audioEntry = entryProvider.provideAudioEntry(url: url, httpMethod: httpMethod, httpBody: httpBody, headers: headers)
|
||||
play(audioEntry: audioEntry)
|
||||
}
|
||||
|
||||
/// Starts the audio playback for the supplied stream
|
||||
///
|
||||
|
||||
@@ -55,7 +55,7 @@ func playerStateAndStopReason(
|
||||
|
||||
// MARK: Public States
|
||||
|
||||
public enum AudioPlayerState: Equatable {
|
||||
public enum AudioPlayerState: Equatable, Sendable {
|
||||
case ready
|
||||
case running
|
||||
case playing
|
||||
@@ -66,7 +66,7 @@ public enum AudioPlayerState: Equatable {
|
||||
case disposed
|
||||
}
|
||||
|
||||
public enum AudioPlayerStopReason: Equatable {
|
||||
public enum AudioPlayerStopReason: Equatable, Sendable {
|
||||
case none
|
||||
case eof
|
||||
case userAction
|
||||
@@ -74,7 +74,7 @@ public enum AudioPlayerStopReason: Equatable {
|
||||
case disposed
|
||||
}
|
||||
|
||||
public enum AudioPlayerError: LocalizedError, Equatable {
|
||||
public enum AudioPlayerError: LocalizedError, Equatable, Sendable {
|
||||
case streamParseBytesFailure(AudioFileStreamError)
|
||||
case audioSystemError(AudioSystemError)
|
||||
case codecError
|
||||
@@ -100,7 +100,7 @@ public enum AudioPlayerError: LocalizedError, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public enum AudioSystemError: LocalizedError, Equatable {
|
||||
public enum AudioSystemError: LocalizedError, Equatable, Sendable {
|
||||
case engineFailure
|
||||
case playerNotFound
|
||||
case playerStartError
|
||||
|
||||
@@ -9,7 +9,7 @@ enum UnitDescriptions {
|
||||
static let output: AudioComponentDescription = {
|
||||
var desc = AudioComponentDescription()
|
||||
desc.componentType = kAudioUnitType_Output
|
||||
#if os(iOS)
|
||||
#if os(iOS) || os(tvOS)
|
||||
desc.componentSubType = kAudioUnitSubType_RemoteIO
|
||||
#else
|
||||
desc.componentSubType = kAudioUnitSubType_DefaultOutput
|
||||
|
||||
+2
-1
@@ -6,7 +6,8 @@ let package = Package(
|
||||
name: "AudioStreaming",
|
||||
platforms: [
|
||||
.iOS(.v12),
|
||||
.macOS(.v13)
|
||||
.macOS(.v13),
|
||||
.tvOS(.v16)
|
||||
],
|
||||
products: [
|
||||
.library(
|
||||
|
||||
@@ -18,6 +18,8 @@ Known limitations:
|
||||
|
||||
# Requirements
|
||||
- iOS 13.0+
|
||||
- macOS 13.0+
|
||||
- tvOS 16.0+
|
||||
- Swift 5.x
|
||||
|
||||
# Using AudioStreaming
|
||||
@@ -163,39 +165,11 @@ Under the hood the concrete class for frame filters, `FrameFilterProcessor` inst
|
||||
|
||||
# Installation
|
||||
|
||||
### Cocoapods
|
||||
|
||||
[Cocoapods](https://cocoapods.org/) is a dependency manager for Cocoa projects. You can install it with the following command:
|
||||
```
|
||||
$ gem install cocoapods
|
||||
```
|
||||
|
||||
To intergrate AudioStreaming with [Cocoapods](https://cocoapods.org/) to your Xcode project add the following to your `Podfile`:
|
||||
```
|
||||
pod 'AudioStreaming'
|
||||
```
|
||||
|
||||
### Swift Package Manager
|
||||
|
||||
On Xcode 11.0+ you can add a new dependency by going to **File / Swift Packages / Add Package Dependency...**
|
||||
and enter package repository URL https://github.com/dimitris-c/AudioStreaming.git, then follow the instructions.
|
||||
|
||||
### Carthage
|
||||
|
||||
[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with frameworks.
|
||||
|
||||
You can install Carthage with Homebrew using the following command:
|
||||
```
|
||||
$ brew update
|
||||
$ brew install carthage
|
||||
```
|
||||
|
||||
To integrate AudioStreaming into your Xcode project using Carthage, add the following to your `Cartfile`:
|
||||
```
|
||||
github "dimitris-c/AudioStreaming"
|
||||
```
|
||||
Visit [installation instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) on Carthage to install the framework
|
||||
|
||||
# Licence
|
||||
|
||||
AudioStreaming is available under the MIT license. See the LICENSE file for more info.
|
||||
|
||||
Reference in New Issue
Block a user