【问题标题】:converting .wav file to .ogg in javascript在javascript中将.wav文件转换为.ogg
【发布时间】:2013-07-06 01:38:46
【问题描述】:

我正在尝试从浏览器捕获用户的音频输入。我已经用 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 有吗?

【问题讨论】:

  • 我从 vorbis 找到了 .ogg 编码器源代码。但是在 JS 中什么都没有,我不能在 JS 中使用相同的算法来做到这一点
  • +1 因为没有必要对此投反对票。
  • +1 同意。这对谁有帮助?
  • 谢谢你们。对 stackoverflow.com 的信任已恢复!
  • i got off the internetwork by Matt Diamond

标签: audio web ogg


【解决方案1】:

致那些对这篇帖子投反对票的人:如果不花时间提供一些关于为什么问题在某种程度上“不好”的见解,就对问题投反对票确实没有成效。我认为这个问题是有道理的,发帖人显然花了一些时间试图自己解决这个问题。 Web Audio spec 实际上旨在完全允许这种功能,但还没有接近实现该目的:

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

下面是关于当前w3caudio 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 端来完成类似的事情。

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

编辑:如果您不介意将用户限制为 Chrome,您也可以使用 Google 的 native-client。这似乎是一种非常有前途的技术,可以加载到沙箱中并实现几乎与本机执行代码一样好的速度。我假设在某些时候其他浏览器中也会有类似的实现。

【讨论】:

  • 非常感谢@jtrick。 Chrome native-client 似乎是我的解决方案。转换为 ogg 的整个想法不是发送巨大的 wav 文件(我想这可以解决服务器选项上的 ffmpeg)。特别感谢您对我的问题的支持:)
  • @himura:乐于助人!我正在做类似的事情,所以一旦我有时间专注于它,我可能会自己走这条路。我很想听听你的情况。
【解决方案2】:

这个问题一直让我发疯,因为我还没有看到有人提出一个真正干净的解决方案,所以我想出了自己的库:

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 编码选项,完全在浏览器中捕获和编码音频输入是完全合理的,跨浏览器,无需服务器或本机代码。

演示http://sb2702.github.io/audioRecord.js/

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

【讨论】:

  • 我喜欢您创建的内容...您是否考虑添加Opus support
  • 当然!这个周末我会去看看 - 我会看看我是否可以将我们的项目整合到一起放入 OGG Opus。
  • 我不再为此工作,但我已对您的答案投了赞成票,以便人们看到它。我真的希望它早点出现:)
  • 是否可以在用户第一次点击记录时请求授权?因为有些用户可能不需要在页面上使用录音功能。只是Chrome标签中的红点很烦人
  • 嗨@Toolkit - 您可以在用户点击记录时调用 audioRecord.requestDevice(在用户点击记录时调用的任何函数内),而不是在页面加载时调用。不过你是对的 - 它有点笨拙 - 如果你没有权限,我会尝试考虑一种更简化的方式来请求权限,这是你第一次使用 recorder.record()
【解决方案3】:

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感兴趣。

【讨论】:

    【解决方案4】:

    好的,这可能不是一个直接的答案,因为它没有说明如何将.wav 转换为.ogg。再说一次,当您可以直接使用.ogg 文件时,为什么还要麻烦转换。这取决于MediaRecorder API,但支持 WebAudio 的浏览器通常也有这个(Firefox 25+ 和 Chrome 47+)

    github.io Demo

    Github Code Source

    【讨论】:

    • 显然 Chrome 49 中唯一的音频格​​式是 Opus @ 48kHz。
    • opus 是一种新的格式 afaik。只是在调查它。根据this,对音乐不利,但对演讲有利
    • @timmacp 不错的文章,显然,.ogg 是 vorbis 和 opus 格式的容器,请查看此 reddit 页面以供他们讨论
    • 在 chrome 49 中尝试了您的 MediaRecorder-sample,我得到了 script.js:17 Uncaught TypeError: navigator.mediaDevices.getUserMedia is not a function。我猜 Matt diamonds 示例使用 navigator.webkitGetUserMedia 进行 chrome?
    • 你是对的,应该添加adapter.js来处理浏览器的不一致,
    猜你喜欢
    • 2023-04-08
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多