小程式功能特點
- 文字轉語音
- 多平臺多發音人可選
- 可調語速
- 可提供音訊下載
- 良心產品無廣告?
小程式碼
已對接線上語音識別服務
小程式截圖
服務端主要程式碼
class TTSController extends Controller {
async tts () {
let params = this.ctx.query
let result = null
// 根據plat引數來呼叫不同的介面
if (params.plat === 'xf') {
result = await this.ctx.service.xftts.getTts(params)
} else if (params.plat === 'baidu') {
result = await this.ctx.service.baidutts.getTts(params)
} else {
result = await this.ctx.service.aispeechtts.getTts(params)
}
// 設定response的型別,這樣客戶端接收到的就是一個檔案流
this.ctx.response.type = 'audio/mpeg'
this.ctx.body = result
}
}
複製程式碼
小程式客戶端template程式碼(使用的mpvue)
<template>
<div class="container">
<div class="preview">
<textarea :class="textAreaFocus? 'focus' : ''"
auto-height @focus="bindTextAreaFocus"
@blur="bindTextAreaBlur" placeholder="請輸入文字"
v-model="text" maxlength="256"/>
</div>
<div class="setting">
<picker @change="bindPlatChange" v-model="platIndex" range-key="name" :range="platArr">
<div class="item">
<div class="label">選擇平臺</div>
<div class="value voice">
{{platArr[platIndex].name}}
</div>
</div>
</picker>
<picker @change="bindPickerChange" v-model="index" range-key="name" :range="array">
<div class="item">
<div class="label">選擇發音人</div>
<div class="value voice">
{{array[index].name}}
</div>
</div>
</picker>
<div class="item speed">
<div class="label">調節語速</div>
<div class="value">
<slider @change="onSpeedChange" :value="speedObj.default" :step='speedObj.step' activeColor="#6F8FFF" :min="speedObj.min" :max="speedObj.max" show-value />
</div>
</div>
</div>
<div style="height: 140rpx;">
<div class="btn-group">
<div class="item"><button @click="audioPlay" type="main">播放合成語音</button> </div>
<div class="item"> <button @click="audioDownload" type="submain">複製連結下載</button> </div>
</div>
</div>
<div class="desc">
說明:tts是英文 text to speech的縮寫,即文字轉語音技術
<contact-button
type="default-light"
session-from="weapp">聯絡客服
</contact-button>
</div>
</div>
</template>
複製程式碼
script 程式碼
<script>
import voiceIdArray from './voiceIdArray'
export default {
data () {
return {
array: voiceIdArray.aispeech,
platArr: [{id: 'xf', name: '科大訊飛'}, {id: 'aispeech', name: '思必馳'}, {id: 'baidu', name: '百度'}],
platIndex: 1,
index: 26,
text: `改革春風吹滿地,吹滿地,春風吹滿地。\n中國人民真爭氣,真爭氣,人民真爭氣。\n這個世界太瘋狂,耗子都給貓當伴娘。\n齊德隆,齊東強。\n齊德隆的咚得隆咚鏘。`,
voiceId: 'lili1f_diantai',
speed: 1,
textAreaFocus: false,
audioCtx: null,
ttsServer: 'https://tts.server.com',
audioSrc: '',
downloadUrl: '',
xfSpeedObj: {
min: 0,
max: 100,
default: 50,
step: 1
},
aispeechSpeedObj: {
min: 0.7,
max: 2,
default: 1,
step: 0.1
},
baiduSpeedObj: {
min: 0,
max: 9,
default: 5,
step: 1
},
speedObj: {}
}
},
watch: {
platIndex (newVal, oldVal) {
if (newVal === 2) {
this.array = voiceIdArray.baidu
this.index = 0
this.speedObj = this.baiduSpeedObj
}
if (newVal === 1) {
this.array = voiceIdArray.aispeech
this.index = 26
this.speedObj = this.aispeechSpeedObj
}
if (newVal === 0) {
this.array = voiceIdArray.xf
this.index = 0
this.speedObj = this.xfSpeedObj
}
}
},
onShareAppMessage () {
return {
title: '文字轉語音服務,多發音人可選'
}
},
methods: {
onSpeedChange (e) {
this.speedObj.default = e.target.value
},
bindPlatChange (e) {
this.platIndex = e.target.value * 1
},
bindPickerChange (e) {
this.index = e.target.value
},
getAudioSrc () {
if (this.text === '') {
return false
}
const speed = this.speedObj.default
const voiceId = this.array[this.index].id
const plat = this.platArr[this.platIndex].id
return encodeURI(`${this.ttsServer}/tts?plat=${plat}&voiceId=${voiceId}&speed=${speed}&text=${this.text}`)
},
getDownloadUrl () {
const plat = this.platArr[this.platIndex].id
const voiceId = this.array[this.index].id
wx.showLoading({
title: '載入中'
})
wx.request({
url: 'https://tts.server.com/getdownloadurl',
data: {
plat: plat,
voiceId: voiceId,
speed: this.speedObj.default,
text: this.text
},
header: {
'content-type': 'application/json' // 預設值
},
success (res) {
wx.hideLoading()
wx.setClipboardData({
data: res.data.short_url,
success (res) {
wx.showToast({
title: '連結已複製請用瀏覽器下載(ios端無法下載)',
icon: 'none',
duration: 3000
})
}
})
}
})
},
audioPlay () {
this.audioCtx.src = this.getAudioSrc()
if (!this.audioCtx.src) {
wx.showToast({
title: '請先輸入文字',
icon: 'none',
duration: 2000
})
return false
}
wx.showLoading({
title: '載入中'
})
this.audioCtx.play()
},
audioDownload () {
this.getDownloadUrl()
},
bindTextAreaBlur (e) {
this.textAreaFocus = false
this.text = e.target.value
},
bindTextAreaFocus () {
this.textAreaFocus = true
}
},
created () {
this.speedObj = this.aispeechSpeedObj
},
mounted () {
this.audioCtx = wx.createInnerAudioContext()
this.audioCtx.onEnded((res) => {
wx.hideLoading()
})
this.audioCtx.onPlay((res) => {
wx.hideLoading()
})
wx.showShareMenu({
withShareTicket: true
})
}
}
</script>
複製程式碼
介面對接過程中,百度的是最方便的因為有sdk可以直接使用,訊飛的最麻煩需要自己做引數加密,思必馳dui的雖然沒提供SDK但是文件寫的比較詳細對接過程也很方便快速。
目前無法解決的就是,小程式內無法直接下載的問題,只能提供連結,然後使用者自己開啟瀏覽器進行下載(iPhone似乎無解)。