47 lines
1.5 KiB
Swift
47 lines
1.5 KiB
Swift
import AVFoundation
|
|
|
|
/// gates mic capture on AVCaptureDevice audio permission and exposes start/stop to the iced viewport.
|
|
class CaptureController {
|
|
|
|
private let session = CaptureSession()
|
|
weak var view: IcedViewportView?
|
|
|
|
/// true while AVAudioEngine is running through CaptureSession.
|
|
var isCapturing: Bool { session.isCapturing }
|
|
|
|
/// requests AVCaptureDevice audio permission if missing; starts the mic session on grant or when already granted.
|
|
func start() {
|
|
switch AVCaptureDevice.authorizationStatus(for: .audio) {
|
|
case .authorized:
|
|
startSession()
|
|
case .notDetermined:
|
|
AVCaptureDevice.requestAccess(for: .audio) { [weak self] granted in
|
|
DispatchQueue.main.async {
|
|
if granted { self?.startSession() }
|
|
else { print("[YrXtals] mic permission denied") }
|
|
}
|
|
}
|
|
case .denied, .restricted:
|
|
print("[YrXtals] mic permission previously denied")
|
|
@unknown default:
|
|
print("[YrXtals] mic permission status unknown")
|
|
}
|
|
}
|
|
|
|
/// stops the mic session.
|
|
func stop() {
|
|
session.stop()
|
|
}
|
|
|
|
private func startSession() {
|
|
session.viewportHandleProvider = { [weak view = self.view] in
|
|
view?.viewportHandle
|
|
}
|
|
do {
|
|
try session.start()
|
|
} catch {
|
|
print("[YrXtals] CaptureSession start failed: \(error)")
|
|
}
|
|
}
|
|
}
|