皇冠新体育APP

IT技术之家

微信小程序实现讯飞语音合成

上架耗时:2023-08-25 16:17:48 小程序 49次 标签:微信小程序 语音识别 小程序
参考文档:语音合成(流式版)WebAPI 文档微信小程序背景音频播报可参考:uniapp实现微信小程序websocket+背景音频语音播报实现步骤注册讯飞账号,完成实名认证,获取应用appid 连接讯飞websocket,在握手阶段,请求方需要对请求进行签名 发送请求文本,讯飞服务器返回合成后的音频片段,采用base64编码 将返回的音频片段组合,并转成可播放的MP3文件1.注册账号,并获取应用appid打开官网网址:讯飞开放平台-语音合成点击免费试用,按步骤完成实名认证后得....

基准文本:录音生成(流式细胞术版)WebAPI 文本 qq小软件小系统软件的游戏背景声频报时可参看:uniapp做到qq小软件小系统软件websocket+的游戏背景声频qq语音报时 达成工作步骤

    注册讯飞账号,完成实名认证,获取应用appid连接讯飞websocket,在握手阶段,请求方需要对请求进行签名发送请求文本,讯飞服务器返回合成后的音频片段,采用base64编码将返回的音频片段组合,并转成可播放的MP3文件

1.注册账号,并获取应用appid

弹框官方网站网页:讯飞开发的平台-录音合并?弹框兔费免费体验,按步奏做好微信实名认真后得出appid

?2.连接讯飞websocket,在握手阶段,请求方需要对请求进行签名

async getWebsocketUrl() {
		// 合成讯飞语音请求地址
		const that = this;
		return await new Promise((resolve, reject) => {
			var apiKey = API_KEY; // 讯飞控制台查看
			var apiSecret = API_SECRET; // 讯飞控制台查看
			var url = 'wss://tts-api.xfyun.cn/v2/tts';
			var host = BASEURL; // 请求的主机地址
			var date = new Date().toGMTString();
			var algorithm = 'hmac-sha256';
			var headers = 'host date request-line';
			var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/tts HTTP/1.1`;
			var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret);
			var signature = CryptoJS.enc.Base64.stringify(signatureSha);
			var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
			var authorization = that.base64_encode(authorizationOrigin);
			url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;
			resolve(url);
		});
	}
	async linkXunfeiSocket() {
		// 连接讯飞Socket服务器
		let url = await this.getWebsocketUrl();
		let XunfeiSocketTask;
		await new Promise((resolve, reject) => {
			XunfeiSocketTask = uni.connectSocket({
				url: encodeURI(url),
				header: {
					'content-type': 'application/json'
				},
				success: () => {
					console.log(`讯飞 connect成功`);
					resolve();
				},
				fail: () => {
					console.log('讯飞 connect失败');
					reject();
				}
			});
		});
		this.xunfeiSocketTask = XunfeiSocketTask;
		this.initXunFei(this.xunfeiSocketTask);
	}
	initXunFei(xunfeiSocketTask) {
		// 监听消息
		xunfeiSocketTask.onMessage(res => {
			// console.log('接收讯飞消息');
			this.result(res.data);
		});
		xunfeiSocketTask.onOpen(() => {
			// console.log('讯飞websocket打开');
			this.webSocketSend();
		});
		xunfeiSocketTask.onClose(res => {
			clearTimeout(this.playTimeout);
			// console.error('讯飞断开');
		});
		xunfeiSocketTask.onError(err => {
			// console.error('讯飞连接错误', err);
		});
	}

注意:

(1)signature_sha:hmac-sha256百度算法紧密结合apiSecret对signature_origin签字,选用crypto-js达成
// 安装
npm install crypto-js
yarn add crypto-js

// 引用
import CryptoJS from 'crypto-js';
(2)signature:需运行CryptoJS.enc.Base64.stringify()方式编号后运行 (3)authorization:还要base64打码后运用,打码玩法有以下(共同于Window.btoa())
	base64_encode(str) {
		// 编码,配合encodeURIComponent使用
		var c1, c2, c3;
		var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
		var i = 0,
			len = str.length,
			strin = '';
		while (i < len) {
			c1 = str.charCodeAt(i++) & 0xff;
			if (i == len) {
				strin += base64EncodeChars.charAt(c1 >> 2);
				strin += base64EncodeChars.charAt((c1 & 0x3) << 4);
				strin += '==';
				break;
			}
			c2 = str.charCodeAt(i++);
			if (i == len) {
				strin += base64EncodeChars.charAt(c1 >> 2);
				strin += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4));
				strin += base64EncodeChars.charAt((c2 & 0xf) << 2);
				strin += '=';
				break;
			}
			c3 = str.charCodeAt(i++);
			strin += base64EncodeChars.charAt(c1 >> 2);
			strin += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4));
			strin += base64EncodeChars.charAt(((c2 & 0xf) << 2) | ((c3 & 0xc0) >> 6));
			strin += base64EncodeChars.charAt(c3 & 0x3f);
		}
		return strin;
	}

3.发送和接收数据

发邮箱word文档信息
webSocketSend() {
		let params = {
			common: {
				app_id: APPID // 讯飞控制台查看
			},
			business: {
				aue: 'lame', // 音频编码表示mp3格式,当aue=lame时需传参sfl=1
				sfl: 1,
				vcn: 'xiaoyan', // 发音人选择
				tte: 'UTF8'
			},
			data: {
				status: 2,
				text: CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(this.toAudioText))
			}
		};

		this.xunfeiSocketTask.send({
			data: JSON.stringify(params),
			success: res => {
				// console.log('发出讯飞消息');
			},
			fail: err => {
				// console.log('发出讯飞消息失败', err);
			}
		});
	}

注意:

(1)发的word文档统计资料data的text需求在使用base64编码查询 (2)send的方式发邮箱的统计资料需要转成json标识符串 (3)回的数据源为组成后的语音场面描写,采取base64简码

?4. 将返回的音频片段组合,并转成可播放的MP3文件

当code为0,data.status为1时,表现归并为中,将base64空格符串归并为 当code为0,data.status为2时,带表两句话并到提交,在这儿将并到的base64转成音頻文件名
	result(resultData) {
		let jsonData = JSON.parse(resultData);
        //陆续合并接收的base64音频流 
		this.audioBase64 += jsonData.data.audio;
		if (jsonData.code !== 0) {
            // 合成失败
			console.log(`${jsonData.code}:${jsonData.message}`);
			return;
		}
		if (jsonData.code === 0 && jsonData.data.status === 2) {
			// 分段发送完成,转成语音文件关闭连接
            // 注意:将base64转化成ArrayBuffer
			const data = uni.base64ToArrayBuffer(this.audioBase64);
			const target = `${wx.env.USER_DATA_PATH}/${new Date().getTime()}.mp3`;
			try {
                // 使用fs.writeFileSync完成音频文件的转化
				const res = fs.writeFileSync(target, data, 'binary');
				this.playAudio.push(target);
				this.xunfeiSocketTask.close();
				this.audioBase64 = '';
			} catch (e) {
				console.error(e);
			}
		}
	}

注意:使用fs.writeFileSync转文件时,传入的data为ArrayBuffer格式