uniapp安卓端实现语音合成播报

07-12 1095阅读

最初尝试使用讯飞语音合成方式,能获取到语音数据,但是数据是base64格式的,在安卓端无法播放,网上有说通过转成blob格式的url可以播放,但是uniapp不支持转换的api;于是后面又想其他办法,使用安卓插件播报原生安卓语音播报插件 - DCloud 插件市场

方案一(讯飞语音合成)

1.在讯飞后台注册登录获得APPID等信息  讯飞语音合成控制台

uniapp安卓端实现语音合成播报

2.在项目根目录使用npm安装crypto-js

npm i crypto-js

3.新建xunfei.js文件,替换讯飞的APPID等3个配置

// 讯飞语音合成api文档	https://www.xfyun.cn/doc/tts/online_tts/API.html
import CryptoJS from 'crypto-js'
import {Base64} from './base64.js';
const APPID = "替换自己的APPID";
const API_SECRET = "替换自己的API_SECRET";
const API_KEY = "替换自己的API_KEY";
const URL = "wss://tts-api.xfyun.cn/v2/tts"
const HOST = "tts-api.xfyun.cn"
function getWssUrl(date) {
	date = date||(new Date().toGMTString())
	let signatureOrigin = `host: ${HOST}\ndate: ${date}\nGET /v2/tts HTTP/1.1`
	let signatureSha = CryptoJS.HmacSHA256(signatureOrigin, API_SECRET)
	let signature = CryptoJS.enc.Base64.stringify(signatureSha)
	let authorizationOrigin = `api_key="${API_KEY}", algorithm="hmac-sha256", headers="host date request-line", signature="${signature}"`
	let authStr = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(authorizationOrigin))
	return URL + "?authorization=" + authStr + "&date=" + date + "&host=" + HOST
	
}
const wssUrl=getWssUrl()
// console.log("讯飞语音合成wssUrl",wssUrl)
export const speak = (word) => {
	if (!word) {return}
	const socketTask=uni.connectSocket({
		url: wssUrl,
		success: res=> {
			console.log("讯飞websocket连接成功",res);
		},
		fail: err=> {
			console.log("讯飞websocket连接失败",err);
		},
	});
	//连接建立完毕,读取数据识别
	let buffs = ""
	socketTask.onOpen(data => {
		let params = {
			"common": {
				"app_id": APPID
			},
			"business": {
				// aue: "raw",
				aue: "lame",//mp3 (当aue=lame时需传参sfl=1)
				sfl: 1,//开启流式返回mp3格式音频
				
				auf: "audio/L16;rate=16000",
				vcn: "xiaoyan",//aisjiuxu	aisxping aisjinger aisbabyxu
				tte: "UTF8",
				speed:60,//默认50,可选0-100
				volume:80,//默认50,可选0-100
			},
			"data": {
				"text": Base64.encode(word),
				"status": 2
			}
		}
		socketTask.send({
			data:JSON.stringify(params),
			success: res=> {
				console.log("讯飞websocket发送成功",res);
			},
			fail: err=> {
				console.log("讯飞websocket发送失败",err);
			},
		})
		socketTask.onMessage(res => {
			let ds = JSON.parse(res.data)
			console.log("接收到websocket消息:",ds)
			buffs+=ds.data.audio//返回的是base64数据
			if (ds.code === 0 && ds.data.status === 2) { //status为2表示合成完成
				console.log("音频合成完成");
				toPlay();
				socketTask.close();
			}
		})
	})
	socketTask.onError(err=>{
		console.log("讯飞websocket发生错误",err);
	})
	function toPlay() {
		const base64data='data:audio/mp3;base64,' + buffs
		let audioContext = uni.createInnerAudioContext();
		audioContext.autoplay = true;
		audioContext.src = base64data
		
		audioContext.play()
		audioContext.onEnded(() => {
			console.log("播放完成");
			audioContext.destroy()
			audioContext=null
		})
		audioContext.onCanplay(() => {
			console.log("可以播放音频了");
		})
		audioContext.onPlay(() => {
		  console.log('开始播放');
		});
		audioContext.onError((res) => {
		  console.log("播放失败",res);
		});
	}
	
}

上面引入的base64.js,也可以自己npm安装base64插件

export const Base64 = {
    keyStr: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
    encode(input) {
        let output = '';
        let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        let i = 0;
        input = Base64.utf8Encode(input);
        while (i > 2;
            enc2 = ((chr1 & 3) > 4);
            enc3 = ((chr2 & 15) > 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
            output = output +
                Base64.keyStr.charAt(enc1) + Base64.keyStr.charAt(enc2) +
                Base64.keyStr.charAt(enc3) + Base64.keyStr.charAt(enc4);
        }
        return output;
    },
    decode(input) {
        let output = '';
        let chr1, chr2, chr3;
        let enc1, enc2, enc3, enc4;
        let i = 0;
        input = input.replace(/[^A-Za-z0-9+/=]/g, '');
        while (i  4);
            chr2 = ((enc2 & 15) > 2);
            chr3 = ((enc3 & 3)  127) && (c > 6) | 192);
                utfString += String.fromCharCode((c & 63) | 128);
            } else {
                utfString += String.fromCharCode((c >> 12) | 224);
                utfString += String.fromCharCode(((c >> 6) & 63) | 128);
                utfString += String.fromCharCode((c & 63) | 128);
            }
        }
        return utfString;
    },
    utf8Decode(utfString) {
        let string = '';
        let i = 0;
        let c = 0;
        let c2 = 0;
        let c3 = 0;
        while (i  191) && (c  {
        let res = JSON.parse(e);
        if (res.code == 200) {
            console.log("播报成功",res.msg);
        } else {
            console.log("播报失败",res.msg);
        }
    });
}
// #endif

后面在页面中使用语音播报api

this.$speak("上班了,打卡成功")

PS:如果设备播报没有声音需要查看设备是否安装了TTS语音引擎,没有的话可以安装微软的TTS语音引擎,安装完成之后,在 设置->文字转语音输出->首选引擎 将安装的TTS设置为首选引擎,然后打开TTS引擎 配置电池优化为允许后台持续运行

下载地址:下载地址

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]