☰
10行 SwiftUI 代码做出听写界面:speech-swift SpeechUI 组件完全指南
2026/10/14 18:03:25 网站建设 项目流程

【免费下载链接】speech-swift

AI speech toolkit for Apple Silicon — ASR, TTS, speech-to-speech, VAD, and diarization powered by MLX and CoreML

项目地址:https://gitcode.com/gh_mirrors/sp/speech-swift
点击查看免费下载

🎤 在 macOS / iOS 应用中做实时语音听写,最难的不是识别模型,而是"边听边滚、区分已确认文字与临时识别文字"的界面逻辑。开源项目 speech-swift(面向 Apple Silicon 的本地语音 AI 工具箱,基于 MLX 与 CoreML)内置了一个极轻量的 SwiftUI 组件库 SpeechUI,只需 10 行左右代码,就能搭出一个专业级实时听写界面。

SpeechUI 是什么:语音转写界面的"即插即用"层

speech-swift 把每个模型都做成独立的 Swift Package 模块(ASR、TTS、VAD、说话人分离等),而 SpeechUI 是其中专门负责"界面展示"的模块。

它的设计哲学是与后端解耦:SpeechUI 不关心你用的是 Parakeet、Whisper 还是 Qwen3-ASR,只接收两样东西——

  • finals:已确认的完整句子(一行一句)
  • currentPartial:正在识别中的临时文字(斜体、灰色显示)

这正是流式语音识别(streaming ASR)的标准输出形态:模型一边说话一边输出 partial 结果,停顿后提交 final 结果。TranscriptionView.swift 里内置了自动滚动到底部、文字可选中复制、空状态占位符等细节,全部开箱即用。

两个核心组件:TranscriptionStore + TranscriptionView

SpeechUI 只导出两个类型(源码见 TranscriptionView.swift):

1️⃣TranscriptionStore—— 可观察的状态容器

一个@Observable+@MainActor类,维护finalLines(已确认行数组)和currentPartial(当前临时行)。核心入口只有一个方法:

store.apply(text: partial.text, isFinal: partial.isFinal)
  • 传入isFinal: false→ 更新临时行,不动已确认行
  • 传入isFinal: true→ 该行进入finalLines,临时行清空

它还帮你处理了边界情况:自动去除首尾空白、忽略空 final、reset()一键清空。这些行为都有单元测试覆盖,见 SpeechUITests.swift。

2️⃣TranscriptionView—— 滚动转写视图

TranscriptionView( finals: store.finalLines, currentPartial: store.currentPartial )

一个ScrollView + LazyVStack滚动列表:已确认句子用正常样式且支持选中复制,临时识别文字用次要颜色 + 斜体区分,每次内容变化都会带 0.2 秒缓出动画滚到底部。支持placeholder(默认 "Listening…")和autoScroll参数。

10 行 SwiftUI 代码完成一个听写界面

把模型输出"喂"给 store 就行。下面是 README.md 中的完整示例,识别部分用的是 Parakeet 流式 ASR:

import SwiftUI import ParakeetStreamingASR import SpeechUI @MainActor struct DictateView: View { @State private var store = TranscriptionStore() var body: some View { TranscriptionView(finals: store.finalLines, currentPartial: store.currentPartial) .task { let model = try? await ParakeetStreamingASRModel.fromPretrained() guard let model else { return } for await p in model.transcribeStream(audio: samples, sampleRate: 16000) { store.apply(text: p.text, isFinal: p.isFinal) } } } }

✅ 关键点:transcribeStream是一个异步序列,每产出一条 partial 就调用一次store.apply,界面自动刷新。换后端模型?只要它输出(text, isFinal)二元组,其余代码一行不用改。这个"接线方式"还有一条端到端测试用真实模型验证过:E2ESpeechUIWiringTests.swift。

添加 SpeechUI 依赖:SPM 安装步骤

在项目的Package.swift中追加产品依赖即可(产品清单见 Package.swift 与 README.md):

.product(name: "SpeechUI", package: "speech-swift"), // 可选的 SwiftUI 视图 .product(name: "ParakeetStreamingASR", package: "speech-swift") // 你选择的 ASR 后端

speech-swift 的每个模型都是独立 SPM 库,按需引入、不引入不占用编译时间——这也是新手最容易踩的坑:只加 SpeechUI 而忘了加 ASR 模块。

官方示例 DictateDemo:菜单栏听写应用实战

想看"生产级"用法,直接看 Examples/DictateDemo——一个 macOS 菜单栏听写 App,实测 18 倍实时速度(RTF 0.056):

文件作用
DictateDemoApp.swiftMenuBarExtra菜单 + 浮动 HUD 窗口入口
DictateViewModel.swift模型加载、麦克风采集、后台队列处理 ASR 的完整状态管理
DictateHUDView.swift带音量指示与自动滚动的浮动转写面板
DictateMenuView.swift菜单栏弹层中的听写控制界面

它的亮点实践值得借鉴:

  • 后台处理、主线程只更新 UI:音频块先进缓冲队列,由userInteractiveQoS 的 DispatchQueue 跑 ASR,结果再通过主线程回写(DictateViewModel.swift)
  • VAD 辅助断句:叠加 Silero VAD 检测静默,在停顿约 960ms 后强制提交句子,避免 EOU 模型被环境噪音拖慢
  • 热词粘贴:识别完一键Cmd+Shift+V粘贴到前台任意应用

本地运行:cd Examples/DictateDemo && swift build,首次启动会自动下载约 112 MB 的模型。

使用建议与常见坑

  1. 麦克风采集不在 SpeechUI 里:官方明确说 SpeechUI 只提供转写展示层,录音用 AVFoundation 或项目里的 SystemAudioTap.swift。
  2. @Observable在菜单栏弹层中可能不触发刷新:DictateDemo 特意改用ObservableObject + @Published(见 DictateViewModel.swift 的注释)。如果你的听写界面跑在MenuBarExtrapopover 里,建议照抄这个方案。
  3. 临时行别当最终文本用:currentPartial会被后续更新覆盖,复制/提交内容请基于finalLines。
  4. 性能预期:Parakeet 120M 流式模型在 Apple Silicon 上约 18 倍实时;更大模型(如 Qwen3-ASR)可参考 docs/benchmarks/ios-coreml.md 的基准数据选档。

参考文件速查

  • 组件源码:Sources/SpeechUI/(仅 2 个文件,可直接精读)
  • 单元/端到端测试:Tests/SpeechUITests/
  • 完整示例 App:Examples/DictateDemo/
  • 构建指南:docs/building.md

📌 总结:SpeechUI 用最少的代码(一个 store + 一个 view)把流式 ASR 最难看的界面问题一次性解决。对新手而言,先跑通 DictateDemo 示例,再按本文的 10 行接线方式替换成自己的 ASR 后端,是接入 speech-swift 最快的路径。

【免费下载链接】speech-swift

AI speech toolkit for Apple Silicon — ASR, TTS, speech-to-speech, VAD, and diarization powered by MLX and CoreML

项目地址:https://gitcode.com/gh_mirrors/sp/speech-swift
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询