Web Speech API 使你能够将语音数据合并到 Web 应用程序中。Web Speech API 有两个部分:SpeechSynthesis 语音合成(文本到语音 TTS)和 SpeechRecognition 语音识别(异步语音识别)。
Speech synthesis
语音合成 (也被称作是文本转为语音,英语简写是 tts) 包括接收 app 中需要语音合成的文本,再在设备麦克风播放出来这两个过程。
Web Speech API 对此有一个主要控制接口——
SpeechSynthesis
,外加一些处理如何表示要被合成的文本 (也被称为 utterances),用什么声音来播出 utterances 等工作的相关接口。
语音合成
1.
SpeechSynthesis
语音合成服务的控制器接口,可用于获取设备上可用的合成语音,开始、暂停以及其他相关命令的信息。
属性
SpeechSynthesis.paused
只读
当
SpeechSynthesis
处于暂停状态时,
Boolean
值返回
true
。
SpeechSynthesis.pending
只读
当语音播放队列到目前为止保持没有说完的语音时,
Boolean
值返回
true
。
SpeechSynthesis.speaking
只读
当语音谈话正在进行的时候,即使
SpeechSynthesis
处于暂停状态,
Boolean
返回
true
。
事件操作
SpeechSynthesis.onvoiceschanged
当由
SpeechSynthesis.getVoices()
方法返回的
SpeechSynthesisVoice
列表改变时触发。
方法
SpeechSynthesis.cancel()
移除所有语音谈话队列中的谈话。
SpeechSynthesis.getVoices()
返回当前设备所有可用声音的
SpeechSynthesisVoice
列表。
SpeechSynthesis.pause()
把
SpeechSynthesis
对象置为暂停状态。
SpeechSynthesis.resume()
把
SpeechSynthesis
对象置为一个非暂停状态:如果已经暂停了则继续。
SpeechSynthesis.speak()
添加一个
utterance
到语音谈话队列;它将会在其他语音谈话播放完之后播放。
2.
SpeechSynthesisErrorEvent
包含了在发音服务处理
SpeechSynthesisUtterance
对象过程中的信息及报错信息。
3.
SpeechSynthesisEvent
包含了经由发音服务处理过的
SpeechSynthesisUtterance
对象当前状态的信息。
4.
SpeechSynthesisUtterance
表示一次发音请求。其中包含了将由语音服务朗读的内容,以及如何朗读它(例如:语种、音高、音量)。
5.
SpeechSynthesisVoice
表示系统提供的一个声音。每个
SpeechSynthesisVoice
都有与之相关的发音服务,包括了语种、名称 和 URI 等信息。
Window.speechSynthesis
由规格文档指定的,被称为
SpeechSynthesisGetter
的
[NoInterfaceObject]
接口的一部分,在
Window
对象中实现,
speechSynthesis
属性可用于访问
SpeechSynthesis
控制器,从而获取语音合成功能的入口。
浏览器兼容性
目前主流浏览器版本(截止2024-5-21)
Firefox (126.0)
Chrome(125.0.6422.61)
Safari(15.6.1)
<template>
<div class="s-s-wrap">
<textarea
id="text-to-speak"
rows="10"
cols="50"
placeholder="Enter text here"
></textarea>
<br /><br />
<label for="voices">Voice:</label>
<select id="voices"></select>
<br /><br />
<label for="rate">Rate:</label>
<input type="range" id="rate" min="0.5" max="2" value="1" step="0.1" />
<span id="rate-value">1</span>
<br /><br />
<label for="pitch">Pitch:</label>
<input type="range" id="pitch" min="0" max="2" value="1" step="0.1" />
<span id="pitch-value">1</span>
<br /><br />
<label for="volume">Volume:</label>
<input type="range" id="volume" min="0" max="1" value="1" step="0.1" />
<span id="volume-value">1</span>
<br /><br />
<button id="speak-btn" @click="speak" style="margin-right: 10px">
Speak
</button>
<button id="cancel-btn" @click="cancel" style="margin-right: 10px">
cancel
</button>
<button id="pause-btn" @click="pause" style="margin-right: 10px">
pause
</button>
<button id="resume-btn" @click="resume" style="margin-right: 10px">
resume
</button>
</div>
</template>
<script>
/*
大千世界,无奇不有。我陈平安,唯有一剑,可搬山,倒海,降妖,镇魔,敕神,摘星,断江,摧城,开天!<mark name="highlight">我叫陈平安</mark>,平平安安的平安。我是一名剑客。
*/
let voices = []
export default {
mounted() {
this.populateVoices()
let synth = window.speechSynthesis
/*
因为 Firefox 不支持SpeechSynthesis.onvoiceschanged ,
所以很常规地只是返回语音对象列表当SpeechSynthesis.getVoices() 被触发。
但是 Chrome 就有点不同了,在SpeechSynthesis.getVoices() 被触发时,
先要等待事件触发 (有点绕~按照下面代码,populateVoices 函数在 Firefox 运行一次,在 Chrome 中运行两次):
*/
if (synth.onvoiceschanged !== undefined) {
synth.onvoiceschanged = this.populateVoices
}
// 监听
const rate = document.getElementById('rate')
rate.addEventListener('change', this.setRateValue)
const pitch = document.getElementById('pitch')
pitch.addEventListener('change', this.setPitchValue)
const volume = document.getElementById('volume')
volume.addEventListener('change', this.setVolumeValue)
},
methods: {
// 使用设备可使用的不同的语音选项展示
populateVoices() {
// 引用window.speechSynthesis这个api
let synth = window.speechSynthesis
// 调用SpeechSynthesis.getVoices()
// 这个函数返回包含所有可用语音 (SpeechSynthesisVoice对象) 的列表
voices = synth.getVoices()
const voicesDropdown = document.getElementById('voices')
// 循环填入声音的名称(从SpeechSynthesisVoice.name获取),语音的语言(从SpeechSynthesisVoice.lang获取)
// 引擎默认的 (SpeechSynthesisVoice.default属性是true)
voicesDropdown.innerHTML = voices
.map(
(voice, i) =>
`<option value="${i}">${voice.name} (${voice.lang})</option>`
)
.join('')
},
// 设置语速
setRateValue() {
const rate = document.getElementById('rate')
const rateValue = document.getElementById('rate-value')
rateValue.textContent = rate.value
},
setPitchValue() {
const pitch = document.getElementById('pitch')
const pitchValue = document.getElementById('pitch-value')
pitchValue.textContent = pitch.value
},
setVolumeValue() {
const volume = document.getElementById('volume')
const volumeValue = document.getElementById('volume-value')
volumeValue.textContent = volume.value
},
speak() {
let synth = window.speechSynthesis
console.log('speak', synth)
if (synth.speaking) {
console.error('speechSynthesis.speaking')
return
}
const textArea = document.getElementById('text-to-speak')
const voicesDropdown = document.getElementById('voices')
// 创建一个新的SpeechSynthesisUtterance() 实例——把文本输入框中的值作为参数传递。
const utterThis = new SpeechSynthesisUtterance(textArea.value)
// const utterThis = new SpeechSynthesisUtterance()
// utterThis.text = '这是一段<mark name="highlight">重要的</mark>文本。'
console.log(voices, 'voices', voices[voicesDropdown.value])
// 使用哪种语音
// 把匹配的语音对象设置为SpeechSynthesisUtterance.voice 的属性值
utterThis.voice = voices[voicesDropdown.value]
const rate = document.getElementById('rate')
const pitch = document.getElementById('pitch')
const volume = document.getElementById('volume')
// 设置语速
utterThis.rate = rate.value
// 设置音高(音调)
utterThis.pitch = pitch.value
// 设置音量(响度)
utterThis.volume = volume.value
// 错误监听
utterThis.onerror = event => {
console.log(`speech-synthesis-错误监听: ${event}`)
}
// 暂停操作监听
utterThis.onpause = event => {
const char = event.utterance.text.charAt(event.charIndex)
console.log(
event,
`当前暂停位置的字符索引:${event.charIndex}, 文本内容:"${event.utterance.text}", 具体字符: "${char}".`
)
}
// 边界监听
utterThis.onboundary = event => {
console.log(event, `${event.name} 时间: ${event.elapsedTime} 秒.`)
}
// 标记监听
utterThis.onmark = event => {
console.log('标记监听', event)
if (event.name === 'highlight') {
console.log('朗读到达标记:' + event.name)
// 在这里执行您想要的操作,比如高亮显示文本、播放声音等
}
}
// 调用 SpeechSynthesis.speak() 开始说话
// 把 SpeechSynthesisUtterance 实例作为参数传递
synth.speak(utterThis)
},
cancel() {
let synth = window.speechSynthesis
console.log('cancel', synth)
synth.cancel()
},
pause() {
let synth = window.speechSynthesis
console.log('pause', synth)
synth.pause()
},
resume() {
let synth = window.speechSynthesis
console.log('resume', synth)
synth.resume()
}
}
}
</script>
<style>
.s-s-wrap {
width: 370px;
margin: auto;
}
</style>
版权归原作者 lrz136 所有, 如有侵权,请联系我们删除。