Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Large MP3 files cause DOM Exception 12 #9

Closed
vernondegoede opened this issue Apr 21, 2013 · 39 comments
Closed

Large MP3 files cause DOM Exception 12 #9

vernondegoede opened this issue Apr 21, 2013 · 39 comments
Labels

Comments

@vernondegoede
Copy link

Hi there,

I absolutely love this plugin. It works great when I try to play small MP3 files.

However, when I try to load a larger MP3 file (51 MB), I get an JS error: DOM Exception 12.
The MP3 file seems to load fine in the beginning, but in the end it's slowing down (the line which indicates that it's loading moves at a much slower rate). My Chrome browser tab also crashes at the end (gives me a purple error message).

This is the error I'm getting:

Uncaught Error: SyntaxError: DOM Exception 12 webaudio.js:66
WaveSurfer.WebAudio.loadData webaudio.js:66
(anonymous function)

When I'm looking at webaudio.js it seems to be an issue with the decodeAudioData() method.

Is this a known issue? And how can I fix this problem?

Help would be appreciated, since I'm stuck with my project right now.

Thanks in advance!

@katspaugh
Copy link
Owner

Hi @goedev001,

I'm away from computer this week, but just a guess — try to lower the sampleRate of the WebAudio context and bufferSize of the script node.

Thanks for your report!

@katspaugh
Copy link
Owner

Also this might help (see a workaround in the bottom): https://bugs.webkit.org/show_bug.cgi?id=106658

@vernondegoede
Copy link
Author

Hi @katspaugh, thanks for your reply!

I tried lowering the sampleRate (which is called fftSize in webaudio.js, if I'm correct), but no luck.
Do you have any idea when this problem will be fixed? We prefer to use your original code, since upgrading should be easier after some time.
I've seen in your source code that you added a TO DO comment which indicates that you're still working on fixing the problem with large audio files. Is that correct?

Thanks!

@katspaugh
Copy link
Owner

Vernon, that TODO was about streaming audio (to draw the waveform as it plays).

As for upgrading, I'd include your changes if you made a pull request. Otherwise, just wait until I get back to computer next week and we shall look for a reliable solution.

@ajeethboaz
Copy link

Hi, Very interesting plugin. I tried downloading it and tried to run the example but it seems not to play. Can you plz help me out in this.

@katspaugh
Copy link
Owner

Khm-khm. @ajeethboaz, you should start your own issue with more details, and I would help you gladly. Thanks!

@ajeethboaz
Copy link

Sorry, But am not able to play an mp3, If I can do that I can proceed....

@vernondegoede
Copy link
Author

Hi @katspaugh, do you have any updates for us / any estimated time when this issue will be resolved? Thanks!

@katspaugh
Copy link
Owner

Hey @goedev001! I'll get at it tomorrow, will keep you posted.

@katspaugh
Copy link
Owner

@goedev001, could you provide the exact file that causes the problem? I tried with a 68 MB MP3 from Librivox and it loads OK in Safari (though it crashes Chrome tabs completely).

@vernondegoede
Copy link
Author

That's exactly my problem. Files that are > 8 MB cause Google Chrome tabs to crash.

@vernondegoede
Copy link
Author

Whoops, pressed the wrong button... Sorry.

@katspaugh
Copy link
Owner

@goedev001, I've added the workaround from the WebKit bug report and it seems to work with big files now. However, they still take an unpractical eternity to decode. See 8ddef58

@ajeethboaz, you need to serve the example from an HTTP 1.1 server in order for it to work, you can't just open the downloaded file in the browser. If you have any further questions, please create a separate issue. This one is only about large MP3 files.

@vernondegoede
Copy link
Author

@katspaugh, I'm sorry but I've pulled the latest version of the script and it still causes a crash! Would you like to receive the URL of the project where we're using your plugin? Maybe that can help you to solve te problem.

Also, this seems a common error with Google Chrome. I think the web audio API isn't completely bug free...

@katspaugh
Copy link
Owner

Yeah, definitely do. I'm interested in what you are using it for, anyway.

@vernondegoede
Copy link
Author

Our poject can be seen on: http://vernonweb.nl/audio/
You can search songs and drag and drop them into a player. When the duration of a song is too long, Chrome will crash!

@vernondegoede
Copy link
Author

Hey @katspaugh! Do you have any idea what the problem might be? :-)

@katspaugh
Copy link
Owner

