Web端在线语音连续播报文本 - SpeechSynthesis

HTML5 SpeechSynthesis接口是语音服务的控制接口;它可以用于获取设备上关于可用的合成声音的信息,开始、暂停语音

 以下是示例使用代码:

<template>
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form label-width="70px" class="form-speech">
              <el-form-item label="播报文本">
                <el-input v-model="state.code" type="textarea" rows="8" />
              </el-form-item>
              <el-form-item label="语言">
                <el-select v-model="state.lang" @change="syncConfig" placeholder="请选择">
                  <el-option
                    v-for="item in langOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="音调">
                <el-slider v-model="state.pitch" @change="syncConfig" :min="0" :max="2" :step="1"></el-slider>
              </el-form-item>
              <el-form-item label="音速">
                <el-slider v-model="state.rate" @change="syncConfig" :min="0.1" :max="10" :step="0.1"></el-slider>
              </el-form-item>
              <el-form-item label="音量">
                <el-slider v-model="state.volume" @change="syncConfig" :min="0" :max="1" :step="0.1"></el-slider>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="addPlay">添加至待播</el-button>
              </el-form-item>
            </el-form>
          </el-col>
          <el-col :span="12">
            <div class="list-playlist">
              <div class="list-head">
                <div><span>待播:</span><span style="color:#409EFF">{{ list.length }}</span></div>
                <div><span>已播:</span><span style="color:green">{{ playlist.length - list.length }}</span></div>
              </div>
              <div class="list-body">
                <div v-for="(item,i) in list" :key="i + item.code" class="list-item">{{ formatText(item.code) }}</div>
              </div>
              <div class="list-foot">
                <el-button v-if="!speech" type="primary" @click="run">播放</el-button>
                <el-button v-if="speech" type="default" @click="stop">停止</el-button>
                <el-button v-if="speech && isSpeaking" type="default" @click="pause">暂停</el-button>
                <el-button v-if="speech && isPaused" type="default" @click="resume">继续</el-button>
              </div>
            <div>
          </el-col>
        </el-row>
  </div>
</template>

<script>
export default {
  data () {
	  return {
      speech: null,
      state: {
        code: '',
        lang: '',
        pitch: 1,
        rate: 1,
        volume: 1,
      },
      langOptions: [
        { label: '默认语言', value: '' },
        { label: '中文', value: 'zh' },
        { label: '英文', value: 'en' },
        { label: '法语', value: 'fr' },
        { label: '日语', value: 'ja' },
        { label: '德语', value: 'de' }
      ],
      isSpeaking: false,
      isPaused: false,
      isStop: false,
      playlist: [],
      list: []
    }
  },

  mounted() {
    this.initView()
  },

  methods: {
    // 初始化视图
    initView() {},
    // 添加至待播
    addPlay () {
      if (/^\s*$/.test(this.state.code)) {
        this.$message({
          message: '请输入播放文本',
          type: 'warning'
        })
        return false
      }
    	// 检查浏览器是否支持Web Speech API
    	if ('speechSynthesis' in window) {
        let node = Object.assign({}, this.state)
  		  this.playlist.push(node)
  		  this.list.push(node)
    	} else {
        this.$message({
          message: '浏览器不支持语音播报',
          type: 'warning'
        })
  	    console.error('浏览器不支持Web Speech API');
    	}
    },
    // 开始播放
    run () {
      if (!this.list[0]) {
        this.$message({
          message: '请添加播放文本',
          type: 'warning'
        })
        return false
      }
    	// 检查浏览器是否支持Web Speech API  
    	if ('speechSynthesis' in window) {
        this.isStop = false
        this.play()
    	} else {
        this.$message({
          message: '浏览器不支持语音播报',
          type: 'warning'
        })
  	    console.error('浏览器不支持Web Speech API');
    	}
    },
    // 播放
    play () {
      // 清空未播放完的
      speechSynthesis.cancel()
		  // 创建一个新的SpeechSynthesisUtterance对象
	    let text = this.list[0].code
	    let speech = new SpeechSynthesisUtterance(text)
      speech.text = text //文字
      this.speech = speech
	    this.syncConfig(this.state)
      this.bindEvents()
	    speechSynthesis.speak(speech) //播放语音
    },
    // 播放下一个
    playNext () {
      this.list.shift()
      if (!this.list[0]) {
        return false
      }
      this.play()
    },
    // 同步配置
    syncConfig (options) {
	    let speech = this.speech
      if (!speech) {
        return true
      }
      if (options.lang) {
        speech.lang = options.lang
      }
	    speech.pitch = options.pitch // 语速
	    speech.rate = options.rate // 语速
      speech.volume = options.volume // 音量
    },
    // 事件绑定
    bindEvents () {
	    let speech = this.speech
      if (!speech) {
        return true
      }
      // 开始语音播放时触发
      speech.addEventListener('start', () => {
        this.isSpeaking = true
        this.isPaused = false
      })
      // 暂停语音播放时触发
      speech.addEventListener('pause', () => {
        this.isSpeaking = false
        this.isPaused = true
      })
      // 恢复语音播放时触发
      speech.addEventListener('resume', () => {
        this.isSpeaking = true
        this.isPaused = false
      })
      // 语音播放结束时触发
      speech.addEventListener('end', () => {
        this.speech = null
        this.isSpeaking = false
        if (this.isStop || this.isPaused) {
          this.isPaused = false
          return true
        }
        this.isPaused = false
        // 播放下一个
        this.playNext()
      })
      // 语音播放错误时触发
      speech.addEventListener('error', () => {
        this.speech = null
        this.isSpeaking = false
        this.isPaused = false
      })
    },
    // 停止播放
    stop () {
	    let speech = this.speech
      if (!speech) {
        return true
      }
      speechSynthesis.cancel()
      this.isStop = true
      this.speech = null
    },
    // 暂停播放
    pause () {
	    let speech = this.speech
      if (!speech) {
        return true
      }
      speechSynthesis.pause()
    },
    // 继续播放
    resume () {
	    let speech = this.speech
      if (!speech) {
        return true
      }
      speechSynthesis.resume()
    },
    // 文本格式化
    formatText (value) {
      let len = value.length
      return value.slice(0, 20) + (len > 20 ? '...' : '')
    }
  }
}
</script>

<style scoped>
  .list-playlist {
    .list-head {
      display: flex;
      justify-content: space-between;
      font-weight: 700;
    }
    .list-body {
      overflow: auto;
      padding: 8px;
      max-height: 240px;
    }
  }
</style>

低配置云服务器,首次加载速度较慢,请耐心等候

预览页面:http://www.daelui.com/#/tigerlair/saas/preview/lvakef63u84k
演练页面:http://www.daelui.com/#/tigerlair/saas/practice/lvakef63u84k

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果`window.speechSynthesis`有时无法播放文本,可能是由于以下原因: 1. 浏览器不支持Web Speech API:请确保您的浏览器支持Web Speech API。Web Speech API在某些旧版本的浏览器中可能不可用。您可以在浏览器控制台中检查是否有任何错误消息来确定问题的原因。 2. 合成语音数据未加载:有时浏览器可能需要更多时间来加载合成语音数据。您可以尝试等待片刻或尝试在`onvoiceschanged`事件中更新可用的语音。例如: ```javascript const synth = window.speechSynthesis; let voices = []; synth.onvoiceschanged = () => { voices = synth.getVoices(); } const utterance = new SpeechSynthesisUtterance(this.text); utterance.voice = voices[0]; // 设置第一个可用的语音 synth.speak(utterance); ``` 3. 某些语音不可用:某些语音可能不可用或需要下载。您可以使用`synth.getVoices()`方法检查可用的语音,并选择一个可用的语音。例如: ```javascript const synth = window.speechSynthesis; let voices = []; synth.onvoiceschanged = () => { voices = synth.getVoices(); } const utterance = new SpeechSynthesisUtterance(this.text); const voice = voices.find(v => v.lang === 'en-US'); // 查找英语语音 utterance.voice = voice; synth.speak(utterance); ``` 4. 播放速率过快或过慢:有时语音播放速度可能会影响语音的可听性。您可以尝试调整播放速率。例如: ```javascript const synth = window.speechSynthesis; const utterance = new SpeechSynthesisUtterance(this.text); utterance.rate = 0.8; // 设置播放速率为0.8倍 synth.speak(utterance); ``` 希望这些提示可以帮助您解决问题。如果问题仍然存在,请提供更多详细信息,以便我更好地帮助您。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值