JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1394
  • Score
    100M100P100Q121348F
  • License MIT

This dependency free library can analyze the BPM (Tempo) of an audio/video node or any stream in realtime on your browser

Package Exports

  • realtime-bpm-analyzer
  • realtime-bpm-analyzer/dist/index.esm.js
  • realtime-bpm-analyzer/dist/index.js

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 (realtime-bpm-analyzer) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Realtime BPM Analyzer

XO code style npm npm CI Actions Status Join the chat at https://gitter.im/realtime-bpm-analyzer/Lobby

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.

Getting started

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.

Features

  • Dependency-free library that utilizes the Web Audio API to analyze audio or video sources and provide accurate BPM detection.
  • Can be used to analyze audio or video nodes, streams as well as files.
  • Allows you to compute the BPM while the audio or video is playing.
  • Lightweight and easy to use, making it a great option for web-based music production and DJing applications.

Usages

If you encounter issues along the way, remember we have a discord server and a chat !

Realtime (stream/playing) strategy

Mesure or detect the BPM from a stream or a player ? Meaning that it is technically a stream. The library provide an AudioWorkletProcessor that will compute BPM while the stream is distributed.

This example shows how to deal with a simple audio node.

  1. An AudioNode to analyze. So something like this:
<audio src="./new_order-blue_monday.mp3" id="track"></audio>
  1. Create the AudioWorkletProcessor with createRealTimeBpmProcessor, create and pipe the lowpass filter 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);

// Lowpass filter
const filter = audioContext.createBiquadFilter();
filter.type = 'lowpass';

// Connect stuff together
source.connect(filter).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);
  }
};
  1. You also need to expose the file dist/realtime-bpm-processor.js (already bundled) to your public root diretory. Typically, this file must be available at http://yourdomain/realtime-bpm-processor.js.
// For NextJS see your next.config.js and add this:
// You also need to install `npm install copy-webpack-plugin@6.4.1 -D`
// Note that the latest version (11.0.0) didn't worked properly with NextJS 12
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
  webpack: config => {
    config.plugins.push(
      new CopyPlugin({
        patterns: [
          {
            from: './node_modules/realtime-bpm-analyzer/dist/realtime-bpm-processor.js',
            to: path.resolve(__dirname, 'public'),
          },
        ],
      },
      ));

    return config;
  },
};

Local/Offline strategy

Analyze the BPM from files located in your desktop, tablet or mobile !

  1. Import the library
import * as realtimeBpm from 'realtime-bpm-analyzer';
  1. Use an input[type=file] to get the files you want.
<input type="file" accept="wav,mp3" onChange={event => this.onFileChange(event)}/>
  1. You can listen the 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) {
  // Get the first file from the list
  const file = event.target.files[0];
  const reader = new FileReader();
  reader.addEventListener('load', () => {
    const audioContext = new window.AudioContext();
    // 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);
};

Development

npm install
npx husky install
npm test

Tests & Coverage

To launch the test suite, just launch the command below:

npm test
npm run test:report

Credits

This library was inspired by the Tornqvist project, which was also based on Joe Sullivan's algorithm. Thank you to both of them.