如何在浏览器中使用JavaScript播放音频字节数组(不是文件!)

时间:2011-11-04 21:04:28

标签: streaming web wav

出于安全原因,我不允许在服务器上存储WAV文件以供浏览器访问。我所拥有的是一个字节数组包含服务器上的音频数据(我相信WAV文件的数据部分),我希望它通过JavaScript(或Applet,但首选JS)在浏览器上播放,我可以使用JSON- PRC发送整个byte [],或者我可以打开一个套接字来流过它,但在任何一种情况下我都不知道在浏览器中播放byte []的人是谁?

4 个答案:

答案 0 :(得分:6)

以下代码将以0.5和2.0播放正弦波。在您的按钮或任何您想要的地方调用函数play_buffersource()

使用启用了Web音频标记的Chrome进行测试。对于您的情况,您需要做的只是将音频字节随机播放到buf

<script type="text/javascript">
const kSampleRate = 44100; // Other sample rates might not work depending on the your browser's AudioContext
const kNumSamples = 16834;
const kFrequency  = 440;
const kPI_2       = Math.PI * 2;

function play_buffersource() {
    if (!window.AudioContext) {
        if (!window.webkitAudioContext) {
            alert("Your browser sucks because it does NOT support any AudioContext!");
            return;
        }
        window.AudioContext = window.webkitAudioContext;
    }

    var ctx = new AudioContext();

    var buffer = ctx.createBuffer(1, kNumSamples, kSampleRate);
    var buf    = buffer.getChannelData(0);
    for (i = 0; i < kNumSamples; ++i) {
        buf[i] = Math.sin(kFrequency * kPI_2 * i / kSampleRate);
    }

    var node = ctx.createBufferSource(0);
    node.buffer = buffer;
    node.connect(ctx.destination);
    node.noteOn(ctx.currentTime + 0.5);

    node = ctx.createBufferSource(0);
    node.buffer = buffer;
    node.connect(ctx.destination);
    node.noteOn(ctx.currentTime + 2.0);
}
</script>

参考文献:

如果您需要重新取样音频,可以使用JavaScript重新采样器:https://github.com/grantgalitz/XAudioJS

如果你需要解码base64数据,那么有很多JavaScript base64解码器:https://github.com/carlo/jquery-base64

答案 1 :(得分:1)

如果您在服务器上有字节,那么我建议您在服务器上创建某种处理程序,将字节作为wav文件流式传输到响应中。此“文件”仅在服务器上的内存中,而不在磁盘上。然后浏览器可以像普通的wav文件一样处理它。 需要有关服务器堆栈的更多详细信息,以提供有关如何在您的环境中完成此操作的更多信息。

答案 2 :(得分:1)

我通过以下代码完成了这项工作。我传入一个字节数组,其中包含wav文件中的数据到函数playByteArray。我的解决方案与Peter Lee的解决方案类似,但我不能让他的工作在我的情况下(输出是乱码),而这个解决方案适合我。我确认它适用于Firefox和Chrome。

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

答案 3 :(得分:0)

我怀疑你可以通过HTML5 Audio API轻松实现这一目标:

https://developer.mozilla.org/en/Introducing_the_Audio_API_Extension

这个库也可以派上用场,虽然我不确定它是否反映了最新的浏览器行为:

https://github.com/jussi-kalliokoski/audiolib.js