Record failure notifications
This commit is contained in:
parent
ac8174b258
commit
eb04104bcb
@ -26,6 +26,9 @@ class AudioEngineRecorder: ObservableObject {
|
|||||||
private let audioProcessingQueue = DispatchQueue(label: "com.prakashjoshipax.VoiceInk.audioProcessing", qos: .userInitiated)
|
private let audioProcessingQueue = DispatchQueue(label: "com.prakashjoshipax.VoiceInk.audioProcessing", qos: .userInitiated)
|
||||||
private let fileWriteLock = NSLock()
|
private let fileWriteLock = NSLock()
|
||||||
|
|
||||||
|
// Callback to notify parent class of runtime recording errors
|
||||||
|
var onRecordingError: ((Error) -> Void)?
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
setupNotifications()
|
setupNotifications()
|
||||||
}
|
}
|
||||||
@ -225,6 +228,9 @@ class AudioEngineRecorder: ObservableObject {
|
|||||||
|
|
||||||
guard let convertedBuffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: outputCapacity) else {
|
guard let convertedBuffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: outputCapacity) else {
|
||||||
logger.error("Failed to create converted buffer")
|
logger.error("Failed to create converted buffer")
|
||||||
|
Task { @MainActor in
|
||||||
|
self.onRecordingError?(AudioEngineRecorderError.bufferConversionFailed)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,6 +250,9 @@ class AudioEngineRecorder: ObservableObject {
|
|||||||
|
|
||||||
if let error = error {
|
if let error = error {
|
||||||
logger.error("Audio conversion error: \(error.localizedDescription)")
|
logger.error("Audio conversion error: \(error.localizedDescription)")
|
||||||
|
Task { @MainActor in
|
||||||
|
self.onRecordingError?(AudioEngineRecorderError.audioConversionError(error))
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,6 +260,9 @@ class AudioEngineRecorder: ObservableObject {
|
|||||||
try audioFile.write(from: convertedBuffer)
|
try audioFile.write(from: convertedBuffer)
|
||||||
} catch {
|
} catch {
|
||||||
logger.error("Failed to write buffer to file: \(error.localizedDescription)")
|
logger.error("Failed to write buffer to file: \(error.localizedDescription)")
|
||||||
|
Task { @MainActor in
|
||||||
|
self.onRecordingError?(AudioEngineRecorderError.fileWriteFailed(error))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +321,9 @@ enum AudioEngineRecorderError: LocalizedError {
|
|||||||
case failedToCreateFile(Error)
|
case failedToCreateFile(Error)
|
||||||
case failedToCreateConverter
|
case failedToCreateConverter
|
||||||
case failedToStartEngine(Error)
|
case failedToStartEngine(Error)
|
||||||
|
case bufferConversionFailed
|
||||||
|
case audioConversionError(Error)
|
||||||
|
case fileWriteFailed(Error)
|
||||||
|
|
||||||
var errorDescription: String? {
|
var errorDescription: String? {
|
||||||
switch self {
|
switch self {
|
||||||
@ -322,6 +337,12 @@ enum AudioEngineRecorderError: LocalizedError {
|
|||||||
return "Failed to create audio format converter"
|
return "Failed to create audio format converter"
|
||||||
case .failedToStartEngine(let error):
|
case .failedToStartEngine(let error):
|
||||||
return "Failed to start audio engine: \(error.localizedDescription)"
|
return "Failed to start audio engine: \(error.localizedDescription)"
|
||||||
|
case .bufferConversionFailed:
|
||||||
|
return "Failed to create buffer for audio conversion"
|
||||||
|
case .audioConversionError(let error):
|
||||||
|
return "Audio format conversion failed: \(error.localizedDescription)"
|
||||||
|
case .fileWriteFailed(let error):
|
||||||
|
return "Failed to write audio data to file: \(error.localizedDescription)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,6 +90,13 @@ class Recorder: NSObject, ObservableObject {
|
|||||||
let engineRecorder = AudioEngineRecorder()
|
let engineRecorder = AudioEngineRecorder()
|
||||||
recorder = engineRecorder
|
recorder = engineRecorder
|
||||||
|
|
||||||
|
// Set up error callback to handle runtime recording failures
|
||||||
|
engineRecorder.onRecordingError = { [weak self] error in
|
||||||
|
Task { @MainActor in
|
||||||
|
await self?.handleRecordingError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try engineRecorder.startRecording(toOutputFile: url)
|
try engineRecorder.startRecording(toOutputFile: url)
|
||||||
|
|
||||||
logger.info("✅ AudioEngineRecorder started successfully")
|
logger.info("✅ AudioEngineRecorder started successfully")
|
||||||
@ -153,6 +160,21 @@ class Recorder: NSObject, ObservableObject {
|
|||||||
deviceManager.isRecordingActive = false
|
deviceManager.isRecordingActive = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func handleRecordingError(_ error: Error) async {
|
||||||
|
logger.error("❌ Recording error occurred: \(error.localizedDescription)")
|
||||||
|
|
||||||
|
// Stop the recording
|
||||||
|
stopRecording()
|
||||||
|
|
||||||
|
// Notify the user about the recording failure
|
||||||
|
await MainActor.run {
|
||||||
|
NotificationManager.shared.showNotification(
|
||||||
|
title: "Recording Failed: \(error.localizedDescription)",
|
||||||
|
type: .error
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func updateAudioMeter() {
|
private func updateAudioMeter() {
|
||||||
guard let recorder = recorder else { return }
|
guard let recorder = recorder else { return }
|
||||||
|
|
||||||
|
|||||||
@ -224,7 +224,7 @@ struct MenuBarView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
|
|
||||||
Button("Quit VoiceInk") {
|
Button("Quit VoiceInk") {
|
||||||
NSApplication.shared.terminate(nil)
|
NSApplication.shared.terminate(nil)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user