Simple audio player for sync / async chunked audio streams.
You can add swift-chunked-audio-player
to an Xcode project by adding it to your project as a package.
If you want to use swift-chunked-audio-player
in a SwiftPM project, it's as
simple as adding it to your Package.swift
:
dependencies: [
.package(url: "https://github.com/mihai8804858/swift-chunked-audio-player", from: "1.0.0")
]
And then adding the product to any target that needs access to the library:
.product(name: "ChunkedAudioPlayer", package: "swift-chunked-audio-player"),
ChunkedAudioPlayer
uses the following approach to stream real time audio:
- Parse
AudioStreamBasicDescription
and split data chunks into audio packets usingAudioFileStreamOpen(_)
andAudioFileStreamParseBytes(_)
- Convert audio packets into
CMSampleBuffer
- Enqueue and play the sample buffers using
AVSampleBufferAudioRenderer
andAVSampleBufferRenderSynchronizer
- Create an instance of
AudioPlayer
:
private let player = AudioPlayer()
- Get the audio data stream (can be either
AsyncThrowableStream
orAnyPublisher
):
let stream = AsyncThrowableStream<Data, Error> = ...
- Start playing the audio stream:
// type parameter is optional, but recommended (if the stream type is known)
player.start(stream, type: kAudioFileMP3Type)
- Listen for changes:
player.$state.sink { state in
// handle player state
}.store(in: &bag)
player.$rate.sink { rate in
// handle player rate
}.store(in: &bag)
player.$currentTime.sink { time in
// handle player time
}.store(in: &bag)
player.$error.sink { error in
if let error {
// handle player error
}
}.store(in: &bag)
- Control playback:
// Pause current stream
player.pause()
// Resume current stream
player.resume()
// Stop current stream
player.stop()
- SwiftUI Support
AudioPlayer
conforms to ObservableObject
so it can be easily integrated into SwiftUI View
and automatically update the UI when properties change:
struct ContentView: View {
@ObservedObject private var player = AudioPlayer()
var body: some View {
Text("State \(player.state)")
Text("Rate \(player.rate)")
Text("Time \(player.currentTime)")
if let error = player.error {
Text("Error \(error)")
}
}
}
This library is released under the MIT license. See LICENSE for details.