### Start Live Transcription Stream Source: https://context7.com/saik0s/whisperboard/llms.txt Initiates a live transcription stream using a loaded Whisper model. It continuously processes audio, providing updates on confirmed and unconfirmed text segments, voice activity detection, and transcription progress. Ensure a model is loaded before starting. ```swift import AudioProcessing import Foundation @Dependency(RecordingTranscriptionStream.self) var transcriptionStream // Load a fast model suitable for live transcription try await transcriptionStream.loadModel("tiny.en") { progress in print("Loading model: \(Int(progress * 100))%") } // Start live transcription loop for try await state in await transcriptionStream.startLiveTranscription() { // State contains both confirmed and unconfirmed segments print("Confirmed segments: \(state.confirmedSegments.count)") print("Unconfirmed segments: \(state.unconfirmedSegments.count)") print("Current text: \(state.currentText)") print("Tokens/sec: \(state.tokensPerSecond)") // Combine all segments for full transcription let allText = state.segments.map(\.text).joined(separator: " ") print("Full transcription: \(allText)") // Check if voice activity is detected print("Working: \(state.isWorking)") print("Progress: \(state.transcriptionProgressFraction)") } ``` -------------------------------- ### Fetch and Manage Whisper Models Source: https://context7.com/saik0s/whisperboard/llms.txt Fetches available Whisper models, displays their status (local, default, disabled), and provides functionality to download, load, delete, and manage models. Use `recommendedModels()` to get models suitable for the current device. Progress tracking is available during model loading. ```swift import AudioProcessing import WhisperKit import Foundation @Dependency(RecordingTranscriptionStream.self) var transcriptionStream // Fetch available models from remote repository and local storage let models = try await transcriptionStream.fetchModels() // Models contain information about availability and status for model in models { print("Name: \(model.name)") print("Is Local: \(model.isLocal)") print("Is Default: \(model.isDefault)") print("Is Disabled: \(model.isDisabled)") } // Get recommended models for the device let (defaultModel, disabledModels) = transcriptionStream.recommendedModels() print("Recommended: \(defaultModel)") print("Disabled for this device: \(disabledModels)") // Download and load a specific model with progress tracking try await transcriptionStream.loadModel("small.en") { progress in // Progress goes through stages: downloading, prewarming, loading print("Loading progress: \(Int(progress * 100))%") } // Delete a specific model to free up space try await transcriptionStream.deleteModel("small.en") // Delete all downloaded models try await transcriptionStream.deleteAllModels() // Model storage location let modelDirectory = TranscriptionStream.modelDirURL // ~/Documents/huggingface/models/argmaxinc/whisperkit-coreml/ ``` -------------------------------- ### Manage Recording Information and Transcription Source: https://context7.com/saik0s/whisperboard/llms.txt Demonstrates creating a RecordingInfo instance, accessing computed properties, and attaching a Transcription object to manage status. ```swift import Common import Foundation // Create a new recording info var recording = RecordingInfo( fileName: "meeting_notes.wav", title: "Team Meeting", date: Date(), duration: 300.0 // 5 minutes ) // Access computed properties print("ID: \(recording.id)") // Same as fileName print("File URL: \(recording.fileURL)") print("Waveform URL: \(recording.waveformImageURL)") print("Is Transcribed: \(recording.isTranscribed)") print("Is Transcribing: \(recording.isTranscribing)") print("Text: \(recording.text)") // Add transcription to recording let transcription = Transcription( id: UUID(), fileName: recording.fileName, startDate: Date(), segments: [ Segment( startTimeMS: 0, endTimeMS: 5000, text: "Hello, welcome to the meeting.", tokens: [Token(id: 1, index: 0, logProbability: -0.5)], words: [ WordData(word: "Hello", startTimeMS: 0, endTimeMS: 500, probability: 0.95), WordData(word: "welcome", startTimeMS: 600, endTimeMS: 1000, probability: 0.92) ] ) ], parameters: TranscriptionParameters(language: "en"), model: "base.en", status: .done(Date()), text: "Hello, welcome to the meeting." ) recording.transcription = transcription // Check transcription status switch recording.transcription?.status { case .notStarted: print("Not started") case .loading: print("Loading model...") case .progress(let progress, let text): print("Progress: \(progress * 100)% - \(text)") case .done(let date): print("Completed at \(date)") case .error(let message): print("Error: \(message)") case .paused(let task, let progress): print("Paused at \(progress * 100)%") case .canceled: print("Canceled") case .uploading(let progress): print("Uploading: \(progress * 100)%") case .none: print("No transcription") } ``` -------------------------------- ### Manage Storage and iCloud Synchronization Source: https://context7.com/saik0s/whisperboard/llms.txt Utilizes the StorageClient to sync recordings, monitor disk space, perform iCloud uploads, and handle file cleanup. ```swift import Common import ComposableArchitecture import Foundation @Dependency(StorageClient.self) var storage // Sync recordings with local storage @Shared(.recordings) var recordings: IdentifiedArrayOf let syncedRecordings = try await storage.sync(recordings: recordings.elements) // Check disk space let freeSpace = storage.freeSpace() let totalSpace = storage.totalSpace() let usedSpace = storage.takenSpace() print("Free: \(freeSpace / 1_000_000_000) GB") print("Total: \(totalSpace / 1_000_000_000) GB") print("Used by app: \(usedSpace / 1_000_000) MB") // Upload recordings to iCloud // reset: true clears upload history and re-uploads all files try await storage.uploadRecordingsToICloud(reset: false, recordings: recordings.elements) // Delete all recordings and storage try await storage.deleteStorage() // Set current recording URL (for crash recovery) let currentRecordingURL = URL.documentsDirectory.appending(path: "current.wav") storage.setCurrentRecordingURL(url: currentRecordingURL) ``` -------------------------------- ### Configure Transcription and Decoding Parameters Source: https://context7.com/saik0s/whisperboard/llms.txt Defines transcription settings and decoding options for the WhisperKit framework. Use these structures to control language detection, translation tasks, and model inference behavior. ```swift import Common import WhisperKit // Create transcription parameters let parameters = TranscriptionParameters( // Optional prompt to guide transcription style/vocabulary initialPrompt: "Technical meeting about software development.", // Language code (nil for auto-detection) language: "en", // or "es", "fr", "de", etc. // Start transcription from this offset offsetMilliseconds: 0, // Translate to English (for non-English audio) shouldTranslate: false ) // Use with DecodingOptions in TranscriptionStream // The stream internally creates DecodingOptions like: let options = DecodingOptions( verbose: false, task: .transcribe, // or .translate language: Constants.languages[selectedLanguage, default: "en"], temperature: 0.0, temperatureFallbackCount: 5, sampleLength: 224, usePrefillPrompt: true, usePrefillCache: true, skipSpecialTokens: true, withoutTimestamps: false, wordTimestamps: true ) ``` -------------------------------- ### Control Audio Playback Source: https://context7.com/saik0s/whisperboard/llms.txt Manages audio playback from a given URL, emitting playback state updates including current position, duration, and errors. Supports play, pause, resume, stop, seeking to a specific progress point, and adjusting playback speed. Ensure the audio file exists at the provided URL. ```swift import AVFoundation import Dependencies import Foundation @Dependency(\.audioPlayer) var audioPlayer // Play an audio file and receive state updates let audioURL = URL.documentsDirectory.appending(path: "recording.wav") for await state in audioPlayer.play(audioURL) { switch state { case .playing(let position): print("Playing: \(position.currentTime)/\(position.duration)") print("Progress: \(position.progress * 100)%") case .pause(let position): print("Paused at: \(position.currentTime)") case .stop: print("Playback stopped") case .finish(let successful): print("Finished playing: \(successful ? "success" : "failure")") case .error(let error): print("Playback error: \(error?.localizedDescription ?? "unknown")") } } // Control playback await audioPlayer.pause() await audioPlayer.resume() await audioPlayer.stop() // Seek to specific position (0.0 to 1.0) await audioPlayer.seekProgress(0.5) // Seek to middle // Adjust playback speed await audioPlayer.speed(1.5) // 1.5x speed await audioPlayer.speed(0.75) // 0.75x speed ``` -------------------------------- ### Transcribe Audio Files with WhisperKit Source: https://context7.com/saik0s/whisperboard/llms.txt Utilize the TranscriptionStream actor to load Whisper models and process audio files. Progress callbacks allow for monitoring and cancellation during the transcription pipeline. ```swift import AudioProcessing import WhisperKit import Foundation @Dependency(RecordingTranscriptionStream.self) var transcriptionStream // First, ensure a model is loaded try await transcriptionStream.loadModel("base.en") { progress in print("Model loading: \(Int(progress * 100))%") } // Transcribe an audio file with progress tracking let audioFileURL = URL.documentsDirectory.appending(path: "recording.wav") let result = try await transcriptionStream.transcribeAudioFile(audioFileURL) { progress, fraction in // progress: TranscriptionProgress contains current text and timings // fraction: Double represents overall progress (0.0 to 1.0) print("Progress: \(Int(fraction * 100))%") print("Current text: \(progress.text)") // Return true to continue, false to cancel, nil for default behavior return true } // Access transcription results print("Full text: \(result.text)") print("Tokens per second: \(result.timings.tokensPerSecond)") print("Total time: \(result.timings.fullPipeline) seconds") // Access individual segments with timestamps for segment in result.segments { let startTime = Float(segment.start) let endTime = Float(segment.end) print("[\(startTime)s - \(endTime)s]: \(segment.text)") } ``` -------------------------------- ### Manage Audio Recording Sessions Source: https://context7.com/saik0s/whisperboard/llms.txt Use the RecordingStream actor to handle microphone input, file writing, and state monitoring. The stream provides real-time updates on duration and energy levels for waveform rendering. ```swift import AudioProcessing import Foundation // Access the recording transcription stream via dependency injection @Dependency(RecordingTranscriptionStream.self) var transcriptionStream // Start recording to a specific file URL let fileURL = URL.documentsDirectory.appending(path: "recording_\(UUID().uuidString).wav") // Start recording and receive state updates for try await state in await transcriptionStream.startRecording(fileURL) { // Access recording state properties print("Recording: \(state.isRecording)") print("Paused: \(state.isPaused)") print("Duration: \(state.duration) seconds") print("Wave samples: \(state.waveSamples.count)") // state.waveSamples contains energy levels for waveform visualization if state.duration > 60 { // Stop after 60 seconds await transcriptionStream.stopRecording() } } // Pause and resume recording await transcriptionStream.pauseRecording() // ... some time later await transcriptionStream.resumeRecording() // Stop recording when finished await transcriptionStream.stopRecording() ``` -------------------------------- ### Configure App Settings with TCA Shared State Source: https://context7.com/saik0s/whisperboard/llms.txt Configure transcription behavior, model selection, and app features through the Settings structure. Settings are persisted and shared across the app using TCA's Shared state. ```swift import Common import ComposableArchitecture // Access settings through shared state @Shared(.settings) var settings: Settings // Configure settings settings = Settings( useMockedClients: false, selectedModelName: "base.en", parameters: TranscriptionParameters( initialPrompt: nil, language: "en", offsetMilliseconds: 0, shouldTranslate: false ), isICloudSyncEnabled: true, shouldMixWithOtherAudio: false, isUsingGPU: false, isUsingNeuralEngine: true, // Recommended for better performance isVADEnabled: true, // Voice Activity Detection isLiveTranscriptionEnabled: false ) // Access individual settings print("Selected model: \(settings.selectedModelName)") print("Voice language: \(settings.voiceLanguage ?? "auto")") print("iCloud sync: \(settings.isICloudSyncEnabled)") print("Neural Engine: \(settings.isUsingNeuralEngine)") // Transcription parameters for fine-tuning let params = settings.parameters print("Initial prompt: \(params.initialPrompt ?? "none")") print("Language: \(params.language ?? "auto-detect")") print("Offset: \(params.offsetMilliseconds)ms") print("Translate: \(params.shouldTranslate)") ``` -------------------------------- ### Integrate TranscriptionWorker with TCA Source: https://context7.com/saik0s/whisperboard/llms.txt Use the TranscriptionWorker within a TCA feature to manage transcription tasks. Enqueue tasks using `enqueueTaskForRecordingID` and cancel them with `cancelTaskForRecordingID`. Handle transcription updates via the `transcriptionDidUpdate` action. ```swift import ComposableArchitecture import Common // Using TranscriptionWorker within TCA @Reducer struct MyFeature { struct State { var transcriptionWorker = TranscriptionWorker.State() @Shared(.recordings) var recordings: IdentifiedArrayOf @Shared(.settings) var settings: Settings } enum Action { case transcriptionWorker(TranscriptionWorker.Action) case transcribeRecording(RecordingInfo.ID) case cancelTranscription(RecordingInfo.ID) } var body: some ReducerOf { Scope(state: \.transcriptionWorker, action: \.transcriptionWorker) { TranscriptionWorker() } Reduce { state, action in switch action { case let .transcribeRecording(recordingID): // Enqueue a transcription task return .send(.transcriptionWorker(.enqueueTaskForRecordingID(recordingID, state.settings))) case let .cancelTranscription(recordingID): // Cancel a pending or in-progress transcription return .send(.transcriptionWorker(.cancelTaskForRecordingID(recordingID))) case .transcriptionWorker(.transcriptionDidUpdate(let transcription, task: let task)): // Handle transcription updates if let index = state.recordings.firstIndex(where: { $0.id == task.recordingInfoID }) { state.recordings[index].transcription = transcription } return .none default: return .none } } } } // Check worker state let isProcessing = state.transcriptionWorker.isProcessing let currentTask = state.transcriptionWorker.currentTask let taskQueue = state.transcriptionWorker.taskQueue ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.