2014-10-02 131 views
3

解码我有一个网页,其解码波形文件的某些原因。 Chrome和Safari似乎工作正常。 Firefox偶尔无法解码文件并出现错误:“传递给decodeAudioData的缓冲区包含无法成功解码的无效内容。”我创建了一个jsfiddle这说明了问题:为什么某些.wav文件无法在Firefox

var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); 
var source; 
function getData() { 
    source = audioCtx.createBufferSource(); 
    request = new XMLHttpRequest(); 
    request.open('GET', 'https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav', true); 
    request.responseType = 'arraybuffer'; 
    request.onload = function() { 
    var audioData = request.response; 
    audioCtx.decodeAudioData(audioData, function(buffer) { 
     source.buffer = buffer; 
     source.connect(audioCtx.destination); 
     }, 
     function(e){"Error with decoding audio data" + e.err}); 
    } 
    request.send(); 
} 
getData(); 
source.start(0); 

谁能告诉我是什么问题,如果有任何的方式来规避?非常感谢。

编辑 感谢迈克尔·查尼的重大贡献,我能够实现一些JavaScript哪些进程,以便它可以在Firefox中播放的浪潮。代码修剪16字节的“fmt”块的任何部分。代码位于:jfiddle

var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); 
var source; 
function getData() { 
    source = audioCtx.createBufferSource(); 
    request = new XMLHttpRequest(); 
    request.open('GET', 'https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav', true); 
    request.responseType = 'arraybuffer'; 
    request.onload = function() { 
     var audioData = request.response; 
     var dv = new DataView(audioData); 
     var junk = 0; 
     var position = 12; 
     do { 
      var header = String.fromCharCode.apply(null, Uint8Array(audioData, position, 4)); 
      var length = dv.getUint32(position + 4, true); 
      if (header.trim() === 'fmt') { 
       junk = junk + length - 16; 
      } 
      position = position + 8 + length; 
     }while(position < audioData.byteLength); 
     var productArray = new Uint8Array(audioData.byteLength - junk); 
     productArray.set(new Uint8Array(audioData, 0, 12)); 
     var newPosition = 12; 
     position = 12; 
     var fmt_length_spot; 
     do { 
      var header = String.fromCharCode.apply(null, Uint8Array(audioData, position, 4)); 
      var length = dv.getUint32(position + 4, true); 
      if (header.trim() === 'fmt') { 
       productArray.set(new Uint8Array(audioData, position, 24), newPosition); 
       fmt_length_spot = newPosition + 4; 
       newPosition = newPosition + 24; 
      } 
      else { 
       productArray.set(new Uint8Array(audioData, position, length + 8), newPosition); 
       newPosition = newPosition + 8 + length; 
      } 
      position = position + 8 + length; 
     }while(position < audioData.byteLength); 
     audioData = productArray.buffer; 
     dv = new DataView(audioData); 
     dv.setUint32(4, audioData.byteLength - 8, true); 
     dv.setUint32(fmt_length_spot, 16, true); 
     audioCtx.decodeAudioData(audioData, function(buffer) { 
      source.buffer = buffer; 
      source.connect(audioCtx.destination); 
     }, 
     function(e){"Error with decoding audio data" + e.err}); 
    } 
    request.send(); 
} 
getData(); 
source.start(0); 

谢谢迈克尔。

+0

你介意我这个文件添加到我的WebAudio解码器的测试套件?这个项目背后的想法是不断检查哪些浏览器在解码什么样的音频文件时失败? http://notthetup.github.io/decodethis/ – notthetup 2014-10-09 02:54:18

+1

@notthetup,它的全部属于你的。 – laertiades 2014-10-09 03:30:48

+0

我试过这段代码,它并没有解决问题(我使用Firefox 52.0.2)。这并不令人意外,因为它已经在3年前写下了。 – maximedupre 2017-07-07 01:55:47

回答

2

这可能是在文件的开头垃圾块。您可以通过SOX运行它清理掉这样的外来块:

sox Malice_Bass.wav Malice_Bass_simple.wav 

下面是我个人的解析器说,有关文件:

RIFF - WAVE (36467192 bytes) 
    JUNK (92) 
    bext (602) 
     Description:  
     Originator:  Pro Tools 
     Originator Ref: jicj!dad1ofaaaGk 
     Origination Date: 2014-09-09 
     Origination Time: 20:46:43 
     Time Ref Low:  0 
     Time Ref High:  0 
     BWF Version:  0 
     SMPTE UMID Bytes: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
     Coding History:  
    fmt (40) 
     Format Tag:  1 
     Channels:   2 
     Samples per sec: 48000 
     Avg bytes per sec: 192000 
     Block align:  4 
     Bits per sample: 16 
    minf (16) 
    elm1 (214) 
    data (36466048) 
    regn (92) 
    umid (24) 

当我清理使用SOX火狐退出抱怨它但仍然无法播放它。我确认它加载了文件,但似乎没有播放它。

+0

我感谢您的帮助。听起来像是Firefox的一个缺点。 – laertiades 2014-10-03 17:03:42

+0

您是否认为可以实现类似于您的个人解析器的内容以在浏览器中运行? – laertiades 2014-10-03 17:06:08

+0

我想这样做,但我没有玩过最新的Javascript功能。 WAV格式文件齐全,易于解析。 – 2014-10-03 18:00:57

1

这wav文件是沉默前20秒。我只是下载了它:

wget https://mpclubtest.s3.amazonaws.com/Malice_Bass.wav 

我尝试使用Chrome和小提琴沉默了,起初我还以为 由于其实我只是用笔记本音箱。 使用大胆性的FFT表示它在静默20秒后开始非常低的频率。

网络音频API使用计算机的默认采样率,这是典型的 由于44.1的文件使用48 kHz的,是你的机器 配置了48 kHz的smple率是多少?如果您将48 kHz的文件重新采样到44.1kHz,这是一个典型的计算机采样率,它可能会工作。

+2

我有一个我为WAV写的解析器。它显示了具有2个通道,48K采样/秒,16位/采样的fmt块。这是正常的。在开头有一个JUNK块,bext,以及minf,elm1,data,regn和umid。看起来像一个正常的专业工具wav/bwav。 – 2014-10-03 15:44:15

+0

感谢您的帮助。我会研究这一点。 (我将不得不学习如何重新采样波浪)。 – laertiades 2014-10-03 16:56:28

0

我最近有这个问题与Firefox不读使用浏览器的音频API wav文件,并发现该问题是不应该以超过16位至火狐被识别的音频文件的比特深度。我还发现,这是一个8岁的Firefox“错误”,这是相当惊人(https://bugzilla.mozilla.org/show_bug.cgi?id=524109

我soultion是降级的任何wav文件与32位深度通过SOX命令行到16bit的是这样的:袜输入.wav -b 16 output.wav。你显然可以使用ffmpeg或其他可以在Linux下执行的应用程序。 希望有所帮助。

相关问题