【问题标题】:How to play wav audio byte array via javascript/html5?如何通过 javascript/html5 播放 wav 音频字节数组?
【发布时间】:2014-07-31 19:32:05
【问题描述】:

我正在使用以下方法播放包含 wav 数据的字节数组。正在从 GWT 项目调用该函数。

这个函数播放声音,但听起来像是某种地狱般的怪物。采样率绝对正确(声音是由 neospeech 生成的),我尝试了 numberOfSamples 的各种值,这似乎只是代表音频数据的长度。

numberOfSamples 的值大于 30000 将播放音频文件的完整长度,但会出现乱码和可怕的问题。

那么,我做错了什么?

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);
}

【问题讨论】:

    标签: javascript html gwt wav audiocontext


    【解决方案1】:

    我想出了如何做我在问题中描述的内容,并认为我应该发布它以造福他人。代码如下。我调用 playByteArray 并将其传递给包含 pcm wav 数据的字节数组。

    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);
    }
    

    【讨论】:

    • 好东西,我一直在寻找一个像这样的简明扼要的例子
    • 我是否遗漏了什么,或者for 循环将每个单独的字节分配给playByteArray 函数内的bufferView 没有意义?
    • @user7290573 是的,我也有同样的问题,不知道作者介意解释一下吗?
    【解决方案2】:

    清理建议:

    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】:

      与 AudioContext 相比,此方法适用于最新的 iOS Safari。音频对象应该在点击/点击(用户交互)事件时创建,所以不要在请求回调中这样做。

      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()
            })
      

      来自here的sn-p

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-14
        • 1970-01-01
        • 2012-07-27
        • 2023-03-12
        相关资源
        最近更新 更多