Welcome to Realtime BPM Analyzer, a powerful and easy-to-use TypeScript/JavaScript library for detecting the beats-per-minute (BPM) of an audio or video source in real-time.
To install this module to your project, just launch the command below:
npm install realtime-bpm-analyzer
To learn more about how to use the library, you can check out the documentation.
If you encounter issues along the way, remember we have a discord server and a chat !
Mesure or detect the BPM from a web player.
This example shows how to deal with a simple audio
node.
<audio src="./new_order-blue_monday.mp3" id="track"></audio>
createRealTimeBpmProcessor
, create and pipe the filters to the AudioWorkletNode (realtimeAnalyzerNode
).import { createRealTimeBpmProcessor } from 'realtime-bpm-analyzer';
const realtimeAnalyzerNode = await createRealTimeBpmProcessor(audioContext);
// Set the source with the HTML Audio Node
const track = document.getElementById('track');
const source = audioContext.createMediaElementSource(track);
// Connect nodes together
source.connect(realtimeAnalyzerNode);
source.connect(audioContext.destination);
realtimeAnalyzerNode.port.onmessage = (event) => {
if (event.data.message === 'BPM') {
console.log('BPM', event.data.result);
}
if (event.data.message === 'BPM_STABLE') {
console.log('BPM_STABLE', event.data.result);
}
};
Analyze the BPM of a source continuously. This feature is quite simple and basically get rid of all data inside the analyzer after the stabilizationTime is reached. Why ? Because we store all the "valid peaks" for each thresholds in order to find the best candidates. And we would keep all those data forever, we would have memory leaks.
Note: This approach is NOT recommended if you are using a microphone as source. Except if the microphone gets correct audio source. Typically, if the BPM is never computed using this approach, you probably capture low intensity audio with your microphone (too far from the source, too much noise, directional microphone could be reasons why it's not working).
<audio src="https://ssl1.viastreaming.net:7005/;listen.mp3" id="track"></audio>
Thank you IbizaSonica for the stream.
continuousAnalysis
flag to periodically delete collected data.import { createRealTimeBpmProcessor } from 'realtime-bpm-analyzer';
const realtimeAnalyzerNode = await createRealTimeBpmProcessor(audioContext);
// Set the source with the HTML Audio Node
const track = document.getElementById('track');
const source = audioContext.createMediaElementSource(track);
// Connect nodes together
source.connect(realtimeAnalyzerNode);
source.connect(audioContext.destination);
// Enable the continuous feature
realtimeAnalyzerNode.port.postMessage({
message: 'ASYNC_CONFIGURATION',
parameters: {
continuousAnalysis: true,
stabilizationTime: 20_000, // Default value is 20_000ms after what the library will automatically delete all collected data and restart analysing BPM
}
})
realtimeAnalyzerNode.port.onmessage = (event) => {
if (event.data.message === 'BPM') {
console.log('BPM', event.data.result);
}
if (event.data.message === 'BPM_STABLE') {
console.log('BPM_STABLE', event.data.result);
}
};
Analyze the BPM from files located in your desktop, tablet or mobile !
import * as realtimeBpm from 'realtime-bpm-analyzer';
input[type=file]
to get the files you want.<input type="file" accept="wav,mp3" onChange={event => this.onFileChange(event)}/>
change
event like so, and analyze the BPM of the selected files. You don't need to be connected to Internet for this to work.function onFileChange(event) {
const audioContext = new AudioContext();
// Get the first file from the list
const file = event.target.files[0];
const reader = new FileReader();
reader.addEventListener('load', () => {
// The file is uploaded, now we decode it
audioContext.decodeAudioData(reader.result, audioBuffer => {
// The result is passed to the analyzer
realtimeBpm.analyzeFullBuffer(audioBuffer).then(topCandidates => {
// Do something with the BPM
console.log('topCandidates', topCandidates);
});
});
});
reader.readAsArrayBuffer(file);
};
Let us know what is your most wanted feature by opening an issue.
The test suite is built on top of karma and is very practical to test new features. Before running tests switch the singleRun
property of karma.config.js
to leave the browser open after the tests.
npm install
npm run prepare
npm test
To launch the test suite, just launch the command below:
open http://localhost:9876
npm test
Note that tests requires real human gesture to be successfully run!
This library was inspired by the Tornqvist project, which was also based on Joe Sullivan's algorithm. Thank you to both of them.