SilenceListenerNode is a pseudo-AudioNode which invokes a callback function whenever a stream of audio becomes or unbecomes silent. Uses AudioWorklet when available, falling back to ScriptProcessorNode when Worklets are not available.
Install using NPM:
npm i @alexanderolsen/silence-listener-node
To utilize AudioWorklet functionality, you must copy the sln.worklet.js
file in /node_modules/@alexanderolsen/silence-listener-node/dist/ to where the library can find it. The default location for this file is at the server root (/sln.worklet.js). This location can be changed using the options dict passed into createSilenceListenerNode()
:
createSilenceListenerNode(context, nChannels, {
pathToWorklet: '/some/path/to/sln.worklet.js', // default '/sln.worklet.js'
});
See Configuration for more instructions on using the options
dict.
import { createSilenceListenerNode } from '@alexanderolsen/silence-listener-node';
let context = new AudioContext();
let nChannels = 2;
let options = {}; // see **Configuration**
let buffSource = context.createBufferSource();
createSilenceListenerNode(context, nChannels, options)
.then((silenceListenerNode) => {
buffSource.connect(silenceListenerNode);
silenceListenerNode.connect(context.destination);
buffSource.start();
});
or
const createSilenceListenerNode = require('@alexanderolsen/silence-listener-node').createSilenceListenerNode;
(async function() {
let context = new AudioContext();
let nChannels = 2;
let options = {}; // see **Configuration**
let buffSource = context.createBufferSource();
let silenceListenerNode = await createSilenceListenerNode(context, nChannels, options);
buffSource.connect(silenceListenerNode);
silenceListenerNode.connect(context.destination);
buffSource.start();
})();
<script src="https://cdn.jsdelivr.net/npm/@alexanderolsen/silence-listener-node"></script>
<script>
var context = new AudioContext();
var nChannels = 2;
var options = {}; // see **Configuration**
let buffSource = context.createBufferSource();
SilenceListenerNode.createSilenceListenerNode(context, nChannels, options)
.then((silenceListenerNode) => {
buffSource.connect(silenceListenerNode);
silenceListenerNode.connect(context.destination);
buffSource.start();
});
</script>
Or use the silence-listener-node.js file in the dist folder:
<script src="silence-listener-node.js"></script>
When creating a SilenceListenerNode instance, you have number of options available:
let context = new AudioContext();
let nChannels = 2;
// entries are defaults
let options = {
nInputs: 1, // The number of inputs connected to this node. Probably 1
nOutputs: 1, // The number of outputs connected to this node. Probably 1
batchSize: 512, // Stuck at 128 for `AudioWorklet`s. Can be powers of 2 where 256 < batchSize < 16384
silenceThreshold: Math.floor(44100 / batchSize), // This is the number of silent batches which must
// occur before silence callbacks are invoked.
pathToWorklet: '/sln.worklet.js' //The path to the worklet file
}
createSilenceListenerNode(context, nChannels, options).then((silenceListenerNode) => { ... });
The number of AudioNode
s connected to this instance of SilenceListenerNode. Default 1.
The nubmer of outputs AudioNode
s this instance of SilenceLisnerNode is connected to. Default 1.
Modifies the batch size processed by ScriptProcessorNode
. This does not affect AudioWorklet
s as they're stuck at 128. If using ScriptProcessorNode, must be one of the following: [256, 512, 1024, 2048, 4096, 8192, 16384]
.
The number of silent batches which must occur before the audio stream will be flagged as silent. Default is (roughly) one second worth of audio.
The location of your sln.worklet.js file. Default is at server root.
Once you've created the SilenceListenerNode using createSilenceListener()
or SilenceListenerNode.createSilenceListener()
, the returned object exposes:
/**
* Connects SilenceListenerNode to the specific destination AudioNode
*
* @param {AudioNode} destination The node to connect to
*/
connect(destination) { ... }
/** Disconnects from the currently-connected AudioNode */
disconnect() { ... }
/**
* Begin receiving silence notifications
*
* @param { Function(isSilent, timeSinceLast) } callback Invoked whenever audio becomes or unbecomes silent
* @return { String } id of the subscription. use with unsubscribeFromSilence(id) to stop receiving notifications
*/
subscribeToSilence(callback) { ... }
/**
* Stop receiving silence events for given ID.
*
* @param { String } id Identifier for callback subscription
*/
unsubscribeFromSilence(id) { ... }
get silent() { ... }
get silence() { ... } // for simplicity
get numberOfInputs() { ... }
get numberOfOutputs() { ... }
get channelCount() { ... }
get channelCountMode() { ... }
get channelInterpretation() { ... }
// e.g. let isSilent = silenceListenerNode.silent;
set channelCount(channelCount) { ... }
set channelCountMode(channelCountMode) { ... }
set channelInterpretation(channelInterpretation) { ... }
// e.g. silenceListenerNode.channelInterpretation = 'speakers';
Run any server (http-server, etc) from the project directory:
cd silence-listener-node
http-server
and visit localhost:8080/examples/basic or localhost:8080/examples/react in a browser. Examples must be hosted from the root directory, as they need to access the files in dist.
git clone https://github.com/aolsenjazz/silence-listener-node
cd silence-listener-node
npm run watch
Production files are placed in the dist directory.
This super unhelpful error message occurs when SilenceListenerNode is unable to find your sln.worklet.js. To fix this, make sure your options.pathToWorklet
is set correctly and that the file is actually reachable at that location.
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Licenses are available in LICENSE.md
.