101 lines
3.3 KiB
Swift
101 lines
3.3 KiB
Swift
import Foundation
|
|
import FluidAudio
|
|
import AppKit
|
|
|
|
extension WhisperState {
|
|
private func parakeetDefaultsKey(for modelName: String) -> String {
|
|
"ParakeetModelDownloaded_\(modelName)"
|
|
}
|
|
|
|
private func parakeetVersion(for modelName: String) -> AsrModelVersion {
|
|
modelName.lowercased().contains("v2") ? .v2 : .v3
|
|
}
|
|
|
|
private func parakeetCacheDirectory(for version: AsrModelVersion) -> URL {
|
|
AsrModels.defaultCacheDirectory(for: version)
|
|
}
|
|
|
|
func isParakeetModelDownloaded(named modelName: String) -> Bool {
|
|
UserDefaults.standard.bool(forKey: parakeetDefaultsKey(for: modelName))
|
|
}
|
|
|
|
func isParakeetModelDownloaded(_ model: ParakeetModel) -> Bool {
|
|
isParakeetModelDownloaded(named: model.name)
|
|
}
|
|
|
|
func isParakeetModelDownloading(_ model: ParakeetModel) -> Bool {
|
|
parakeetDownloadStates[model.name] ?? false
|
|
}
|
|
|
|
@MainActor
|
|
func downloadParakeetModel(_ model: ParakeetModel) async {
|
|
if isParakeetModelDownloaded(model) {
|
|
return
|
|
}
|
|
|
|
let modelName = model.name
|
|
parakeetDownloadStates[modelName] = true
|
|
downloadProgress[modelName] = 0.0
|
|
|
|
let timer = Timer.scheduledTimer(withTimeInterval: 1.2, repeats: true) { timer in
|
|
Task { @MainActor in
|
|
if let currentProgress = self.downloadProgress[modelName], currentProgress < 0.9 {
|
|
self.downloadProgress[modelName] = currentProgress + 0.005
|
|
}
|
|
}
|
|
}
|
|
|
|
let version = parakeetVersion(for: modelName)
|
|
|
|
do {
|
|
_ = try await AsrModels.downloadAndLoad(version: version)
|
|
|
|
_ = try await VadManager()
|
|
|
|
UserDefaults.standard.set(true, forKey: parakeetDefaultsKey(for: modelName))
|
|
downloadProgress[modelName] = 1.0
|
|
} catch {
|
|
UserDefaults.standard.set(false, forKey: parakeetDefaultsKey(for: modelName))
|
|
}
|
|
|
|
timer.invalidate()
|
|
parakeetDownloadStates[modelName] = false
|
|
downloadProgress[modelName] = nil
|
|
|
|
refreshAllAvailableModels()
|
|
}
|
|
|
|
@MainActor
|
|
func deleteParakeetModel(_ model: ParakeetModel) {
|
|
if let currentModel = currentTranscriptionModel,
|
|
currentModel.provider == .parakeet,
|
|
currentModel.name == model.name {
|
|
currentTranscriptionModel = nil
|
|
UserDefaults.standard.removeObject(forKey: "CurrentTranscriptionModel")
|
|
}
|
|
|
|
let version = parakeetVersion(for: model.name)
|
|
let cacheDirectory = parakeetCacheDirectory(for: version)
|
|
|
|
do {
|
|
if FileManager.default.fileExists(atPath: cacheDirectory.path) {
|
|
try FileManager.default.removeItem(at: cacheDirectory)
|
|
}
|
|
UserDefaults.standard.set(false, forKey: parakeetDefaultsKey(for: model.name))
|
|
} catch {
|
|
// Silently ignore removal errors
|
|
}
|
|
|
|
refreshAllAvailableModels()
|
|
}
|
|
|
|
@MainActor
|
|
func showParakeetModelInFinder(_ model: ParakeetModel) {
|
|
let cacheDirectory = parakeetCacheDirectory(for: parakeetVersion(for: model.name))
|
|
|
|
if FileManager.default.fileExists(atPath: cacheDirectory.path) {
|
|
NSWorkspace.shared.selectFile(cacheDirectory.path, inFileViewerRootedAtPath: "")
|
|
}
|
|
}
|
|
}
|