遇到的问题:
在给
voiceContent赋值的时候。this指向不对,所以在之前用_this保存this的值,在$nextTick(()里面操作更新dom才能实时刷新
参考:
https://segmentfault.com/q/1010000038702128
https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader
关键代码:
<input type="file" class="file"/>
<el-button type="primary" @click="readFile">导入文本</el-button>
readFile() {
let fileSelect = document.querySelector('input[type=file]').files[0]//找到文件上传的元素
let reader = new FileReader()
if (typeof FileReader === 'undefined') {
console.log('您的浏览器不支持FileReader接口')
return
}
reader.readAsText(fileSelect, 'gb2312')//注意读取中文的是用这个编码,不是utf-8
const _this = this
reader.onload = function() {
// console.log(reader.result)
_this.$nextTick(() => {
_this.voiceContent = reader.result
// console.log(_this.voiceContent)
})
}
console.log(reader)
}
效果:
完整代码:
<template>
<div class="box">
<!-- 语音合成页面-->
<!-- 1,合成文字内容-->
<div class="composite-text-content">
<div class="top-box">
<el-row>
<el-col :span="20" class="col1">
<div class="grid-content bg-purple"><h3>合成文字内容</h3></div>
</el-col>
<el-col :span="4">
<div class="grid-content bg-purple-light" style="text-align: center">
<el-button type="primary" @click="importText">导入文本</el-button>
</div>
</el-col>
</el-row>
</div>
<div class="line"></div>
<div class="bottom-box">
<el-input
type="textarea"
:rows="15"
placeholder="请输入内容" class="voice-content-input"
v-model="query.voiceContent"
maxlength="2000"
show-word-limit
>
</el-input>
</div>
</div>
<!-- 2,发声人-->
<div class="sound-adjustment">
<el-row>
<el-col :span="2" class="col1">
<div class="grid-content bg-purple" style="">发声人</div>
</el-col>
<el-col :span="2" class="col2">
<el-radio-group v-model="query.people">
<div>
<el-radio v-model="radio" label="60020">女声</el-radio>
</div>
<div>
<el-radio v-model="radio" label="60030">男声</el-radio>
</div>
</el-radio-group>
</el-col>
<el-col :span="2" class="col3">
<div class="grid-content bg-purple">语速</div>
<div class="grid-content bg-purple">-500~500</div>
</el-col>
<el-col :span="6" class="col4">
<div>
<el-slider
v-model="query.speed"
show-input
:min="-500"
:max="500"
style="line-height: 100px;"
>
</el-slider>
</div>
</el-col>
<el-col :span="2" class="col5">
<div class="grid-content bg-purple">语调</div>
<div class="grid-content bg-purple">-500~500</div>
</el-col>
<el-col :span="6" class="col6">
<div>
<el-slider
v-model="query.intonation"
:min="-500"
:max="500"
show-input
>
</el-slider>
</div>
</el-col>
<el-col :span="2" class="col7">
<div class="grid-content bg-purple">
<el-button type="primary" @click="synthesis">合成</el-button>
</div>
</el-col>
<el-col :span="2" class="col7">
<div class="grid-content bg-purple">
<el-button type="primary" @click="saveSynthesis">保存</el-button>
</div>
</el-col>
</el-row>
</div>
<!-- 3,试听合成语音-->
<div class="listening-box">
<div class="top-box">
<h3>试听合成语音</h3>
</div>
<!-- 声波-->
<div class="acoustic-wave-box">
<my-wave-surfer :voiceSrc="voiceSrc"/>
</div>
</div>
</div>
</template>
<script>
import myWaveSurfer from '@/components/MyWaveSurfer/index'
import {
voiceSynthesis
} from '@/api/web/voiceSynthesisLog'
export default {
name: 'speechSynthesis',
components: {
myWaveSurfer
},
data() {
return {
// voiceSrc: require('../../../assets/当真-曲肖冰&蒋家驹(蒋蒋).mp3'),//音频url
voiceSrc: 'http://192.168.3.174:8081/profile/tempSynthesisVoice/test.mp3',//音频url
// voiceSrc: 'http://192.168.3.174:8081/profile/uploadPath/tempSynthesisVoice/1609838363078.mp3',//音频url
radio: '1',
newUrl: '',
query: {
people: '60020',
speed: 0,
intonation: 0,
voiceContent: ''
}
}
},
watch:{
// voiceSrc(val,newval){
// console.log(val)
// console.log(newval)
// }
},
mounted() {
console.log(this.newUrl==='')
},
methods: {
importText() {
const input = document.createElement('input')
input.type = 'file'
input.accept = '.txt'
input.click()
input.addEventListener('input', ($e) => {
const fileSelect = $e.target.files[0]
// 处理文件逻辑
let reader = new FileReader()
if (typeof FileReader === 'undefined') {
console.log('您的浏览器不支持FileReader接口')
return
}
reader.readAsText(fileSelect, 'gb2312')//注意读取中文的是用这个编码,不是utf-8
const _this = this
reader.onload = function() {
// console.log(reader.result)
_this.$nextTick(() => {
_this.query.voiceContent = reader.result
// console.log(_this.query.voiceContent)
})
}
console.log(reader)
})
},
//读取文件
readFile() {
let fileSelect = document.querySelector('input[type=file]').files[0]//找到文件上传的元素
let reader = new FileReader()
if (typeof FileReader === 'undefined') {
console.log('您的浏览器不支持FileReader接口')
return
}
reader.readAsText(fileSelect, 'gb2312')//注意读取中文的是用这个编码,不是utf-8
const _this = this
reader.onload = function() {
// console.log(reader.result)
_this.$nextTick(() => {
_this.query.voiceContent = reader.result
// console.log(_this.query.voiceContent)
})
}
console.log(reader)
},
//合成
synthesis() {
if(this.query.voiceContent == ''){
this.$message({
message: '内容不能为空',
type: 'error'
});
return;
}
this.query.isSave = '0'
voiceSynthesis(this.query).then(response => {
var newUrl = response.data
this.voiceSrc = newUrl + ''
this.$message({
message: '语音合成成功',
type: 'success'
});
})
},
//保存
saveSynthesis() {
if(this.query.voiceContent == ''){
this.$message({
message: '内容不能为空',
type: 'error'
});
return;
}
this.query.isSave = '1'
voiceSynthesis(this.query).then(response => {
var newUrl = response.data
this.voiceSrc = newUrl + ''
this.$message({
message: '保存成功',
type: 'success'
});
})
}
}
}
</script>
<style lang="scss" scoped>
//公用样式
.el-row {
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
.el-col {
border-radius: 4px;
}
.bg-purple-dark {
background: #99a9bf;
}
.bg-purple {
background: white;
//background: lightcoral;
}
.bg-purple-light {
background: white;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.row-bg {
padding: 10px 0;
background-color: #f9fafc;
}
.box {
//background-color: lightskyblue;
margin: 30px 20px;
min-width: 990px;
.composite-text-content {
border: 1px solid gray;
border-radius: 10px;
margin: 30px 0;
.top-box {
line-height: 50px;
border-radius: 10px 10px 0 0;
.col1 {
padding: 0 20px;
div {
border-radius: 10px 0 0 0;
}
}
.col3 {
div {
border-radius: 0 10px 0 0;
}
}
h3 {
margin: 0;
}
}
.line {
height: 1px;
width: 100%;
background-color: gray;
}
.bottom-box {
width: 100%;
max-height: 332px;
min-height: 200px;
p {
margin: 0;
}
}
}
.sound-adjustment {
margin: 30px auto;
border: 1px solid gray;
border-radius: 10px;
height: 100%;
text-align: center;
line-height: 100px;
.col1 {
border-radius: 10px 0 0 10px;
div {
border-radius: 10px 0 0 10px;
}
}
.col2 {
border-left: 1px solid gray;
border-right: 1px solid gray;
border-radius: 0;
div {
line-height: 50px;
}
}
.col3, .col5 {
div {
line-height: 50px;
}
}
.col4 {
height: 100px;
div {
margin: 31px 0;
}
}
.col6 {
height: 100px;
div {
margin: 31px 0;
}
}
.col7 {
border-radius: 0 10px 10px 0;
background-color: lightcoral;
div {
border-radius: 0 10px 10px 0;
//background-color: lightcoral;
}
}
}
.listening-box {
border: 1px solid gray;
border-radius: 10px;
.top-box {
line-height: 50px;
padding: 0 20px;
h3 {
margin: 0;
}
}
.acoustic-wave-box {
height: 100%;
width: 100%;
border-top: 1px solid gray;
//background-color: lightseagreen;
}
}
}
</style>