Merge branch 'test' of https://git.code.tencent.com/lian-cbtc/jl-client into test
This commit is contained in:
commit
4ab68d8731
@ -8,4 +8,10 @@ export function uploadAudioFiles(file) {
|
|||||||
data: file
|
data: file
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/** 获取百度语音合成token */
|
||||||
|
export function getBaiduToken() {
|
||||||
|
return request({
|
||||||
|
url: `/api/voice/token/baidu`,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -59,11 +59,14 @@
|
|||||||
<notice-info v-if="isCtc" ref="noticeInfo" pop-class="chengdou-03__systerm" />
|
<notice-info v-if="isCtc" ref="noticeInfo" pop-class="chengdou-03__systerm" />
|
||||||
<cmdManage v-if="isCtc" ref="cmdManage" />
|
<cmdManage v-if="isCtc" ref="cmdManage" />
|
||||||
<signedCmd v-if="isCtc" ref="signedCmd" @signedCmdClose="signedCmdClose" @changeSignedStatus="changeSignedStatus" />
|
<signedCmd v-if="isCtc" ref="signedCmd" @signedCmdClose="signedCmdClose" @changeSignedStatus="changeSignedStatus" />
|
||||||
|
<div id="playBtn" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapState } from 'vuex';
|
import { mapGetters, mapState } from 'vuex';
|
||||||
|
import { btts } from '@/utils/baidu_tts_cors';
|
||||||
|
import { getBaiduToken } from '@/api/voice';
|
||||||
import MenuSignal from './menuSignal';
|
import MenuSignal from './menuSignal';
|
||||||
import MenuButton from './menuButton';
|
import MenuButton from './menuButton';
|
||||||
import MenuStationStand from './menuStationStand';
|
import MenuStationStand from './menuStationStand';
|
||||||
@ -180,7 +183,9 @@ export default {
|
|||||||
ctcBarIcon15: CtcBarIcon15,
|
ctcBarIcon15: CtcBarIcon15,
|
||||||
ctcBarIcon16: CtcBarIcon16,
|
ctcBarIcon16: CtcBarIcon16,
|
||||||
ctcBarIcon17: CtcBarIcon17,
|
ctcBarIcon17: CtcBarIcon17,
|
||||||
ctcBarIcon18: CtcBarIcon18
|
ctcBarIcon18: CtcBarIcon18,
|
||||||
|
audio: null,
|
||||||
|
voiceBroadcastToken: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -225,6 +230,14 @@ export default {
|
|||||||
if (this.isCtc) {
|
if (this.isCtc) {
|
||||||
this.getRailwaySimulationRunplanSend();
|
this.getRailwaySimulationRunplanSend();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'$store.state.socket.voiceBroadcastChange': function() {
|
||||||
|
this.$store.state.socket.voiceBroadcastMsgs.forEach(msgCode => {
|
||||||
|
const msg = this.$store.state.socket.railCtcRunplanInitMsg[msgCode];
|
||||||
|
const station = this.$store.getters['map/getDeviceByCode'](msg.arriveRunPlan.stationCode);
|
||||||
|
const text = station.name + msg.arriveRunPlan.tripNumber + '次发车预告';
|
||||||
|
this.speechSynthesis(text);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// // 地图加载完成
|
// // 地图加载完成
|
||||||
// '$store.state.map.mapViewLoadedCount': function (val) { // 地图数据加载完成
|
// '$store.state.map.mapViewLoadedCount': function (val) { // 地图数据加载完成
|
||||||
@ -265,6 +278,36 @@ export default {
|
|||||||
}).catch(()=>{
|
}).catch(()=>{
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
async speechSynthesis(text) {
|
||||||
|
if (!this.voiceBroadcastToken) {
|
||||||
|
const resp = await getBaiduToken();
|
||||||
|
this.voiceBroadcastToken = resp.data;
|
||||||
|
}
|
||||||
|
const that = this;
|
||||||
|
// 调用语音合成接口
|
||||||
|
// 参数含义请参考 https://ai.baidu.com/docs#/TTS-API/41ac79a6
|
||||||
|
this.audio = btts({
|
||||||
|
tex: text,
|
||||||
|
tok: that.voiceBroadcastToken,
|
||||||
|
spd: 5,
|
||||||
|
pit: 5,
|
||||||
|
vol: 15,
|
||||||
|
per: 4
|
||||||
|
}, {
|
||||||
|
volume: 0.3,
|
||||||
|
autoDestory: true,
|
||||||
|
timeout: 10000,
|
||||||
|
hidden: false,
|
||||||
|
onInit: function (htmlAudioElement) {},
|
||||||
|
onSuccess: function(htmlAudioElement) {
|
||||||
|
this.audio = htmlAudioElement;
|
||||||
|
this.audio.play();
|
||||||
|
// playBtn.innerText = '播放';
|
||||||
|
},
|
||||||
|
onError: function(text) { that.$message.error(text); that.voiceBroadcastToken = ''; },
|
||||||
|
onTimeout: function () { that.$message.error('合成语音超时!'); }
|
||||||
|
});
|
||||||
|
},
|
||||||
changeSignedStatus(info) {
|
changeSignedStatus(info) {
|
||||||
this.isCtc && this.$refs.cmdManage.changeSignedStatus(info);
|
this.isCtc && this.$refs.cmdManage.changeSignedStatus(info);
|
||||||
},
|
},
|
||||||
|
@ -254,6 +254,8 @@ export default {
|
|||||||
this.updateButtonShow(val, old);
|
this.updateButtonShow(val, old);
|
||||||
},
|
},
|
||||||
'$store.state.menuOperation.selectedCount': function (val) {
|
'$store.state.menuOperation.selectedCount': function (val) {
|
||||||
|
const station = this.$store.getters['map/getDeviceByCode'](this.$store.state.map.showCentralizedStationCode);
|
||||||
|
if (!station || station.controlMode === 'Interlock') { return; }
|
||||||
this.selectedChange();
|
this.selectedChange();
|
||||||
},
|
},
|
||||||
'$store.state.map.clearButtonCount': function(val) {
|
'$store.state.map.clearButtonCount': function(val) {
|
||||||
|
@ -726,6 +726,7 @@ export default {
|
|||||||
loadData() {
|
loadData() {
|
||||||
this.tableData = [];
|
this.tableData = [];
|
||||||
const railCtcRunplanInitMsg = copyAssign({}, this.$store.state.socket.railCtcRunplanInitMsg);
|
const railCtcRunplanInitMsg = copyAssign({}, this.$store.state.socket.railCtcRunplanInitMsg);
|
||||||
|
console.log(railCtcRunplanInitMsg, 'railCtcRunplanInitMsg');
|
||||||
this.tableData = Object.values(railCtcRunplanInitMsg).filter(data=>{
|
this.tableData = Object.values(railCtcRunplanInitMsg).filter(data=>{
|
||||||
if (data.departRunPlan) {
|
if (data.departRunPlan) {
|
||||||
// data.departRunPlan.planTime = this.coverTime(data.departRunPlan.planTime);
|
// data.departRunPlan.planTime = this.coverTime(data.departRunPlan.planTime);
|
||||||
@ -827,8 +828,7 @@ export default {
|
|||||||
};
|
};
|
||||||
commitOperate(menuOperate.CTC.setTransfinite, params, 3).then(({valid})=>{
|
commitOperate(menuOperate.CTC.setTransfinite, params, 3).then(({valid})=>{
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (valid) {
|
// if (valid) {}
|
||||||
}
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
@ -844,8 +844,7 @@ export default {
|
|||||||
};
|
};
|
||||||
commitOperate(menuOperate.CTC.modifyTrackSection, params, 3).then(({valid})=>{
|
commitOperate(menuOperate.CTC.modifyTrackSection, params, 3).then(({valid})=>{
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (valid) {
|
// if (valid) {}
|
||||||
}
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
@ -874,8 +873,7 @@ export default {
|
|||||||
// element.departRunPlan.sectionCode
|
// element.departRunPlan.sectionCode
|
||||||
commitOperate(menuOperate.CTC.modifyTrackSection, params, 3).then(({valid})=>{
|
commitOperate(menuOperate.CTC.modifyTrackSection, params, 3).then(({valid})=>{
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (valid) {
|
// if (valid) {}
|
||||||
}
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
|
@ -596,7 +596,7 @@ export const loginInfo = {
|
|||||||
systemType: '027'
|
systemType: '027'
|
||||||
},
|
},
|
||||||
designrichorcxjs: {
|
designrichorcxjs: {
|
||||||
title: '长兴技术学院城市轨道交通设计平台',
|
title: '长兴技师学院城市轨道交通设计平台',
|
||||||
loginPath: '/design/login?project=richorcxjs',
|
loginPath: '/design/login?project=richorcxjs',
|
||||||
bottomColumn: '中航锐创(北京)科技发展有限公司 联系电话:4000500081',
|
bottomColumn: '中航锐创(北京)科技发展有限公司 联系电话:4000500081',
|
||||||
loginParam: 'RICHOR_CXJS',
|
loginParam: 'RICHOR_CXJS',
|
||||||
@ -608,7 +608,7 @@ export const loginInfo = {
|
|||||||
systemType: '011'
|
systemType: '011'
|
||||||
},
|
},
|
||||||
richorcxjs: {
|
richorcxjs: {
|
||||||
title: '长兴技术学院城市轨道交通实训平台',
|
title: '长兴技师学院城市轨道交通实训平台',
|
||||||
loginPath: '/login?project=richorcxjs',
|
loginPath: '/login?project=richorcxjs',
|
||||||
bottomColumn: '中航锐创(北京)科技发展有限公司 联系电话:4000500081',
|
bottomColumn: '中航锐创(北京)科技发展有限公司 联系电话:4000500081',
|
||||||
loginParam: 'RICHOR_CXJS',
|
loginParam: 'RICHOR_CXJS',
|
||||||
|
@ -215,6 +215,7 @@ function handle(state, data) {
|
|||||||
// break;
|
// break;
|
||||||
// 大铁项目 ctc 运行图改变信息
|
// 大铁项目 ctc 运行图改变信息
|
||||||
case 'SIMULATION_CTC_RUN_PLAN_CHANGE':
|
case 'SIMULATION_CTC_RUN_PLAN_CHANGE':
|
||||||
|
state.voiceBroadcastMsgs = [];
|
||||||
msg.forEach(element => {
|
msg.forEach(element => {
|
||||||
const tripNumberDe = element.departRunPlan && element.departRunPlan.tripNumber;
|
const tripNumberDe = element.departRunPlan && element.departRunPlan.tripNumber;
|
||||||
const tripNumberAr = element.arriveRunPlan && element.arriveRunPlan.tripNumber;
|
const tripNumberAr = element.arriveRunPlan && element.arriveRunPlan.tripNumber;
|
||||||
@ -229,8 +230,14 @@ function handle(state, data) {
|
|||||||
parseInt(tripNumberAr[tripNumberAr.length - 1]) % 2 == 0 ? element.arriveRunPlan.up = tripNumberAr : element.arriveRunPlan.down = tripNumberAr;
|
parseInt(tripNumberAr[tripNumberAr.length - 1]) % 2 == 0 ? element.arriveRunPlan.up = tripNumberAr : element.arriveRunPlan.down = tripNumberAr;
|
||||||
}
|
}
|
||||||
const code = element.stationCode + '' + element.code;
|
const code = element.stationCode + '' + element.code;
|
||||||
|
if (store.state.training.roleDeviceCode === element.stationCode && element.arriveRunPlan && element.arriveRunPlan.adjacentMessage === '1') {
|
||||||
|
state.voiceBroadcastMsgs.push(element.stationCode + '' + element.code);
|
||||||
|
}
|
||||||
state.railCtcRunplanInitMsg[code] = copyAssign(state.railCtcRunplanInitMsg[code] || {}, element);
|
state.railCtcRunplanInitMsg[code] = copyAssign(state.railCtcRunplanInitMsg[code] || {}, element);
|
||||||
});
|
});
|
||||||
|
if (state.voiceBroadcastMsgs.length) {
|
||||||
|
state.voiceBroadcastChange++;
|
||||||
|
}
|
||||||
state.railCtcRunplanChange++;
|
state.railCtcRunplanChange++;
|
||||||
break;
|
break;
|
||||||
// 大铁项目 ctc 调度发布行车计划 给车站下发消息
|
// 大铁项目 ctc 调度发布行车计划 给车站下发消息
|
||||||
@ -460,7 +467,9 @@ const socket = {
|
|||||||
railCtcStationManageRpMsg:{}, // 大铁项目 ctc 车务管理 端运行图信息
|
railCtcStationManageRpMsg:{}, // 大铁项目 ctc 车务管理 端运行图信息
|
||||||
railCtcStationManageRpChange:0, // 大铁项目 ctc 车务管理 运行图信息变化
|
railCtcStationManageRpChange:0, // 大铁项目 ctc 车务管理 运行图信息变化
|
||||||
railwaySimulationRunplanSendMap:{}, // 大铁项目 调度台 发布 行车计划
|
railwaySimulationRunplanSendMap:{}, // 大铁项目 调度台 发布 行车计划
|
||||||
railwaySimulationRunplanSendChange:0 // 大铁项目 调度台 发布 行车计划变化
|
railwaySimulationRunplanSendChange:0, // 大铁项目 调度台 发布 行车计划变化
|
||||||
|
voiceBroadcastMsgs: [], // 语音播报信息
|
||||||
|
voiceBroadcastChange: 0 // 语音播报信息变化
|
||||||
// railwaySimulationRpMsg:{}, // 大铁项目 调度台 调度台
|
// railwaySimulationRpMsg:{}, // 大铁项目 调度台 调度台
|
||||||
// railwaySimulationRpChange:0 // 大铁项目 调度台 运行图信息变化
|
// railwaySimulationRpChange:0 // 大铁项目 调度台 运行图信息变化
|
||||||
},
|
},
|
||||||
|
118
src/utils/baidu_tts_cors.js
Normal file
118
src/utils/baidu_tts_cors.js
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/**
|
||||||
|
* 浏览器调用语音合成接口
|
||||||
|
* @param {Object} param 百度语音合成接口参数
|
||||||
|
* 请参考 https://ai.baidu.com/docs#/TTS-API/41ac79a6
|
||||||
|
* @param {Object} options 跨域调用api参数
|
||||||
|
* timeout {number} 超时时间 默认不设置为60秒
|
||||||
|
* volume {number} audio控件音量,范围 0-1
|
||||||
|
* hidden {boolean} 是否隐藏audio控件
|
||||||
|
* autoDestory {boolean} 播放音频完毕后是否自动删除控件
|
||||||
|
* onInit {Function} 创建完audio控件后调用
|
||||||
|
* onSuccess {Function} 远程语音合成完成,并且返回音频文件后调用
|
||||||
|
* onError {Function} 远程语音合成完成,并且返回错误字符串后调用
|
||||||
|
* onTimeout {Function} 超时后调用,默认超时时间为60秒
|
||||||
|
*/
|
||||||
|
export function btts(param, options) {
|
||||||
|
var url = 'http://tsn.baidu.com/text2audio';
|
||||||
|
var opt = options || {};
|
||||||
|
var p = param || {};
|
||||||
|
|
||||||
|
// 如果浏览器支持,可以设置autoplay,但是不能兼容所有浏览器
|
||||||
|
var audio = document.createElement('audio');
|
||||||
|
if (opt.autoplay) {
|
||||||
|
audio.setAttribute('autoplay', 'autoplay');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐藏控制栏
|
||||||
|
if (!opt.hidden) {
|
||||||
|
audio.setAttribute('controls', 'controls');
|
||||||
|
} else {
|
||||||
|
audio.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置音量
|
||||||
|
if (typeof opt.volume !== 'undefined') {
|
||||||
|
audio.volume = opt.volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用onInit回调
|
||||||
|
isFunction(opt.onInit) && opt.onInit(audio);
|
||||||
|
|
||||||
|
// 默认超时时间60秒
|
||||||
|
var DEFAULT_TIMEOUT = 60000;
|
||||||
|
var timeout = opt.timeout || DEFAULT_TIMEOUT;
|
||||||
|
|
||||||
|
// 创建XMLHttpRequest对象
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', url);
|
||||||
|
|
||||||
|
// 创建form参数
|
||||||
|
var data = {};
|
||||||
|
for (var p in param) {
|
||||||
|
data[p] = param[p]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 赋值预定义参数
|
||||||
|
data.cuid = data.cuid || data.tok;
|
||||||
|
data.ctp = 1;
|
||||||
|
data.lan = data.lan || 'zh';
|
||||||
|
data.aue = data.aue || 3;
|
||||||
|
|
||||||
|
// 序列化参数列表
|
||||||
|
var fd = [];
|
||||||
|
for(var k in data) {
|
||||||
|
fd.push(k + '=' + encodeURIComponent(data[k]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用来处理blob数据
|
||||||
|
var frd = new FileReader();
|
||||||
|
xhr.responseType = 'blob';
|
||||||
|
xhr.send(fd.join('&'));
|
||||||
|
|
||||||
|
// 用timeout可以更兼容的处理兼容超时
|
||||||
|
var timer = setTimeout(function(){
|
||||||
|
xhr.abort();
|
||||||
|
isFunction(opt.onTimeout) && opt.onTimeout();
|
||||||
|
}, timeout);
|
||||||
|
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState == 4) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
if (xhr.status == 200) {
|
||||||
|
if (xhr.response.type === 'audio/mp3') {
|
||||||
|
|
||||||
|
// 在body元素下apppend音频控件
|
||||||
|
document.body.appendChild(audio);
|
||||||
|
|
||||||
|
audio.setAttribute('src', URL.createObjectURL(xhr.response));
|
||||||
|
|
||||||
|
// autoDestory设置则播放完后移除audio的dom对象
|
||||||
|
if (opt.autoDestory) {
|
||||||
|
audio.onended = function() {
|
||||||
|
document.body.removeChild(audio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isFunction(opt.onSuccess) && opt.onSuccess(audio);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用来处理错误
|
||||||
|
if (xhr.response.type === 'application/json') {
|
||||||
|
frd.onload = function(){
|
||||||
|
var text = frd.result;
|
||||||
|
isFunction(opt.onError) && opt.onError(text);
|
||||||
|
};
|
||||||
|
frd.readAsText(xhr.response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否是函数
|
||||||
|
function isFunction(obj) {
|
||||||
|
if (Object.prototype.toString.call(obj) === '[object Function]') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user