149 lines
3.3 KiB
Vue
149 lines
3.3 KiB
Vue
<template>
|
|
<div>
|
|
<div class="AiTransSpeech" v-if="!noSpeech">
|
|
<button title="语音播报" @click="getSpeech">
|
|
<div>
|
|
<div class="iconfont" :class="{playing:loading}"></div>
|
|
</div>
|
|
<div>{{ text }}</div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: "AiTransSpeech",
|
|
props: {
|
|
src: String,
|
|
content: String
|
|
},
|
|
data() {
|
|
return {
|
|
audioContext: null,
|
|
speech: "",
|
|
loading: false,
|
|
text: "开始"
|
|
}
|
|
},
|
|
computed: {
|
|
speechString() {
|
|
return this.content ? this.content.replace(/<\/?.+?\/?>/g, "") : ""
|
|
},
|
|
noSpeech() {
|
|
return !this.src && !this.content
|
|
}
|
|
},
|
|
methods: {
|
|
getSpeech() {
|
|
if (!this.noSpeech) {
|
|
if (this.audioContext) {
|
|
if (this.loading) {
|
|
this.loading = false
|
|
this.audioContext.pause()
|
|
} else {
|
|
this.loading = true
|
|
this.audioContext.play()
|
|
}
|
|
} else if (this.content) {
|
|
this.loading = true
|
|
if (!this.speech) {
|
|
this.$instance.post("/app/msc/transToSpeech" + `?fileName=demo&words=${this.speechString}`).then(res => {
|
|
if (res && res.data) {
|
|
let url = res.data.join("")
|
|
this.speech = url.substring(0, url.indexOf(";"))
|
|
this.playAudio()
|
|
}
|
|
}).catch(() => this.loading = false)
|
|
} else {
|
|
this.playAudio()
|
|
}
|
|
} else if (this.src) {
|
|
this.loading = true
|
|
this.speech = this.src
|
|
this.playAudio()
|
|
}
|
|
}
|
|
},
|
|
playAudio() {
|
|
let _ = this
|
|
this.audioContext = uni.createInnerAudioContext();
|
|
this.audioContext.src = this.speech;
|
|
this.audioContext.play()
|
|
this.audioContext.onPlay(() => {
|
|
_.text = "暂停"
|
|
});
|
|
this.audioContext.onPause(() => {
|
|
_.loading = false
|
|
_.text = "开始"
|
|
});
|
|
this.audioContext.onEnded(() => {
|
|
_.loading = false
|
|
_.text = "开始"
|
|
});
|
|
this.audioContext.onError((res) => {
|
|
console.error(res.errMsg);
|
|
_.text = "开始"
|
|
});
|
|
},
|
|
},
|
|
destroyed() {
|
|
if (this.audioContext) {
|
|
this.audioContext.pause()
|
|
this.audioContext.destroy()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.AiTransSpeech {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
button {
|
|
position: fixed;
|
|
right: 80px;
|
|
bottom: 150px;
|
|
width: 104px;
|
|
height: 104px;
|
|
background: linear-gradient(130deg, rgba(70, 192, 253, 1) 0%, rgba(37, 158, 249, 1) 57%, rgba(39, 148, 248, 1) 100%);
|
|
border-radius: 50%;
|
|
font-size: 24px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #fff !important;
|
|
z-index: 10000;
|
|
|
|
& > div {
|
|
width: 48px;
|
|
white-space: nowrap;
|
|
line-height: normal;
|
|
|
|
.iconfont {
|
|
width: 48px;
|
|
font-size: 48px;
|
|
line-height: 48px;
|
|
overflow: hidden;
|
|
|
|
&.playing {
|
|
animation: playingSpeech .5s infinite;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@keyframes playingSpeech {
|
|
from {
|
|
width: 30px
|
|
}
|
|
to {
|
|
width: 100%
|
|
}
|
|
}
|
|
}
|
|
</style>
|