参考:
https://segmentfault.com/q/1010000038841873
关键代码:
<el-button type="primary" @click="importText">导入文本</el-button>
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) }) },
完整代码:
<template>
<div class="box">
<!-- 语音合成页面-->
<!-- 1,合成文字内容-->
<div class="composite-text-content">
<div class="top-box">
<el-row>
<el-col :span="16" 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-col :span="4" class="col3">
<div class="grid-content bg-purple-light" style="text-align: center">
<el-button type="primary" v-if="isEditable"
@click="isEditable=!isEditable"
>编辑内容
</el-button>
<el-button type="primary" v-else @click="isEditable=!isEditable">保存</el-button>
</div>
</el-col>
</el-row>
</div>
<div class="line"></div>
<div class="bottom-box">
<el-input
v-if="!isEditable"
type="textarea"
:rows="15"
placeholder="请输入内容" class="voice-content-input"
v-model="query.voiceContent"
maxlength="2000"
show-word-limit
>
</el-input>
<p v-else>{{ query.voiceContent }}</p>
</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
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"
show-input
>
</el-slider>
</div>
</el-col>
<el-col :span="4" class="col7">
<div class="grid-content bg-purple">
<el-button type="primary" @click="synthesis">立即合成</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
radio: '1',
isEditable: false,
query: {
people: '60020',
speed: 0,
intonation: 0,
voiceContent: ''
}
}
},
mounted() {
},
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() {
console.log(this)
voiceSynthesis(this.query).then(response => {
console.log(response.data)
var newUrl = response.data
this.voiceSrc = newUrl + ''
})
}
}
}
</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>
效果图: