资讯详情

在 airi 项目中用 VueUse useSpeechSynthesis 实现响应式语音朗读

📅 2026/9/10 9:32:10 | 华诺云谱 👁 阅读
在 airi 项目中用 VueUse useSpeechSynthesis 实现响应式语音朗读
在 airi 项目中用 VueUse useSpeechSynthesis 实现响应式语音朗读【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airiuseSpeechSynthesis是 VueUse 对 Web Speech Synthesis APISpeechSynthesis的响应式封装属于 Sensors 分类下的组合式函数。它把浏览器朗读能力抽象为isSupported、isPlaying、status、utterance等响应式状态并暴露speak()、toggle()、stop()等控制方法让你在 Vue 3 / Nuxt 3 组件里用几行代码即可完成文本转语音的完整交互。阅读本文后你将掌握该组合式函数的所有参数、返回值与类型约束并能直接把它接入 airi 仓库中的任意 Vue 应用如 apps/stage-web、apps/stage-tamagotchi实现 TTS 朗读能力。本文主体来源于仓库内文档 .agents/skills/vueuse-functions/references/useSpeechSynthesis.md并辅以 .agents/skills/vueuse-functions/SKILL.md 中关于函数选用规则Invocation 规则的说明展开。为什么需要响应式封装Web Speech Synthesis API 本身是命令式的你需要手动创建SpeechSynthesisUtterance实例、监听start/end/pause/resume/boundary/error等一系列事件再手动维护当前是否在朗读、当前状态等标志位极易产生样板代码与状态不同步问题。useSpeechSynthesis将这些细节全部收敛自动检测window.speechSynthesis是否存在SSR 场景下同样安全通过isSupported暴露支持情况内部创建并持有SpeechSynthesisUtterance通过utterance以ComputedRef形式暴露将朗读状态收敛为statusinit | play | pause | end与isPlaying两个响应式信号提供speak()、toggle()、stop()三个控制函数组件内无需再与底层 API 直接打交道。在 .agents/skills/vueuse-functions/SKILL.md 中useSpeechSynthesis被归入 Sensors 类别Invocation 规则为AUTO——即在适用场景下应自动优先使用而非要求显式请求或额外安装依赖。这与该 skill 的核心主张一致优先用 VueUse 组合式函数替代手写逻辑以保持代码简洁、可维护且性能良好。基础用法从vueuse/core引入并在组件中调用import { useSpeechSynthesis } from vueuse/core const { isSupported, isPlaying, status, voiceInfo, utterance, error, stop, toggle, speak, } useSpeechSynthesis()调用后即可直接使用这些返回值。一个最小可用的 Vue 组件示例如下script setup langts import { ref } from vue import { useSpeechSynthesis } from vueuse/core const text ref(你好我是 A.I.R.I很高兴认识你。) const { isSupported, isPlaying, status, speak, stop, toggle } useSpeechSynthesis(text) /script template div v-ifisSupported textarea v-modeltext / button clickspeak()朗读/button button clicktoggle(){{ isPlaying ? 暂停 : 继续 }}/button button clickstop()停止/button span当前状态{{ status }}/span /div p v-else当前环境不支持 Speech Synthesis API/p /template注意useSpeechSynthesis的第一个参数是文本内容类型为MaybeRefOrGetterstring即可以直接传字符串、ref或 getter 函数。传入ref时朗读文本会随响应式数据自动更新这正是响应式 SpeechSynthesis的含义。Options语音参数与默认值useSpeechSynthesis(text, options)的第二个参数UseSpeechSynthesisOptions直接透传给底层的SpeechSynthesisUtterance默认值如下import { useSpeechSynthesis } from vueuse/core useSpeechSynthesis(朗读内容, { lang: en-US, // 语言默认 en-US pitch: 1, // 音高默认 1 rate: 1, // 语速默认 1 volume: 1, // 音量默认 1 })各选项的作用与取值范围说明如下选项类型默认值说明langMaybeRefOrGetterstringen-US朗读使用的语言BCP 47 语言标签如zh-CN、ja-JP。应与所选voice匹配否则可能使用系统默认语音pitchMaybeRefOrGetterSpeechSynthesisUtterance[pitch]1音高数值范围 02典型取值 02越接近 2 声音越尖rateMaybeRefOrGetterSpeechSynthesisUtterance[rate]1语速数值范围 0.1101 为正常语速voiceMaybeRefSpeechSynthesisVoice无默认值指定使用的语音对象可通过speechSynthesis.getVoices()获取候选列表不传则由系统选择volumeMaybeRefOrGetterSpeechSynthesisUtterance[volume]1音量数值范围 01onBoundary(event: SpeechSynthesisEvent) void无触发boundary事件时的回调可用于实现逐词高亮、字幕同步等效果关键点lang、pitch、rate、volume均接受MaybeRefOrGetter意味着这些参数可以绑定到响应式数据上用户在界面上拖动滑块调节语速、音高时下一次speak()自动使用新值voice只接受MaybeRefref 或普通值因为语音对象是浏览器提供的实例不适合用 getter 动态推导由于SpeechSynthesisUtterance的属性如pitch、rate在不同浏览器上校验严格程度不同超出范围的值可能被钳制或忽略建议在 UI 层做好范围约束。返回值详解useSpeechSynthesis返回UseSpeechSynthesisReturn字段说明如下返回值类型说明isSupportedboolean来自Supportable当前环境是否支持 Speech Synthesis API用于条件渲染或功能降级isPlayingShallowRefboolean当前是否处于播放状态statusShallowRefUseSpeechSynthesisStatus朗读状态机init \| play \| pause \| endvoiceInfo语音信息当前使用的语音信息用于展示或调试utteranceComputedRefSpeechSynthesisUtterance当前朗读的SpeechSynthesisUtterance实例文本或参数变化时会重新生成errorShallowRefSpeechSynthesisErrorEvent \| undefined最近一次朗读错误事件无错误时为undefinedstop() void立即停止朗读toggle(value?: boolean) void切换播放 / 暂停传入value时可强制指定目标状态speak() void使用当前文本与参数开始朗读典型的使用模式const { isPlaying, status, error, stop, toggle, speak } useSpeechSynthesis(text) // 在朗读结束时做清理或触发下一步 watch(status, (s) { if (s end) console.log(朗读结束) }) // 朗读出错时回退到文本提示 watch(error, (e) { if (e) console.error(语音朗读失败, e) })toggle()不带参数时自动切换播放与暂停播放中调用则暂停暂停中调用则恢复。这在语音播放/暂停按钮的实现中尤其好用无需手动判断当前状态。类型声明一次看懂完整接口文档给出了完整的 TypeScript 类型声明它是理解该函数能力边界的最佳入口export type UseSpeechSynthesisStatus init | play | pause | end export interface UseSpeechSynthesisOptions extends ConfigurableWindow { lang?: MaybeRefOrGetterstring pitch?: MaybeRefOrGetterSpeechSynthesisUtterance[pitch] rate?: MaybeRefOrGetterSpeechSynthesisUtterance[rate] voice?: MaybeRefSpeechSynthesisVoice volume?: MaybeRefOrGetterSpeechSynthesisUtterance[volume] onBoundary?: (event: SpeechSynthesisEvent) void } export interface UseSpeechSynthesisReturn extends Supportable { isPlaying: ShallowRefboolean status: ShallowRefUseSpeechSynthesisStatus utterance: ComputedRefSpeechSynthesisUtterance error: ShallowRefSpeechSynthesisErrorEvent | undefined stop: () void toggle: (value?: boolean) void speak: () void } export declare function useSpeechSynthesis( text: MaybeRefOrGetterstring, options?: UseSpeechSynthesisOptions, ): UseSpeechSynthesisReturn值得注意的类型细节UseSpeechSynthesisStatus是一个四态字符串联合类型init表示尚未开始play/pause/end对应朗读的三种终态与中间态用status end即可可靠判断一轮朗读是否结束UseSpeechSynthesisOptions extends ConfigurableWindow与 VueUse 中大多数浏览器相关组合式函数一致允许通过window选项传入自定义窗口对象主要用于测试或特殊宿主环境如 Electron 渲染进程返回值extends Supportable保证isSupported字段的存在且isSupported在 SSR 环境下为false避免服务端渲染时误调用浏览器 APIutterance是ComputedRef当text或lang/pitch/rate/volume等响应式参数变化时内部会重新构建SpeechSynthesisUtterance实例保证每次speak()都使用最新配置。在 airi 仓库中的接入实践airi 仓库是一个多应用、多包的大型 Vue 3 工程多个应用与包都声明了对vueuse/core的依赖包括 apps/stage-web/package.json、apps/stage-tamagotchi/package.json、apps/stage-pocket/package.json、packages/stage-ui/package.json、packages/stage-shared/package.json 等因此useSpeechSynthesis可直接在这些工程中开箱即用无需额外安装依赖这与 SKILL.md 中该函数的AUTO调用规则一致。一个贴近实际场景的完整示例——带语速 / 音量控制与状态展示的朗读面板script setup langts import { ref } from vue import { useSpeechSynthesis } from vueuse/core const message ref(A.I.R.I 正在为你朗读这条消息。) const rate ref(1) const volume ref(1) const { isSupported, isPlaying, status, error, speak, toggle, stop } useSpeechSynthesis(message, { lang: zh-CN, rate, volume, }) /script template section v-ifisSupported textarea v-modelmessage rows2 / label语速 input v-model.numberrate typerange min0.5 max2 step0.1 //label label音量 input v-model.numbervolume typerange min0 max1 step0.1 //label button clickspeak()开始朗读/button button clicktoggle(){{ isPlaying ? 暂停 : 继续 }}/button button clickstop()停止/button p状态{{ status }}span v-iferror错误{{ error.error }}/span/p /section /template注意事项与限制浏览器支持差异Speech Synthesis API 的支持程度与语音质量因浏览器、操作系统而异可通过isSupported检测基本可用性。部分浏览器要求页面交互后才能触发朗读首次调用speak()前建议先由用户手势触发。在 Chromium 系浏览器上还存在已知的长时间朗读后静默停止的问题可监听status变为end但实际未播完的情况做兜底。SSR 安全由于继承Supportable且基于window能力检测isSupported在服务端渲染时为false配合v-ifisSupported可以避免在 SSR 阶段调用浏览器 API。语音与语言匹配lang只声明语言实际使用哪个语音由系统决定若需要精确控制请通过speechSynthesis.getVoices()获取SpeechSynthesisVoice列表用voice选项显式指定。范围校验pitch02、rate0.110、volume01超出浏览器合法范围时行为不确定建议在 UI 上限制滑块范围。语音切换异步性getVoices()在部分浏览器上首次调用可能返回空数组需要在voiceschanged事件后再读取接入时注意时序。小结useSpeechSynthesis以最小的 API 面覆盖了 Web Speech Synthesis 的核心能力isSupported做能力检测、status/isPlaying做状态追踪、speak()/toggle()/stop()做播放控制配合lang/pitch/rate/volume等响应式参数可以在 Vue 3 应用中快速构建出健壮的 TTS 朗读功能。对于 airi 这类大量使用 Vue 3 与vueuse/core的工程它正是 SKILL.md 所倡导的用组合式函数替代手写逻辑的典型实践。若需要完整的类型约束与参数语义可直接查阅参考文档 useSpeechSynthesis.md。【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。