Add voice notes: on-device transcription, multi-language, watch capture
- Schema v2: Note.AudioInfo, .m4a sidecar next to the note JSON in iCloud - AudioRecorderService (iOS/macOS) + SpeechAnalyzer transcription pipeline with enabled-language set and confidence-based auto-pick, re-transcribe menu - Settings > Transcription > Languages with asset download/reserve handling - watchOS app + accessory complication: one-button recorder, WCSession transferFile to phone, WatchInbox staging, direct-upsert ingestion - Player UI, transcription status chips, quick-capture mic in notes list - Version 0.2, changelog + README updated
This commit is contained in:
@@ -11,6 +11,9 @@ final class AppServices {
|
||||
let syncEngine: SyncEngine
|
||||
let contextService: ContextService
|
||||
let backupController: BackupController
|
||||
let audioRecorder: AudioRecorderService
|
||||
let transcriptionSettings: TranscriptionSettings
|
||||
let transcriptionService: TranscriptionService
|
||||
|
||||
init() async {
|
||||
let container = NotesModelContainer.make()
|
||||
@@ -21,6 +24,20 @@ final class AppServices {
|
||||
self.backupController = BackupController(
|
||||
configuration: NotesBackupConfiguration(syncEngine: engine)
|
||||
)
|
||||
self.audioRecorder = AudioRecorderService()
|
||||
let settings = TranscriptionSettings()
|
||||
self.transcriptionSettings = settings
|
||||
let transcription = TranscriptionService(
|
||||
syncEngine: engine,
|
||||
settings: settings,
|
||||
modelContainer: container
|
||||
)
|
||||
self.transcriptionService = transcription
|
||||
|
||||
// A watch recording, once ingested, is this device's to transcribe.
|
||||
engine.onAudioNoteIngested = { [weak transcription] id in
|
||||
transcription?.enqueue(noteID: id)
|
||||
}
|
||||
}
|
||||
|
||||
/// The file extension this app owns for backup documents. Used to route
|
||||
@@ -30,5 +47,12 @@ final class AppServices {
|
||||
/// Slow startup work (iCloud container discovery) — runs after the UI is up.
|
||||
func startDeferredServices() async {
|
||||
await syncEngine.connect()
|
||||
// Drain any watch recordings delivered while the app was closed — the
|
||||
// container is connected now, so they can be written and ingested.
|
||||
await syncEngine.ingestStagedWatchRecordings()
|
||||
// Load the supported languages / reservation cap, then pick up any of
|
||||
// this device's notes that were still pending when it last quit.
|
||||
await transcriptionSettings.prepare()
|
||||
transcriptionService.resumePendingWork()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user