我想阅读使用Google Speech API的文本数组。我使用fetch API下载这些audio/mpeg
文件,而不是将它们嵌入到<audio>
元素中。
我实现fetch的原因,因为我想在第一个音频文件开始播放之前下载所有音频文件。我不得不把句子放到数组中,因为我希望在句子末尾有较低的音高。
但是我很难从resp.blob()
...
audioPlayer: function (file) {
var _this = this;
var voice = document.getElementById("voice");
var audio = document.createElement('audio');
audio.id = 'audio-player';
audio.controls = 'controls';
audio.preload = 'auto';
audio.src = file;
audio.type = 'audio/mpeg';
voice.appendChild(audio);
return audio;
},
voice: function (text) {
var _this = this;
var strings = text.split(/(?:\.)+\s|(?::)+\s/g);
var urls = [];
for (var i = 0; i < strings.length; i += 1) {
urls.push('https://www.google.com/speech-api/v1/synthesize?ie=UTF-8&text=' + strings[i] + '&lang=hu&pitch=0.5&speed=0.5&vol=1');
}
var myInit = {
method: 'GET',
mode: 'no-cors',
cache: 'default',
};
var promises = urls.map(url => fetch(url, myInit).then(resp => resp.blob()));
Promise.all(promises).then(results => {
var arr = [];
for (var i = 0; i < results.length; i += 1) {
var myBlob = new Blob([results[i]], {type: 'audio/mpeg'});
var objectURL = URL.createObjectURL(myBlob);
arr.push(objectURL);
}
var index = 1;
_this.audioPlayer(arr[0]).onended = function () {
if (index < arr.length) {
this.src = arr[index];
this.play();
index++;
}
};
});
},
此代码将以下错误返回到Chrome控制台:GET blob:https://example.com/c6998993-2882-44a8-8da5-285b40400a8c 416 (Requested Range Not Satisfiable)
或在Firefox中:Error Code: NS_ERROR_DOM_MEDIA_METADATA_ERR (0x806e0006)
感谢您的帮助!
更新
我阅读了MDN文档,这是使用fetch解析音频文件的方法:https://github.com/mdn/fetch-examples/blob/master/fetch-array-buffer/index.html
但是,它适用于存储在本地服务器上的.ogg
文件,但是当我想在外部解析Google Speech API时却不行:
getAudioData: function () {
var _this = this;
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var source;
var play = document.querySelector('.play');
var stop = document.querySelector('.stop');
//var url = 'viper.ogg';
var url = 'https://www.google.com/speech-api/v1/synthesize?ie=UTF-8&text=Szia%20vil%C3%A1g!&lang=hu&pitch=0.5&speed=0.5&vol=1';
var myRequest = new Request(url);
var myInit = { mode: 'no-cors' };
// use fetch to load an audio track, and
// decodeAudioData to decode it and stick it in a buffer.
// Then we put the buffer into the source
function getData() {
source = audioCtx.createBufferSource();
fetch(myRequest, myInit)
.then(function (response) {
return response.arrayBuffer();
})
.then(function (buffer) {
audioCtx.decodeAudioData(buffer, function (decodedData) {
source.buffer = decodedData;
source.connect(audioCtx.destination);
});
});
};
play.onclick = function () {
getData();
source.start(0);
play.setAttribute('disabled', 'disabled');
}
stop.onclick = function () {
source.stop(0);
play.removeAttribute('disabled');
}
},
控制台错误是:Uncaught (in promise) DOMException: Unable to decode audio data