How to play wav audio byte array via javascript/html5?

会有一股神秘感。 提交于 2019-11-26 13:59:41

问题


I'm using the following method to play a byte array containing wav data. The function is being called from a GWT project.

This function plays back sound, but it sounds like some kind of Hellish monster. The sample rate is definitely correct (the sound is being generated by neospeech) and I've tried all kinds of values for numberOfSamples, which just seems to represent how long the audio data is.

A value greater than 30000 for numberOfSamples will play the audio file's full length but it is garbled and horrible.

So, what am I doing wrong?

function playByteArray(byteArray, numberOfSamples) {
    sampleRate = 8000;

    if (!window.AudioContext) {
        if (!window.webkitAudioContext) {
            alert("Your browser does not support any AudioContext and cannot play back this audio.");
            return;
        }
        window.AudioContext = window.webkitAudioContext;
    }

    var audioContext = new AudioContext();

    var buffer = audioContext.createBuffer(1, numberOfSamples, sampleRate);
    var buf = buffer.getChannelData(0);
    for (i = 0; i < byteArray.length; ++i) {
        buf[i] = byteArray[i];
    }

    var source = audioContext.createBufferSource();
    source.buffer = buffer;
    source.connect(audioContext.destination);
    source.start(0);
}

回答1:


I figured out how to do what I described in my question and thought I should post it for the benefit of others. The code is below. I call playByteArray and pass it a byte array containing pcm wav data.

window.onload = init;
var context;    // Audio context
var buf;        // Audio buffer

function init() {
if (!window.AudioContext) {
    if (!window.webkitAudioContext) {
        alert("Your browser does not support any AudioContext and cannot play back this audio.");
        return;
    }
        window.AudioContext = window.webkitAudioContext;
    }

    context = new AudioContext();
}

function playByteArray(byteArray) {

    var arrayBuffer = new ArrayBuffer(byteArray.length);
    var bufferView = new Uint8Array(arrayBuffer);
    for (i = 0; i < byteArray.length; i++) {
      bufferView[i] = byteArray[i];
    }

    context.decodeAudioData(arrayBuffer, function(buffer) {
        buf = buffer;
        play();
    });
}

// Play the loaded file
function play() {
    // Create a source node from the buffer
    var source = context.createBufferSource();
    source.buffer = buf;
    // Connect to the final output node (the speakers)
    source.connect(context.destination);
    // Play immediately
    source.start(0);
}



回答2:


Clean up suggestion:

function playByteArray( bytes ) {
    var buffer = new Uint8Array( bytes.length );
    buffer.set( new Uint8Array(bytes), 0 );

    context.decodeAudioData(buffer.buffer, play);
}

function play( audioBuffer ) {
    var source = context.createBufferSource();
    source.buffer = audioBuffer;
    source.connect( context.destination );
    source.start(0);
}



回答3:


This approach will work with the latest iOS safari comparing to AudioContext. Audio object should be created on tap/click (user interaction) event, so don't do it in request callbacks.

const audio = new Audio()    
fetch(url, options) // set content header to array buffer
      .then((response) => {
        var blob = new Blob([response.value], { type: 'audio/mp3' })
        var url = window.URL.createObjectURL(blob)        
        audio.src = url
        audio.play()
      })

snippet from here



来源:https://stackoverflow.com/questions/24151121/how-to-play-wav-audio-byte-array-via-javascript-html5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!