恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
ZCode 语音输入组件 SpeechInput 实战指南:Web Speech API 与 MediaRecorder 双引擎语音转文字方案
首页
资讯中心
/
ZCode 语音输入组件 SpeechInput 实战指南:Web Speech API 与 MediaRecorder 双引擎语音转文字方案
ZCode 语音输入组件 SpeechInput 实战指南:Web Speech API 与 MediaRecorder 双引擎语音转文字方案
发布时间:2026/9/23 8:46:08
ZCode 语音输入组件 SpeechInput 实战指南Web Speech API 与 MediaRecorder 双引擎语音转文字方案【免费下载链接】ZCodeZ.ais coding agent harness. Powerful, intelligent, extensible.项目地址: https://gitcode.com/gh_mirrors/zco/ZCode本文围绕 ZCode 仓库中 ai-elements 技能包提供的SpeechInput语音输入组件系统讲解如何在基于 shadcn/ui 的 React 应用中接入点击麦克风说话 → 自动转写为文本的完整能力。组件在 Chrome、Edge 上借助 Web Speech API 实现免服务器的实时转写在 Firefox、Safari 上自动降级为 MediaRecorder 录音并交给外部转写服务如 OpenAI Whisper。读完本文你将掌握该组件的安装方式、Props 契约、双引擎工作原理、生命周期与状态管理并能基于 示例脚本 在真实项目中落地一套跨浏览器可用的语音输入方案。SpeechInput 组件概述SpeechInput是一个封装了捕获语音输入并转换为文本能力的按钮组件核心价值在于用一个组件抹平不同浏览器在语音识别能力上的差异在支持 Web Speech API 的浏览器Chrome、Edge中使用SpeechRecognition进行实时转录无需任何服务器参与在不支持 Web Speech API 的浏览器Firefox、Safari中自动降级为MediaRecorder录音将音频 Blob 交给调用方提供的转写回调例如 OpenAI Whisper、Google Cloud Speech-to-Text、AssemblyAI在两者都不可用的环境中按钮自动置灰禁用避免出现点了没反应的糟糕体验。该组件是 ai-elements 组件库的一部分。ai-elements 是构建在 shadcn/ui 之上的 AI 原生应用组件库SpeechInput直接继承 shadcn/ui 的Button组件因此按钮的variant、size、disabled等全部属性都天然可用安装后组件代码会直接落入你的项目源码目录默认/components/ai-elements/可以像自己写的组件一样自由修改。仓库中的完整可运行示例见 speech-input.tsx它演示了从录音回调到转写文本展示的完整链路。安装与项目集成在 ai-elements 体系中组件通过 CLI 安装到当前项目npx ai-elementslatest add speech-input如果项目使用 pnpm 或 bun 作为包管理器请使用对应的 runnerpnpm dlx ai-elementslatest add speech-input或bunx --bun ai-elementslatest add speech-input。根据 SKILL.md 中的说明安装前需要满足以下前提Node.js 18 及以上一个Next.js 项目且已安装AI SDK项目已配置shadcn/ui未配置时执行安装命令会自动补装。安装完成后组件代码会写入/components/ai-elements/speech-input.tsx实际目录取决于你 shadcn 的 components 配置样式基于 Tailwind CSS 类无需额外配置即可直接使用。若导入时报 module not found请检查tsconfig.json是否正确配置了/*路径别名例如{ compilerOptions: { baseUrl: ., paths: { /*: [./*] } } }Props 契约SpeechInput继承 shadcn/uiButton的全部 props仅新增三个专属属性Prop类型默认值说明onTranscriptionChange(text: string) void无最终转写文本就绪时触发的回调。只在完整语句产出时触发中间过程产生的临时结果interim results不会触发。onAudioRecorded(audioBlob: Blob) Promisestring无MediaRecorder 降级模式的回调。Firefox/Safari 支持的必要条件接收录音 Blob返回外部转写服务如 OpenAI Whisper给出的文本。langstringen-US语音识别的语言代码。...propsReact.ComponentPropstypeof Button无其余 props 全部透传给 Button包括variant、size、disabled等。需要特别强调的是onAudioRecorded的必要性语义它只在 MediaRecorder 模式下被调用但在 Firefox/Safari 上如果不提供该回调按钮会直接处于禁用状态。因此要获得完整的跨浏览器能力这两个回调都应提供。双引擎工作机制识别模式自动探测组件挂载时会自动检测浏览器能力选择当前环境可用的最佳方案浏览器模式行为Chrome、EdgeWeb Speech API实时转录无需服务器Firefox、SafariMediaRecorder录音后交由外部转写服务不支持的环境禁用按钮置灰Web Speech API 模式Chrome、Edge基于SpeechRecognition含 webkit 前缀实现内置如下配置Continuous连续识别设为true识别保持激活直到用户再次点击按钮手动停止Interim Results临时结果设为true说话过程中持续返回部分结果Language语言通过langprop 配置默认en-US。该模式下识别过程不依赖任何后端服务音频在浏览器本地被处理延迟低、体验顺滑。MediaRecorder 模式Firefox、Safari当 Web Speech API 不可用时组件切换到录音降级流程完整步骤为使用MediaRecorderAPI 采集麦克风音频用户停止录音后生成audio/webm格式的音频 Blob调用onAudioRecorded(blob)将音频交给外部转写服务等待转写服务返回文本将返回文本传给onTranscriptionChange。注意该模式下录音格式固定为audio/webmonAudioRecorded是必须提供的 prop否则按钮在 Firefox/Safari 上会被禁用。转录处理只认最终结果组件对回调做了严格的语义约束只有最终转写文本final transcript才会触发onTranscriptionChange。Web Speech API 产生的 interim results说话中途的不完整片段会被丢弃避免下游把说到一半的文本当作完整输入处理。这一点对聊天输入、命令输入等场景至关重要——你可以放心地拿到文本后立即发送或执行不会出现半截话。生命周期组件的完整生命周期可以概括为四个阶段挂载Mount检测可用的浏览器 API初始化对应模式点击Click在监听/录音中与已停止两个状态间切换停止StopMediaRecorder 模式处理音频并等待转写结果返回卸载Unmount停止识别/录音并释放麦克风资源避免残留占用。卸载时的资源释放尤其重要可以防止组件销毁后麦克风指示灯常亮或浏览器持续显示正在使用麦克风。视觉状态与状态机组件为不同阶段提供明确的可视反馈方便用户感知当前所处状态状态表现默认状态标准按钮外观 麦克风图标监听中呼吸/脉冲pulse动画 强调色提示正在收音处理中加载 spinner仅 MediaRecorder 模式等待转写服务返回禁用无可用 API 或缺少必要 props 时按钮置灰完整实战MediaRecorder 降级 OpenAI Whisper要在 Firefox 和 Safari 上获得完整支持需要为onAudioRecorded提供一个把音频送给转写服务的实现。原文档给出的标准写法如下仓库配套示例见 speech-input.tsxconst handleAudioRecorded async (audioBlob: Blob): Promisestring { const formData new FormData(); formData.append(file, audioBlob, audio.webm); formData.append(model, whisper-1); const response await fetch(https://api.openai.com/v1/audio/transcriptions, { method: POST, headers: { Authorization: Bearer ${process.env.OPENAI_API_KEY}, }, body: formData, }); const data await response.json(); return data.text; }; SpeechInput onTranscriptionChange{(text) console.log(text)} onAudioRecorded{handleAudioRecorded} /;配套示例脚本在此基础上做了两个值得借鉴的增强适合直接迁移到生产代码1. 错误显式抛出!response.ok时抛出throw new Error(Transcription failed)让组件内部的错误处理逻辑能够感知失败并自动停止识别/录音流程原文档 Notes 中说明错误会记录到 console 并自动停止识别/录音。2. 转写文本的增量拼接onTranscriptionChange在回调里把每次的最终文本追加到已有内容之后而不是覆盖const handleTranscriptionChange useCallback((text: string) { setTranscript((prev) { const newText prev ? ${prev} ${text} : text; return newText; }); }, []);因为 Web Speech API 的 Continuous 模式在持续说话过程中会产出多个最终结果采用追加式拼接可以让多轮语音输入自然累积成一段完整文本配合一个 Clear 按钮即可形成完整的语音输入体验。示例中组件以图标按钮形式呈现SpeechInput onAudioRecorded{handleAudioRecorded} onTranscriptionChange{handleTranscriptionChange} sizeicon variantoutline /如果你的转写服务不是 OpenAI WhisperonAudioRecorded的签名(audioBlob: Blob) Promisestring同样适配 Google Cloud Speech-to-Text、AssemblyAI 等任意输入音频、输出文本的服务只需替换内部实现即可。浏览器支持矩阵组件通过两层架构实现跨浏览器覆盖浏览器使用的 API前提条件ChromeWeb Speech API无EdgeWeb Speech API无FirefoxMediaRecorder提供onAudioRecordedpropSafariMediaRecorder提供onAudioRecordedprop要实现完整的跨浏览器支持请务必提供onAudioRecorded回调将音频发送到 OpenAI Whisper、Google Cloud Speech-to-Text 或 AssemblyAI 等转写服务。无障碍设计组件在无障碍方面保持了 shadcn/ui 组件的一贯水准通过 shadcn/uiButton使用语义化的button元素监听状态提供明确的视觉反馈脉冲动画同时不影响键盘用户支持键盘触发Space/Enter 可激活/停用语义化的按钮结构对屏幕阅读器友好。安全与使用注意以下注意事项直接影响组件能否正常工作建议在接入前逐条核对均出自 原文档 的 Notes 与 Behavior 章节安全上下文要求麦克风访问要求页面处于安全上下文即HTTPS 或 localhost浏览器权限提示首次使用时浏览器会向用户弹出麦克风权限请求请提前在交互文案中引导用户授权只回调最终文本onTranscriptionChange仅在最终转写文本产出时触发interim results 一律忽略语言可配置通过langprop 设置识别语言默认en-US如中文可传zh-CN连续识别Continuous 开启识别会一直持续直到再次点击按钮错误自动收敛出错时错误信息写入 console识别/录音自动停止不会卡在异常状态录音格式MediaRecorder 降级模式录音格式固定为audio/webm回调完整性MediaRecorder 降级模式依赖onAudioRecordedprop缺失时按钮在 Firefox/Safari 下禁用。TypeScript 类型支持组件内置了 Web Speech API 的完整 TypeScript 类型声明同时兼容标准实现与 webkit 前缀实现SpeechRecognitionSpeechRecognitionEventSpeechRecognitionResultSpeechRecognitionAlternativeSpeechRecognitionErrorEvent这些类型声明意味着在 TypeScript 项目中无需自行编写declare global补丁即可获得完整的类型提示与编译期检查。语音输入组件生态与周边组件的配合SpeechInput并非孤立组件它是 ai-elements 语音能力组件族的一员。仓库 references 目录中与之配套的还有MicSelector麦克风设备选择器基于useAudioDevices()hook 枚举输入设备、处理权限与devicechange热插拔检测可用来为SpeechInput指定默认麦克风VoiceSelectorAI 语音TTS 音色选择器负责说话的声音这一侧Transcription转写结果展示组件接收 AI SDKtranscribe()产出的带时间轴分段{ text, startSecond, endSecond }支持播放高亮与点击跳转适合做录音回放 逐句同步的场景。实际项目中一个完整的语音交互链路通常这样组织用MicSelector选择输入设备 → 用SpeechInput采集并转写语音 → 用Transcription展示带时间轴的转写结果。三者分工明确SpeechInput负责其中最核心的语音转文本环节。故障排查速查Firefox/Safari 上按钮是禁用的检查是否提供了onAudioRecordedprop这是降级模式工作的硬性前提按钮可点但没有任何反应确认页面运行在 HTTPS 或 localhost 安全上下文中并检查浏览器是否拦截了麦克风权限转写文本不完整或缺失确认只依赖onTranscriptionChange接收最终文本interim results 不会被回调导入报 module not found确认tsconfig.json中/*路径别名配置正确且组件文件确实存在于/components/ai-elements/目录下样式缺失确认项目的globals.css已导入 Tailwind 并包含 shadcn/ui 基础样式Tailwind 4 项目尤其注意。总结SpeechInput用约 150 行组件代码解决了语音输入领域最棘手的浏览器兼容性问题Web Speech API 优先、MediaRecorder 外部转写服务兜底、不支持时优雅禁用。通过onTranscriptionChange与onAudioRecorded两个回调组件把采集语音和文本消费彻底解耦——前者由组件全权负责后者由你的业务代码按需实现。配合仓库中的 配套示例你可以在一个下午内为聊天输入框、命令面板或任何文本输入场景接入可靠的语音输入能力。【免费下载链接】ZCodeZ.ais coding agent harness. Powerful, intelligent, extensible.项目地址: https://gitcode.com/gh_mirrors/zco/ZCode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考