使用fetch从Google Speech API解析合成的音频文件

时间:2017-10-18 21:06:37

标签: javascript audio cors fetch-api google-speech-api

我想阅读使用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

0 个答案:

没有答案