最近在做一个小程序接入腾讯云语音合成的功能,目的是将文本转换为语音并播放。调用腾讯云服务后会返回给我们一个arraybuffer流数据,并不是一个直接可供播放的音频地址,那么在小程序端我们又如何进行转换最终获取到一个临时地址并播放呢?
请看如下代码:
//创建媒体控制对象
const audioContext = wx.createInnerAudioContext();
wx.request({
method: "POST",
url: "https://tts.cloud.tencent.com/stream",
header: {
"Content-Type": "application/json",
Authorization: Signature,
},
responseType: "arraybuffer", // 设置响应类型为 arraybuffer
data: params,
success(res) {
// 获取到响应的二进制数据
const arrayBuffer = res.data;
// 将 arrayBuffer 转为 base64 字符串
const base64String = wx.arrayBufferToBase64(arrayBuffer);
// 将 base64 字符串转为文件
const filePath = `${wx.env.USER_DATA_PATH}/${message.id}.mp3`;
wx.getFileSystemManager().writeFile({
filePath,
data: base64String,
encoding: "base64",
success(e) {
audioContext.src = filePath;
audioContext.play();
// 可以使用 filePath 进行后续操作,如播放音频或显示图像等
},
fail(error) {
console.error("文件保存失败", error);
},
});
},
fail(error) {
console.error("网络请求失败", error);
},
});
此时肯定有小伙伴问,h5中又是如何实现呢,这里我也做了相关拓展,代码如下,需要的朋友可以看一看,仅供大家参考:
export async function TextToStreamAudio(data: any) {
const { Signature, params } = V1(ttsconfig.TextToStreamAudio, data);
const fetchRes = await fetch(`https://tts.cloud.tencent.com/stream`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: Signature,
},
body: JSON.stringify(params),
});
const res = await fetchRes.arrayBuffer();
return parseArrayBuffer(res);
}
export function parseArrayBuffer(buffer: ArrayBuffer) {
const uint8Array = new Uint8Array(buffer);
// 使用btoa()函数将Uint8Array转换为Base64编码的字符串
const base64String = btoa(String.fromCharCode.apply(null, uint8Array));
// 将Base64字符串转换为二进制数据
const binaryString = atob(base64String);
// 将二进制数据转换为ArrayBuffer
const arrayBuffer = new ArrayBuffer(binaryString.length);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < binaryString.length; i++) {
view[i] = binaryString.charCodeAt(i);
}
// 使用适当的MIME类型(audio/wav)从ArrayBuffer创建Blob 注意这里的类型取决于你的音频类型
const blob = new Blob([arrayBuffer], { type: "audio/wav" });
return URL.createObjectURL(blob);
}