在javascript中将.wav文件转换为.ogg

时间:2013-07-08 16:20:36

标签: audio web ogg

我正在尝试从浏览器捕获用户的音频输入。我用WAV完成了它,但文件非常大。我的一个朋友告诉我,OGG文件要小得多。 有谁知道如何将WAV转换为OGG? 我也有原始数据缓冲区,我真的不需要转换。但我只需要OGG编码器。

以下是来自Matt Diamond's RecorderJS的WAV编码器:

function encodeWAV(samples){
  var buffer = new ArrayBuffer(44 + samples.length * 2);
  var view = new DataView(buffer);

  /* RIFF identifier */
  writeString(view, 0, 'RIFF');
  /* file length */
  view.setUint32(4, 32 + samples.length * 2, true);
  /* RIFF type */
  writeString(view, 8, 'WAVE');
  /* format chunk identifier */
  writeString(view, 12, 'fmt ');
  /* format chunk length */
  view.setUint32(16, 16, true);
  /* sample format (raw) */
  view.setUint16(20, 1, true);
  /* channel count */
  view.setUint16(22, 2, true);
  /* sample rate */
  view.setUint32(24, sampleRate, true);
  /* byte rate (sample rate * block align) */
  view.setUint32(28, sampleRate * 4, true);
  /* block align (channel count * bytes per sample) */
  view.setUint16(32, 4, true);
  /* bits per sample */
  view.setUint16(34, 16, true);
  /* data chunk identifier */
  writeString(view, 36, 'data');
  /* data chunk length */
  view.setUint32(40, samples.length * 2, true);

  floatTo16BitPCM(view, 44, samples);

  return view;
}

OGG有一个吗?

4 个答案:

答案 0 :(得分:18)

对于那些对这篇文章投票不好的人:如果没有花时间提供某种洞察为什么问题在某种程度上“糟糕”,那么向下投票问题真的没有成效。我认为这个问题很有价值,而海报显然花了一些时间试图自己解决这个问题。 Web Audio spec实际上旨在允许这种功能,但是还没有完全实现这个目的:

  

此规范描述了用于在Web应用程序中处理和合成音频的高级JavaScript API。主要范例是音频路由图,其中许多AudioNode对象连接在一起以定义整体音频呈现。实际处理将主要在底层实现中进行(通常是优化的Assembly / C / C ++代码),但也支持 JavaScript处理和综合

这是关于当前w3c audio spec draft的陈述,其中提出了以下几点:

  • 在JavaScript中处理音频时,获得可靠,无故障的音频,同时实现合理的低延迟,尤其是在处理器负载较重的情况下,极具挑战性。
  • JavaScript比大量优化的C ++代码慢得多,并且无法利用SSE优化和多线程,这对于在当今的处理器上获得良好性能至关重要。与JavaScript相比,优化的本机代码处理FFT的速度可快20倍。它对于音频的重载处理(如卷积和大量音频源的3D空间化)来说效率不高。
  • setInterval()和XHR处理将从音频处理中窃取时间。在一个相当复杂的游戏中,游戏物理和图形需要一些JavaScript资源。这带来了挑战,因为音频渲染是截止日期驱动的(以避免故障并获得足够低的延迟)。 JavaScript不会在实时处理线程中运行,因此可以被系统上运行的许多其他线程抢占。
  • 垃圾收集(以及Mac OS X上的自动释放池)可能会导致JavaScript线程出现无法预料的延迟。
  • 可以在主线程上运行多个JavaScript上下文,从执行处理的上下文中窃取时间。
  • 其他代码(除了JavaScript之外),例如页面呈现在主线程上运行。
  • 可以获取锁定并在JavaScript线程上分配内存。这可能导致额外的线程抢占。
  • 今天的移动设备产生的问题更加困难,这些移动设备的处理器具有相对较差的性能和功耗/电池寿命问题。

ECMAScript(js)对于很多事情来说非常快,并且根据引擎解释代码的速度而变得越来越快。然而,对于像音频处理这样密集的东西,使用编译的优化资源以优化特定于任务的资源的低级工具会更好。我目前正在使用ffmpeg on the server方来完成类似的事情。

我知道,为了获得更紧凑的.ogg文件,必须通过互联网连接发送wav文件是非常低效的,但这是web音频api的当前状态。要进行任何客户端处理,用户必须明确地授予对本地文件系统的访问权限以及进行转换的文件的执行权限。希望有人能尽快解决这个明显的问题。祝你好运。

修改:如果您不介意将用户限制为Chrome,也可以使用Google的native-client。看起来非常有前途的技术可以加载到沙盒中,并且可以实现几乎与原生代码一样好的速度。我假设在某些时候在其他浏览器中会有类似的实现。

答案 1 :(得分:11)

这个问题一直让我抓狂,因为我还没有看到有人提出一个非常干净的解决方案,所以我提出了自己的库:

https://github.com/sb2702/audioRecord.js

基本用法

audioRecord.requestDevice(function(recorder){
  // Request user permission for microphone access

      recorder.record(); // Start recording

      recorder.stop();  /Stop recording

      recorder.exportOGG(function(oggBlob){
        //Here's your OGG file
      });

      recorder.exportMP3(function(mp3Blob){
               //Here's your mp3 file
      });

      recorder.exportWAV(function(wavBlob){
            //Here's your WAV file
      });

});

使用连续mp3编码选项,完全可以在浏览器中跨浏览器捕获和编码音频输入,无需服务器或本机代码。

DEMO http://sb2702.github.io/audioRecord.js/

它的边缘仍然很粗糙,但我会尝试清理/修复它。

答案 2 :(得分:4)

Derivative work of Matt Diamond's recorderjs recording to Ogg-Opus

要在没有特殊扩展名的浏览器中整体编码为 Ogg-Opus 文件,可以使用opus-tools/opusenc (demo)的Emscripten端口。它具有对WAV,AIFF和其他几种格式的解码支持以及内置的重新采样器。

Ogg-Vorbis 编码器is also available

由于提问者主要是音频压缩,他们可能也对mp3 encoding using lame感兴趣。

答案 3 :(得分:1)

好的,这可能不是直接的答案,因为它没有说明如何将http://example.com/logo.png转换为.wav。再说一遍,当你可以直接使用.ogg文件时,为什么还要为转换而烦恼呢。这取决于MediaRecorder API,但支持WebAudio的浏览器通常也有此功能(Firefox 25+和Chrome 47 +)

github.io Demo

Github Code Source