Javascript 如何使用HTML5音频API播放从XMLHTTPRequest返回的音频
在向服务器端api发出“AJAX”请求时,我无法播放音频 我有一个backend Node.js代码,它使用IBM的Watson文本到语音服务提供文本音频:Javascript 如何使用HTML5音频API播放从XMLHTTPRequest返回的音频,javascript,node.js,html5-audio,text-to-speech,ibm-watson,Javascript,Node.js,Html5 Audio,Text To Speech,Ibm Watson,在向服务器端api发出“AJAX”请求时,我无法播放音频 我有一个backend Node.js代码,它使用IBM的Watson文本到语音服务提供文本音频: var render=函数(请求、响应){ 变量选项={ text:request.params.text, 声音:“VoiceNusmichael”, 接受:“音频/ogg;编解码器=作品” }; 合成器和接收器(选项、请求、响应); }; var synthezeandender=功能(选项、请求、响应){ var synthezeds
var render=函数(请求、响应){
变量选项={
text:request.params.text,
声音:“VoiceNusmichael”,
接受:“音频/ogg;编解码器=作品”
};
合成器和接收器(选项、请求、响应);
};
var synthezeandender=功能(选项、请求、响应){
var synthezedspeech=textToSpeech.synthesis(选项);
合成语音开启('response',函数(eventResponse){
if(request.params.text.download){
var contentDisposition='attachment;filename=transcript.ogg';
eventResponse.headers['content-disposition']=contentDisposition;
}
});
综合语音管道(响应);
};
我有客户端代码来处理这个问题:
var xhr=new XMLHttpRequest(),
audioContext=新的audioContext(),
source=audioContext.createBufferSource();
module.controllers.TextToSpeechController={
fetch:function(){
xhr.onload=函数(){
var playAudio=功能(缓冲区){
source.buffer=缓冲区;
source.connect(audioContext.destination);
source.start(0);
};
//TODO:正确处理(exiquio)
//注意:收到错误消息
var handleError=函数(错误){
log('发生音频解码错误');
}
音频语境
.解码音频数据(xhr.response、playAudio、handleError);
};
xhr.onerror=function(){console.log('发生错误');};
var urlBase=http://localhost:3001/api/v1/text_to_speech/';
变量url=[
urlBase,
"测试",,
].加入(“”);
open('GET',encodeURI(url),true);
xhr.setRequestHeader('x-access-token',Application.token);
xhr.responseType='arraybuffer';
xhr.send();
}
}
后端返回我期望的音频,但从未调用我的成功方法playAudio。相反,总是调用handleError,并且错误对象总是null
有人能解释一下我做错了什么,以及如何纠正吗?我们将不胜感激
谢谢
注意:URL中的字符串“test”在后端成为一个文本参数,并在SynthesizeAndender中的选项变量中结束。不幸的是,与Chrome的HTML5音频实现不同,Chrome的Web音频是您的请求在此处使用的。您需要将格式设置为
audio/wav
,才能工作。为了确保它被传递到服务器请求,我建议将它放在查询字符串中(accept=audio/wav
,urlencoded)
您只是想播放音频,还是需要访问Web音频API进行音频转换?如果您只需要播放音频,我可以向您展示如何使用HTML5音频API(而不是Web音频API)轻松播放。使用HTML5音频,您可以使用下面的技术对其进行流式处理,并且可以使用最佳的音频/ogg;编解码器=opus
格式
它非常简单,只需动态设置音频元素的源,通过以下方式从DOM查询:
(HTML格式)
您还可以通过XMLHttpRequest设置音频元素的源,但无法获得流式处理。但是,由于可以使用POST方法,因此GET请求的文本长度不受限制(对于此API,~6KB)。要在xhr中进行设置,需要从blob响应创建一个数据uri:
xhr.open('POST', encodeURI(url), true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'blob';
xhr.onload = function(evt) {
var blob = new Blob([xhr.response], {type: 'audio/ogg'});
var objectUrl = URL.createObjectURL(blob);
audio.src = objectUrl;
// Release resource when it's loaded
audio.onload = function(evt) {
URL.revokeObjectURL(objectUrl);
};
audio.play();
};
var data = JSON.stringify({text: yourTextToSynthesize});
xhr.send(data);
如您所见,使用XMLHttpRequest时,必须等到数据完全加载后才能播放。可能有一种方法可以使用最新的媒体源扩展API从XMLHttpRequest流式传输,该API目前仅在Chrome和IE中可用(没有Firefox或Safari)。这是我目前正在试验的一种方法。如果成功,我将在此更新。您确定音频格式受支持吗?我相信它一定受支持。我最初通过一个url直接用同一个Chrome浏览器测试了相同的后端代码,它可以正常运行。实际上,测试是在Chrome和Gnu/Linux上完成的。我相信这应该和我现在正在编写代码的OSX中的Chrome一样,但我不确定。更新:我在开发此代码时使用的浏览器中运行了folliwing查询:Eric回答了我的问题,说明了兼容性和与Chromium问题的链接,并详细阐述了可能的解决方法,非常感谢。我在过去两天里一直在努力。顺便说一句,你可以看看这个AAC格式在所有浏览器中都能工作。你不局限于使用WAV(它是巨大的)。
var audio = document.getElementById('myAudioElement') || new Audio();
audio.src = yourUrl;
xhr.open('POST', encodeURI(url), true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'blob';
xhr.onload = function(evt) {
var blob = new Blob([xhr.response], {type: 'audio/ogg'});
var objectUrl = URL.createObjectURL(blob);
audio.src = objectUrl;
// Release resource when it's loaded
audio.onload = function(evt) {
URL.revokeObjectURL(objectUrl);
};
audio.play();
};
var data = JSON.stringify({text: yourTextToSynthesize});
xhr.send(data);