Package Exports
- standardized-audio-context
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (standardized-audio-context) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
standardized-audio-context
A cross-browser implementation of the AudioContext which aims to closely follow the standard.
This package provides a subset of the Web Audio API which works in a reliable and consistent way in every supported browser. In contrast to other popular polyfills standardized-audio-context does not patch or modify anything on the global scope. In other words, it does not cause any side effects. It can therefore be used safely inside of libraries.
One of the goals of standardized-audio-context is to only polyfill missing functionality and to avoid rewriting builtin features whenever possible.
There are of course some things which cannot be faked in a way that makes them as performant as
they could be when implemented natively. The most obvious amongst those things is the
AudioWorklet. Please have a look at the list of all supported methods below for more detailed information.
Usage
The standardized-audio-context is available on
npm and can be installed as usual.
npm install standardized-audio-contextYou can then import the AudioContext and OfflineAudioContext like this:
import { AudioContext, OfflineAudioContext } from 'standardized-audio-context';Afterwards the AudioContext/OfflineAudioContext can be used in the same way as their native counterparts. The following snippet will produce a nice and clean sine wave.
import { AudioContext } from 'standardized-audio-context';
const audioContext = new AudioContext();
const oscillatorNode = audioContext.createOscillator();
oscillatorNode.connect(audioContext.destination);
oscillatorNode.start();An alternative approach would be to use the AudioNode constructors (the OscillatorNode constructor in this case) instead of the factory methods.
import { AudioContext, OscillatorNode } from 'standardized-audio-context';
const audioContext = new AudioContext();
const oscillatorNode = new OscillatorNode(audioContext);
oscillatorNode.connect(audioContext.destination);
oscillatorNode.start();API
AudioContext
This is an incomplete implementation of the AudioContext interface. It misses the following factory methods: createConvolver(), createDelay(), createDynamicsCompressor(), createMediaStreamDestination(), createPanner(), createPeriodicWave() and createScriptProcessor(). The listener property is also missing for now.
With the exception of createMediaStreamDestination() and createScriptProcessor() there is no technical reason for not supporting these methods. They are just not implemented yet. Please create a new issue if you desperately need any of them.
OfflineAudioContext
This is an incomplete implementation of the OfflineAudioContext interface. It misses mostly the same methods as the AudioContext which are: createConvolver(), createDelay(), createDynamicsCompressor(), createPanner(), createPeriodicWave() and createScriptProcessor().
audioWorklet
The AudioWorklet is accessible as a property of an AudioContext or OfflineAudioContext. It uses the ScriptProcessorNode internally to create an AudioWorkletProcessor in any browser but Chrome. This means it will not provide the performance improvements that you would normally expect from using an AudioWorklet.
The fact that the internal implementation relies on a ScriptProcessorNode also implies that the channelCountMode can only be 'explicit' for now. It also means that the total number of channels of all inputs plus the number of all parameters can't be larger than six.
Another thing to keep in mind is that the fallback will evaluate the AudioWorkletProcessor on the global scope. It gets isolated in a basic way to mimic the AudioWorkletGlobalScope but that can't be done in a way which makes it impossible for an attacker to break out of that sandbox. This should not be a problem unless you load an AudioWorklet from an untrusted source.
decodeAudioData()
This is an implementation of the
decodeAudioData() method.
AnalyserNode / createAnalyser()
This is an implementation of the
AnalyserNode constructor and the createAnalyser() factory method respectively.
BiquadFilterNode / createBiquadFilter()
This is an implementation of the
BiquadFilterNode constructor and the createBiquadFilter() factory method respectively.
AudioBuffer / createBuffer()
This is an implementation of the
AudioBuffer constructor and the createBuffer() factory method respectively.
AudioBufferSourceNode / createBufferSource()
This is an implementation of the
AudioBufferSourceNode constructor and the createBufferSource() factory method respectively. It is currently missing the detune AudioParam.
ChannelMergerNode / createChannelMerger()
This is an implementation of the
ChannelMergerNode constructor and the createChannelMerger() factory method respectively.
ChannelSplitterNode / createChannelSplitter()
This is an implementation of the
ChannelSplitterNode constructor and the createChannelSplitter() factory method respectively.
ConstantSourceNode / createConstantSource()
This is an implementation of the
ConstantSourceNode constructor and the createConstantSource() factory method respectively.
GainNode / createGain()
This is an implementation of the
GainNode constructor and the createGain() factory method respectively.
IIRFilterNode / createIIRFilter()
This is an implementation of the
IIRFilterNode constructor and the createIIRFilter() factory method respectively. It has to be faked internally with a ScriptProcessorNode in Safari which means it is not as performant as in other browsers which support it natively.
MediaElementAudioSourceNode / createMediaElementSource()
This is an implementation of the
MediaElementAudioSourceNode constructor and the createMediaElementSource() factory method respectively. It does only work with an AudioContext but not with an OfflineAudioContext.
MediaStreamSourceNode / createMediaStreamSource()
This is an implementation of the
MediaStreamAudioSourceNode constructor and the createMediaStreamSource() factory method respectively. It does only work with an AudioContext but not with an OfflineAudioContext.
OscillatorNode / createOscillator()
This is an implementation of the
OscillatorNode constructor and the createOscillator() factory method respectively.
StereoPannerNode / createStereoPanner()
This is an implementation of the StereoPannerNode constructor and the createStereoPanner() factory method respectively. The channelCountMode can only be 'explicit' unless Safari comes up with a native implementation.
WaveShaperNode / createWaveShaper()
This is an implementation of the WaveShaperNode constructor and the createWaveShaper() factory method respectively.
isSupported()
standardized-audio-context is also exporting a promise which can be accessed by calling isSupported(). This promise resolves to a boolean which indicates if the functionality is supported within the currently used browser. This is not part of the specification.
import { isSupported } from 'standardized-audio-context';
isSupported()
.then((isSupported) => {
if (isSupported) {
// yeah everything should work
} else {
// oh no this browser seems to be outdated
}
});TypeScript
This package is written in TypeScript which means it can be used seamlessly in any TypeScript project. But that is entirely optional.
In contrast to the Web Audio API types that TypeScript provides out of the box the types exported
by standardized-audio-context do actually match the concrete implementation. TypeScript
generates its types from the Web IDL definition of the Web Audio
API which does not always match the actually available implementations.
Tests
All implemented methods are covered by a large number of tests which are executed on a variety of browsers. Many thanks to BrowserStack and Sauce Labs for allowing this module to be tested with their services.