在大模型应用中,有时需要将模型输出的内容使用语音播报出来。由于大模型一般是流式输出,然后服务端需要将一段段的文字转成语音再推给前端。
之前的文章中介绍过服务端给前端推送mp3格式的音频字节流。那么前端该如何处理呢?
前端是vue框架,我们可以直接使用MediaSource的sequence模式来流式播放音频。直接看代码
const audioRef = ref(null);
const sourceBuffer = ref(null)
const mediaSource = ref(null)
// 服务端推送的音频流处理
const appendVideoBlob = async (blob) => {
blobToArrayBuffer(blob)
.then(arrayBuffer => {
sourceBuffer.value.appendBuffer(new Uint8Array(arrayBuffer));
})
.catch(error => {
console.error(error);
});
}
export const blobToArrayBuffer = async (blob) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
// 当读取操作成功完成时触发
reader.onload = () => {
resolve(reader.result);
};
// 当发生错误时触发
reader.onerror = () => {
reject(new Error('Failed to read the blob as an ArrayBuffer'));
};
// 开始读取 Blob 数据作为 ArrayBuffer
reader.readAsArrayBuffer(blob);
});
}
// 播放
const startStreaming = () => {
console.warn('startStreaming')
if ('MediaSource' in window && MediaSource.isTypeSupported('audio/mpeg')) {
console.log('support mediaSource')
mediaSource.value = new MediaSource()
audioRef.value.src = URL.createObjectURL(mediaSource.value);
mediaSource.value.addEventListener('sourceopen', () => {
sourceBuffer.value = mediaSource.value.addSourceBuffer('audio/mpeg');
sourceBuffer.value.mode = 'sequence'
sourceBuffer.value.addEventListener('updateend', () => {
console.log('update end current buffers length:' + mediaSource.value.sourceBuffers.length)
if (!mediaSource.value.sourceBuffers.length) return
// Play the audio after appending the buffer
audioRef.value.play().catch(error => console.error('Play failed:', error));
});
sourceBuffer.value.addEventListener('updateend', () => {
// console.error('sourceBuffer update end')
})
mediaSource.value.addEventListener('sourceended', function () {
console.error('MediaSource ended.');
});
mediaSource.value.addEventListener('sourceclose', function () {
console.error('MediaSource closed.');
});
});
mediaSource.value.addEventListener('error', event => {
console.error('MediaSource error:', event.target.error);
});
} else {
console.error("Your browser doesn't support MediaSource API.");
}
}
除了这种方式之外,也可以使用第三方工具库,封装的更简洁,但实践中可能会遇到一些问题。直接用MediaSource来写是比较稳定兼容性良好的方式。
这样我们从前后端整个流程就可以完成大模型+语音播报功能啦,如果是数字人也差不多,音频换成视频而已。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
您必须登录才能参与评论!
立即登录

收藏了,感谢分享