vue页面实现语音播报
- 1、vue页面添加鼠标滑动事件
- 2、data中定义是否已经开启了语音播报
- 3、监听用户鼠标移入事件
- 4、voicePlay()方法,使用的是百度的tts
- 5、 watch监听后台推送的数据
- 6、store中定义的 voiceWord
- 7、语音播报的方法voicePlayMethod
- 8、socket中添加订阅的方法
- 9、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"
></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()
},