Hi @goedev001! Sorry that it takes so long to resolve this. From what I managed to google, Safari and Chrome can't decode a large binary due to memory limits. The 8ddef58 patch seems to strip off the size meta-data, that's why it sometimes (I guess, when file's actual size is only slightly above the safe limits) works.

People are suggesting streaming audio through HTML5 Audio, so that WebAudio could decode only a small piece at a time. I think @kevincennis has done this work already in https://github.com/kevincennis/Sound.js, so we might use this library.

katspaugh added a commit that referenced this issue May 14, 2013
@kdelmonte
Copy link

what was the solution here?

@katspaugh
Copy link
Owner

@kdelmonte, no solution, in fact. decodeAudioData has it's limits which we can't affect.

@kdelmonte
Copy link

Understood. Great tool! I'll find a work around.

@katspaugh
Copy link
Owner

@kdelmonte, thank you. What are you using it for?

@kdelmonte
Copy link

@katspaugh using it as a recording player.

@kdelmonte
Copy link

@katspaugh I'm thinking ill try splitting the file in chunks on the server and will create an instance of wave surfer for each part which I will then put right next to each other and will use your events to make them function like one... What are your thoughts?

@katspaugh
Copy link
Owner

@kdelmonte, you can load the files, extracting the peaks, then draw the concatenated peaks array as a single waveform. Something along the lines of:

var loadCount = 0;
var maxPeak = 0;
var peaksSet = new Array(splitTrackUrls.length);

splitTrackUrls.forEach(function (url, index) {
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'arraybuffer';
    xhr.open('GET', url, true);
    xhr.send();
    xhr.addEventListener('load', function (e) {
           wavesurfer.backend.loadBuffer(e.target.response, function () {
               var pixels = wavesurfer.drawer.getPixels(wavesurfer.backend.getDuration() || 1);
               peaksSet[index] = wavesurfer.backend.getPeaks(pixels);
               maxPeak = wavesurfer.backend.getMaxPeak();
               loadCount += 1;
               if (loadCount >= splitTrackUrls.length) {
                   var peaks = new Float32Array(peaksSet.reduce(function (a, b) {
                       return a.length + b.length;
                   }));
                   var offset = 0;
                   peaksSet.forEach(function (arr) {
                       peaks.set(arr, offset);
                       offset += arr.length;
                   });
                   wavesurfer.drawer.drawPeaks(peaks, maxPeak);
                   wavesurfer.fireEvent('ready');
               }
           });
    }, false);
});

Also, beware that chunks must be themselves whole audio-files complete with metadata, otherwise it won't be able to decode them (see the WebKit bug report linked above).

@kdelmonte
Copy link

Thank you... I will try it.. One question though, in the line "var pixels = wavesurfer.drawer.getPixels(duration);" what is "duration" supposed to be?

@katspaugh
Copy link
Owner

@kdelmonte oops! duration is supposed to be downloaded audio's duration. Edited the code sample.

@aboutaaron
Copy link

@katspaugh So, it's look large files are a no go then? Bummer! Great library though. I'm looking to play more with web audio and this looks like a great library to start working with.

@katspaugh
Copy link
Owner

@aboutaaron, alas, the technology (decodeAudioData) is meant for shorter samples.

Thanks for your interest! 😄

@vernondegoede
Copy link
Author

I guess the problem is still not solved?

We wanted to use this library for our HTML5 audio app about 7 months ago, but we felt the HTML5 Audio API is too limited to continue the project. This was one of the main issues we walked into.

@katspaugh
Copy link
Owner

It's not; sorry to disturb the slumber of this thread!

@vernondegoede
Copy link
Author

Too bad. The problem is a Google Chrome issue, right? :-(

@katspaugh
Copy link
Owner

The problem is with our approach maybe. In order to draw the waveform, you need to process (decode) the whole audio at once which takes hundreds of megabytes of memory.

I shall try once more to mix together offlineAudioContext and createMediaElementSource, maybe we could analyze the audio faster than realtime.

@vernondegoede
Copy link
Author

Cool! I'll update the project soon, so we can test it! :-)

@amundo
Copy link

amundo commented Nov 26, 2013

For what it's worth there's at least one other person, me, who is very
interested in this topic! Looking forward to following development on this.

On Mon, Nov 25, 2013 at 2:37 PM, Vernon notifications@github.com wrote:

Cool! I'll update the project soon, so we can test it! :-)


Reply to this email directly or view it on GitHubhttps://github.com//issues/9#issuecomment-29249886
.

Pat

@katspaugh
Copy link
Owner

Sorry guys, it still crashes with offlineAudioContext + createMediaElementSource...

@kevincennis
Copy link
Contributor

This is probably way overkill for wavesurfer itself, but for people running into this problem...

MP3 files are broken up into frames, which can each be decoded independently. It should be possible (although maybe not easy) to split an Arraybuffer into a bunch of separate chunks that are each n frames long, and then decode/analyze those separately and stitch them back together.

The MP3 format is kind of tricky, but finding frames shouldn't be too hard if you read up a bit on the spec. It certainly helps to have some experience working with binary data, though. If I get some time, I'll try to put together a proof of concept and post a link.

@chinshr
Copy link
Contributor

chinshr commented Oct 26, 2015

Instead of starting a new thread on streaming audio, AFAIK, this thread is the most appropriate to propose the idea of using m3u playlists that essentially works like streaming audio, or consecutively playing smaller mp3 files. I am pre-generating the waveform (JSON) ahead of time, so it would be great to have a way to play .m3u files in wavesurfer.js. Would love to hear your thoughts and if this could solve your problem?

@kavishatalsania
Copy link

Does anyone found a solution for this? I am also facing the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants