Skip to content

Instantly share code, notes, and snippets.

@JadenGeller
Last active October 21, 2024 18:56
Show Gist options
  • Save JadenGeller/11ad477bc26a2489ebe419ec039f5738 to your computer and use it in GitHub Desktop.
Save JadenGeller/11ad477bc26a2489ebe419ec039f5738 to your computer and use it in GitHub Desktop.
import AVFoundation
actor AudioRecorder {
private let audioEngine = AVAudioEngine()
#if os(iOS)
private let audioSession = AVAudioSession.sharedInstance()
#endif
static func authorize() async -> Bool {
await withCheckedContinuation { continuation in
AVCaptureDevice.requestAccess(for: .audio) { granted in
continuation.resume(returning: granted)
}
}
}
func stream() async throws -> AsyncStream<AVAudioPCMBuffer> {
#if os(iOS)
try await audioSession.setCategory(.record, mode: .measurement, options: .duckOthers)
try await audioSession.setActive(true, options: .notifyOthersOnDeactivation)
#endif
let inputNode = audioEngine.inputNode
let recordingFormat = inputNode.outputFormat(forBus: 0)
let audioStream = AsyncStream<AVAudioPCMBuffer> { continuation in
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
continuation.yield(buffer)
}
continuation.onTermination = { termination in
Task {
await self.terminate()
}
}
}
audioEngine.prepare()
try audioEngine.start()
return audioStream
}
private func terminate() {
audioEngine.stop()
audioEngine.inputNode.removeTap(onBus: 0)
}
}
@JadenGeller
Copy link
Author

Don't forget to add Audio Input capability and NSMicrophoneUsageDescription!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment