AutoMixer 🎵
Automatic DJ-style audio mixer that sequentially blends MP3 files with BPM detection, pitch adjustment, and beat synchronization.
Features
- 🎯 Automatic BPM Detection - Analyzes audio files to detect tempo using beat detection algorithms
- 🔄 Beat Synchronization - Aligns beats between tracks for seamless transitions
- 🎚️ Pitch-Preserving Tempo Adjustment - Adjusts tempo while maintaining original pitch
- 🌊 Smooth Crossfades - Creates professional equal-power crossfades between tracks
- 📊 Audio Analysis - Extracts metadata, duration, and audio characteristics
- 🖥️ CLI & API - Use from command line or integrate into your Node.js projects
Prerequisites
- Node.js >= 18.0.0
- FFmpeg with FFprobe (required for audio processing)
Installing FFmpeg
# macOS
brew install ffmpeg
# Ubuntu/Debian
sudo apt install ffmpeg
# Windows (with Chocolatey)
choco install ffmpeg
# Windows (with winget)
winget install FFmpeg
Installation
Global Installation (CLI)
npm install -g automixer
Local Installation (Library)
npm install automixer
CLI Usage
Mix Multiple Tracks
# Basic usage - mix tracks in order
automixer mix track1.mp3 track2.mp3 track3.mp3 -o my_mix.mp3
# Specify crossfade duration (default: 8 seconds)
automixer mix track1.mp3 track2.mp3 -c 12 -o output.mp3
# Set a specific target BPM
automixer mix track1.mp3 track2.mp3 -b 128 -o output.mp3
# Allow pitch to change with tempo (faster processing)
automixer mix track1.mp3 track2.mp3 --no-preserve-pitch -o output.mp3
Analyze Tracks
# Analyze a single track
automixer analyze track.mp3
# Analyze multiple tracks
automixer analyze track1.mp3 track2.mp3
# Output as JSON
automixer analyze track.mp3 --json
Check System Requirements
automixer check
CLI Options
| Option | Description | Default |
|---|---|---|
-o, --output <file> |
Output file path | mix_output.mp3 |
-c, --crossfade <seconds> |
Crossfade duration | 8 |
-b, --bpm <number> |
Target BPM | Auto-detect |
--max-bpm-change <percent> |
Maximum BPM change allowed | 8 |
--no-preserve-pitch |
Allow pitch to change with tempo | Pitch preserved |
-q, --quiet |
Suppress progress output | Show progress |
API Usage
Basic Example
import AutoMixer from 'automixer';
const mixer = new AutoMixer({
crossfadeDuration: 8, // seconds
preservePitch: true,
maxBPMChange: 8 // percent
});
// Mix multiple tracks
await mixer.mix(
['track1.mp3', 'track2.mp3', 'track3.mp3'],
'output.mp3'
);
Advanced Usage with Events
import { AutoMixer } from 'automixer';
const mixer = new AutoMixer({
crossfadeDuration: 10,
targetBPM: 128,
preservePitch: true
});
// Listen to events
mixer.on('analysis:track:start', ({ index, filepath }) => {
console.log(`Analyzing track ${index + 1}: ${filepath}`);
});
mixer.on('analysis:track:complete', ({ index, trackInfo }) => {
console.log(`Track ${index + 1}: ${trackInfo.bpm} BPM`);
});
mixer.on('mix:bpm', ({ targetBPM }) => {
console.log(`Target BPM: ${targetBPM}`);
});
mixer.on('mix:render:progress', ({ current, total, message }) => {
console.log(`Progress: ${current}/${total}`);
});
mixer.on('mix:complete', ({ outputPath }) => {
console.log(`Mix saved to: ${outputPath}`);
});
// Run the mix
await mixer.mix(['track1.mp3', 'track2.mp3'], 'output.mp3');
Step-by-Step Processing
import { AutoMixer } from 'automixer';
const mixer = new AutoMixer();
// Add tracks
mixer.addTracks(['track1.mp3', 'track2.mp3', 'track3.mp3']);
// Analyze tracks
const analyzedTracks = await mixer.analyzeTracks();
// Log track information
for (const track of analyzedTracks) {
console.log(`${track.filename}: ${track.bpm} BPM, ${track.duration}s`);
}
// Get optimal BPM
const targetBPM = mixer.calculateOptimalBPM();
console.log(`Optimal BPM: ${targetBPM}`);
// Create the mix
await mixer.createMix('output.mp3');
Using Individual Components
import { BPMDetector, AudioAnalyzer, PitchShifter } from 'automixer';
// Detect BPM
const detector = new BPMDetector();
const { bpm, beats, confidence } = await detector.detect('track.mp3');
console.log(`BPM: ${bpm} (confidence: ${confidence})`);
// Get audio metadata
const analyzer = new AudioAnalyzer();
const metadata = await analyzer.getMetadata('track.mp3');
console.log(`Duration: ${metadata.duration}s`);
// Adjust tempo
const shifter = new PitchShifter();
const adjustedPath = await shifter.adjustTempo('track.mp3', 1.1, true);
console.log(`Tempo-adjusted file: ${adjustedPath}`);
API Reference
AutoMixer
Main class that orchestrates the mixing process.
Constructor Options
| Option | Type | Default | Description |
|---|---|---|---|
crossfadeDuration |
number | 8 |
Crossfade duration in seconds |
targetBPM |
number | null |
Target BPM (auto-detect if null) |
preservePitch |
boolean | true |
Preserve pitch when changing tempo |
maxBPMChange |
number | 8 |
Maximum BPM change percentage |
outputFormat |
string | 'mp3' |
Output format |
outputBitrate |
number | 320 |
Output bitrate in kbps |
Methods
addTracks(filepaths)- Add tracks to the queueclearTracks()- Clear all tracksanalyzeTracks()- Analyze all tracks (returns track info)calculateOptimalBPM()- Calculate the optimal target BPMcreateMix(outputPath)- Create the final mixmix(inputFiles, outputPath)- Full process in one call
Events
analysis:start- Analysis startedanalysis:track:start- Individual track analysis startedanalysis:track:complete- Individual track analysis completedanalysis:complete- All analysis completedmix:start- Mixing startedmix:bpm- Target BPM calculatedmix:prepare:start- Track preparation startedmix:prepare:complete- Track preparation completedmix:render:start- Rendering startedmix:render:progress- Rendering progress updatemix:complete- Mixing completed
BPMDetector
Detects BPM and beat positions in audio files.
const detector = new BPMDetector({ minBPM: 60, maxBPM: 200 });
const { bpm, beats, confidence } = await detector.detect('track.mp3');
AudioAnalyzer
Extracts metadata and analyzes audio characteristics.
const analyzer = new AudioAnalyzer();
const metadata = await analyzer.getMetadata('track.mp3');
// { duration, sampleRate, channels, bitrate, codec, format, tags }
PitchShifter
Adjusts tempo and pitch of audio files.
const shifter = new PitchShifter();
// Adjust tempo (preserving pitch)
await shifter.adjustTempo('input.mp3', 1.1, true);
// Shift pitch (in semitones)
await shifter.shiftPitch('input.mp3', 2);
// Adjust both
await shifter.adjustTempoAndPitch('input.mp3', 1.1, 2);
TrackMixer
Handles crossfading and track mixing.
const mixer = new TrackMixer({
crossfadeDuration: 8,
crossfadeCurve: 'log' // 'linear', 'log', 'sqrt', 'sine', 'exponential'
});
How It Works
BPM Detection
AutoMixer uses the music-tempo library combined with FFmpeg for BPM detection:
- Audio is decoded to raw PCM samples using FFmpeg
- A 30-second analysis window is extracted (skipping intro)
- Beat detection algorithm identifies tempo and beat positions
- BPM is normalized to a standard range (60-200)
- Beats are extrapolated across the full track
Beat Matching
The mixing algorithm:
- Analyzes all input tracks to detect BPM
- Calculates optimal target BPM (median of all tracks)
- Adjusts each track's tempo to match target BPM
- Finds beat-aligned transition points
- Creates equal-power crossfades at transition points
Tempo Adjustment
Tempo adjustment uses FFmpeg's audio filters:
- With pitch preservation: Uses the rubberband filter for high-quality time-stretching
- Without pitch preservation: Uses the atempo filter for simple speed changes
Performance Tips
- Use consistent BPM tracks: Mixing tracks with similar BPMs produces better results
- Allow larger BPM changes: Increase
maxBPMChangeif tracks have very different tempos - Longer crossfades: Use longer crossfades (10-15s) for smoother transitions
- Skip pitch preservation: Use
--no-preserve-pitchfor faster processing when pitch shift is acceptable
Troubleshooting
FFmpeg Not Found
Make sure FFmpeg is installed and available in your PATH:
ffmpeg -version
Poor BPM Detection
Some tracks may have ambiguous tempos. You can:
- Set a specific target BPM with
-boption - Increase
maxBPMChangeto allow larger adjustments
Audio Quality Issues
- Ensure source files are high quality
- Use higher bitrate:
outputBitrate: 320 - Use pitch-preserved tempo adjustment
License
MIT License - see LICENSE file for details.
Repository
Project repository: https://github.com/manalejandro/automixer
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Changelog
v1.0.0
- Initial release
- BPM detection and beat synchronization
- Pitch-preserving tempo adjustment
- Smooth crossfade mixing
- CLI and API interfaces