Decode audio file data in the browser from a File/Blob into a AudioBuffer using AudioContext.decodeAudioData().
This package was originally created and is used in soundcut.
In the current state of Web Audio API, there is a variety of use-cases where one might need to decode a file (Blob
, or ArrayBuffer
) audio data (AudioBuffer
) (though the current APIs are arguably quite inneficient at this, decoding the whole file upfront), including but not limited to:
- Drawing audio waveform
- Audio manipulation, such as looping, etc...
AudioContext.decodeAudioData()
is slow and does not work for large files.
By splitting the source into chunks and decoding these in concurrently, decode-audio-data-fast
works around the native API's limitations.
npm i --save @soundcut/decode-audio-data-fast
import { getFileAudioBuffer } from '@soundcut/decode-audio-data-fast';
function decodeFileAudioData(file) {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
return getFileAudioBuffer(file, audioCtx);
}
const { getFileAudioBuffer } = require('@soundcut/decode-audio-data-fast');
function decodeFileAudioData(file) {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
return getFileAudioBuffer(file, audioCtx);
}
<script src="{YOUR_HOST}/decode-audio-data-fast.standalone.umd.min.js"></script>
<script>
function decodeFileAudioData(file) {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
return window.DADF.getFileAudioBuffer(file, audioCtx);
}
</script>
https://unpkg.com/@soundcut/decode-audio-data-fast
See all files published in ./dist
directory.
Yes. However, it appears decode-audio-data-fast
is twice as fast.
At the moment, decode-audio-data-fast
only supports mp3
files that can be read through mp3-parser.
Visit decodeAudioData / decode-audio-data-fast benchmark page (open your browser console, wait a reasonably long time for all the benchmarks to run).
Test file is a 13MB 320kbps CBR MP3 export of https://www.youtube.com/watch?v=BigolJfoANw
The last argument of getFileAudioBuffer
is an optional options: { concurrency: number }
object:
getFileAudioBuffer(file, audioCtx, { concurrency: 4 })
When omitted, getFileAudioBuffer
will use "automatic concurrency mode", relying on navigator.hardwareConcurrency
:
const DEFAULT_CONCURRENCY = 4;
const CONCURRENCY =
((typeof navigator !== 'undefined' && navigator.hardwareConcurrency) || 1) > 2
? navigator.hardwareConcurrency
: DEFAULT_CONCURRENCY;
See rationale for "automatic concurrency mode" on Twitter.
FIXME
This module is intended for ~modern browsers, uses and assumes availability of the following syntax/API, among others:
This module has somewhat been tested on Firefox/Chrome, for desktop and mobile, and currently has known issues with Safari.