vue页面实现语音播报

1、vue页面添加鼠标滑动事件

现代的浏览器默认是不支持自动播报语音的,第一次需要主动出发,后边就会自动播报了。
使用 @mouseover.stop=“clickOther” 这个方法

<template>
    <div class="wrap wrapBG" @mouseover.stop="clickOther">
        <!--语音播报-->
        <div v-if="voiceWordIsShow" class="flex flex-center" style="position:relative;z-index: 999;">
            <div @click.stop="jumpNewWindow" class="voiceWord_ flex flex-center voicePlayBorderColor voicePlayBg">
                <i class="iconfont iconfont_" style="color: #F6AD31"
                >&#xe697;</i>
                <span>{{voiceWord}}</span>
            </div>
        </div>
    </div>
 </template>

2、data中定义是否已经开启了语音播报

data中定义是否已经开启了语音播报, isOpenPlay 为true时,已经开启,再次鼠标划入的时候,不会再次调用语音播报的模块。

data(){
      return{
            isOpenPlay: false, // 浏览器是否开启了语音播报
            isPlaying: false, // 语音是否正在播报
      }
}

3、监听用户鼠标移入事件

鼠标移入,主动开启语音播报的方法 clickOther(), 这个地方使用 ‘-’ 作为默认的播报文字,不会发出声音,但可以开启浏览器的语音播报

// 监听用户鼠标移入事件
            clickOther() {
                if (!this.isOpenPlay) {
                    this.isOpenPlay = !this.isOpenPlay
                    voicePlay('-')
                }
            },

4、voicePlay()方法,使用的是百度的tts

export function voicePlay(word) {
    let url = "https://tts.baidu.com/text2audio?cuid=baike&spd=5&lan=ZH&ctp=1&pdt=301&vol=4&rate=32&per=0&tex=' "+ encodeURI(word);
    let n = new Audio(url);
    n.src = url;
    n.play();//播放阅读
    return n
}

5、 watch监听后台推送的数据

watch: { 
	// 监听ws的连接状态
            '$store.state.connectStatus'() {
                let sRegion = getRegion(); // 初始化区域Id
                cancelVoiceWordMessage()
                // 实时播报内容
                if(this.$store.state.connectStatus) {
                    // 实时播报内容
                    voiceWordMessage(this.$store.state.region.regionCode)
                }
            },
            // 监听区域ID变化
            '$store.state.region'() {
                this.regionId = this.$store.state.region.regionCode;
                cancelVoiceWordMessage();
                if (this.$store.state.connectStatus) {
                    // 实时播报内容
                    voiceWordMessage(this.regionId)
                }
            },
            //平台实时播报的内容
            '$store.state.voiceWord'() {
                let data = this.$store.state.voiceWord
                if(!this.isPlaying){ // 第一条数据来了之后,就开始播报,
                    this.isPlaying = true
                    this.voicePlayMethod(data)
                }
            }
}

6、store中定义的 voiceWord

import {login, logout} from '../api/user'
import md5 from 'js-md5'
import {getName, getToken, removeToken, setName, setToken} from '../utils/auth'
import vue from 'vue'
import Vuex from 'vuex'

vue.use(Vuex)

const index =new Vuex.Store({
    state: {
        mapInfo: {},
        region: { // 区域ID

        },
        voiceWord: {}, // 实时播报内容
    },
   })

7、语音播报的方法voicePlayMethod

// 播报语音
            voicePlayMethod(data) {
                let that = this
                // 正在播报,就返回
                if (that.voicePlayState) {
                    return
                }// 如果没有开启语音播报,就返回
                    if (!this.isOpenPlay) {
                        return
                    }
                // 没有播报,就开始播报
                if (!that.voicePlayState) {
                    // 存储当前播报的类型和内容
                    that.voiceType = data.tag
                    that.eventId = data.eventId
                    that.orderId = data.orderId
                    that.voiceWord = data.desc
                    
                    // 显示播报弹窗
                    that.voiceWordIsShow = true
                    // 播报文字内容
                    that.voicePlayObj = voicePlay(that.voiceWord)
                    that.voicePlayObj.addEventListener("canplay", function () {   //当浏览器能够开始播放指定的音频/视频时,发生 canplay 事件。
                        that.voicePlayState = true
                    });
                    that.voicePlayObj.addEventListener("ended", function () {   //当播放完一首歌曲时也会触发
                        // 修改为当前没有语音播报
                        that.voicePlayState = false
                        that.isPlaying =  false // 播报完,设置为false

                         that.voiceWord = ''
                         that.voiceWordIsShow = false
                    })
                }
            },

8、socket中添加订阅的方法

import store from '@/store'
import {getToken} from "../utils/auth";
import {wsHostName} from '../utils/request-flask'

var url = wsHostName + "/ws/monitor?access-token=";
//var socket = new SockJS(url, null, {transports: 'websocket'});
//var stomp = Stomp.over(socket);

let subVoiceWordMessage = null;
let publicMessage = null;
//连接
store.state.connectStatus = false
var stomp = null;//定义全局变量,代表一个session
export function connect() {	//定义连接函数
    productWs() // 生产阶段使用
    // devWs() // 开发阶段使用
}

// 开发阶段,前端使用的本地websocket
function devWs() {
// 客户端实例
    stomp = Stomp.client('ws://localhost:61614/stomp');

    // uid来自链接
    let uid = 'uid';

    let headers = {
        login: 'mylogin',
        passcode: 'mypasscode',
        'clientId': uid
    };

    stomp.connect(headers, function (error) {
        if (error.command == "ERROR") {
            console.error(error.headers.message);
        } else {
            store.state.connectStatus = true;
        }
    });
}

// 联调、生成阶段使用的websocket
function productWs() {
    if (stomp == null || !stomp.connected) {
        // eslint-disable-next-line no-undef
        var sockJS = new SockJS(url + getToken());
        // eslint-disable-next-line no-undef
        stomp = Stomp.over(sockJS);
        stomp.debug = null;
        stomp.heartbeat.outgoing = 20000; //若使用STOMP 1.1 版本,默认开启了心跳检测机制(默认值都是10000ms)
        stomp.heartbeat.incoming = 0; //客户端不从服务端接收心跳包
        //stomp.connect({},connectCallback ,errorCallback );
        stomp.connect({},
            function connectCallback(frame) {
                // 连接成功时(服务器响应 CONNECTED 帧)的回调方法
                store.state.connectStatus = true;
                clearInterval(timer);
                console.log('已连接【' + frame + '】');
            },
            function errorCallBack(error) {
                // 连接失败时(服务器响应 ERROR 帧)的回调方法
                if (getToken()) {
                    console.log('连接失败【' + error + '】');
                    store.state.connectStatus = false;
                    setTimeout(function () {
                        //内容3秒后执行
                        connect();
                    }, 6000);
                } else {
                    destorySock();
                }
            }
        );
    } else {
        store.state.connectStatus = true
    }
}

//connect();//建立连接

//断开Socket连接
export function destorySock() {
    stomp.disconnect();
}

// 公共取消订阅
export function cancelSubcribe(name) {
    if (name === 'subVoiceWordMessage') { // 取消  实时播报内容
        publicMessage = subVoiceWordMessage
    }
    publicMessage.unsubscribe()
}

// 订阅实时播报内容
export function voiceWordMessage(region) {
    subVoiceWordMessage = stomp.subscribe("/topic/monitor/voice/" + region, function (res) {
        store.state.voiceWord = JSON.parse(res.body)
    });
}

// 取消订阅, 离开页面需要取消订阅,否则会出现多个订阅,
export function cancelVoiceWordMessage() {
    if(subVoiceWordMessage !== null) {
        subVoiceWordMessage.unsubscribe();
    }
}

}


9、vue页面添加订阅和取消订阅

添加订阅

1、mounted() 和 watch()方法中添加, watch()方法见 第 5 小节

// 导入订阅和取消订阅的方法
 import {
        cancelVoiceWordMessage,
        voiceWordMessage
    } from '@/api/socket'


 mounted() {
            this.initTrafficEvent()
        },
methods: {
						// 初始化socket连接
            initTrafficEvent() {
                if (typeof this.$store.state.region.regionCode === 'undefined') {
                    return
                }
                // 先调用取消订阅
                cancelVoiceWordMessage()
                this.regionId = this.$store.state.region.regionCode;
                if (this.$store.state.connectStatus) {
                    try {
                        // 实时播报内容
                        voiceWordMessage(this.$store.state.region.regionCode)
                    } catch (e) {
                        console.log(e);
                    }
                }
            },
}

2、离开页面时,取消订阅

destroyed() {
					// 调用取消订阅的方法
            cancelVoiceWordMessage()
        },
  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值