I. Demand analysis

① According to the displayed data list, the theme of each data is broadcast in turn;

(2) Mute function: click the voice that is currently broadcasting, pause to continue broadcasting this information, switch to the next information for broadcasting; When clicking on a message that is not currently being broadcast, skip the message with mute enabled.

Two, the use of technology

① SpeechSynthesis: control interface for speech services; It can be used to get information on the device about available synthetic sounds, to start, pause, or to do other commands.

Pause (), Resume (), speak()

MDN address: SpeechSynthesis

(2) SpeechSynthesisUtterance

MDN address: SpeechSynthesisUtterance

Technology stack

Js, vue3, typescript, ES6, Axios

3. Server construction

Nodejs is used to build the server easily

Four, function realization

① The SpeechSynthesis and SpeechSynthesis API

*/ const synth = window. SpeechSynthesis const MSG = new SpeechSynthesisUtterance() export class WarningsSpeech { texts: Array<any> lang: string speed: number pauseFlag: boolean flag: number constructor(texts = [], lang = 'zh-CN', speed = 1) { this.texts = texts this.lang = lang this.speed = speed this.pauseFlag = false this.flag = 0 } init() { msg.lang = this.lang synth.cancel() } speech() { this.init() if (this.pauseFlag) { this._judgePlay() this.resume() } else { msg.text = this.texts[this.flag]? .text ?? '' synth.speak(msg) } msg.onend = (e) => { this._judgePlay() } } _judgePlay() { for (let i = this.flag + 1; i < this.texts.length; i++) { if (this.texts[i].isMuted === false) { this.flag = i msg.text = this.texts[this.flag].text synth.speak(msg) return } } } pause() { synth.pause() this.pauseFlag = true } resume() { synth.resume() this.pauseFlag = false } muted() { if (! this.pauseFlag) { this.pause() } Promise.resolve(this.pauseFlag) .then((res) => { if (res) { this.speech() } }) .then(()  => { this.pauseFlag = false }) } cancel() { synth.pause() this.pauseFlag = true } }Copy the code

② Component Invocation

<div class="speech"> <h1> <ul class="speech"> <template v-for="(items, index) in dataItems" :key="items.id"> <li class="speech_slide"> <span>{{ items.title }}</span> <i @click="handleMuted(items, index)" :class="{ disabled_i: Kitems. isMuted}"> </ I > </li> </template> </ul> </div> </template> <script lang="ts" setup> import {ref, fraternal} onMounted } from 'vue' import { getData } from '@/api/speech' import { WarningsSpeech } from '@/utils/speechSythesis' / / const dataItems = ref([]) const speech = ref<any>(null) onMounted(() => {handleGetData()})/const dataItems = ref([]) const speech = ref<any>(null) onMounted(() => {handleGetData()}) / handleGetData = async () => { try { const { data: res } = await getData() const { data } = res dataItems.value = data.dataList.map((o: any) => { return { ... o, text: o.title, isMuted: Value = new WarningsSpeech(dataItems. Value) speech.value.speech()} Catch (e) {console.error(' Request error, Please contact the administrator! ')}} /** * Muted button function */ const handlefraternal = (item: any, index: number) => { if (index === speech.value.flag) { speech.value.muted() } item.isMuted = ! item.isMuted dataItems.value[index].isMuted = item.isMuted } </script> <! -- Add "scoped" attribute to limit CSS to this component only --> <style scoped> h3 { margin: 40px 0 0; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0; } a { color: #42b983; } .speech_container { width: 15vw; margin: 0 auto; padding: 20px 20px 50px; Color: rgba(255, 255, 255, 0.85); border-radius: 8px 8px 0 0; background-image: -webkit-linear-gradient(#24c5b6, #b2ebd6); } .speech_slide { width: 100%; display: inline-flex; justify-content: space-between; align-items: center; margin: 5px 0; } .speech_slide i { font-style: normal; display: inline-block; padding: 2px 10px; box-sizing: border-box; border-radius: 6px; color: #24c5b6; font-size: 12px; Background: Rgba (255, 255, 255, 0.85); cursor: pointer; }. Speech_slide. Disabled_i {background: rgba(255, 255, 255, 0.55); color: #fff; cursor: not-allowed; } </style>Copy the code

5. Code analysis

① Node: after using Node to build the server, configure the proxy in vue.config.js to successfully send the request, otherwise 404 will appear;

SpeechSynthesis and SpeechSynthesisUtterance The key is to press the mute button to determine whether it is an ongoing speech. If so, the current speech is interrupted and the next unmuted message is broadcast, a conservation method in the WarningsSpeech class. _judgePlay is a private attribute of the class. It is used to find the next unmuted message in the callback at the end of the voice for voice announcement

6. Achievements Display

7. SpeechSynthesis API Compatibility:

Checking Compatibility

As you can see, most major browsers already support this API.

Seven, end

The source code has been uploaded to github(github.com/duangkey/sp…)

The furthest distance in the world is not between you and me through a network cable, but when you saw it, you didn’t leave your star!!