A powerful application for organizing and managing large music collections. MP3Org helps you find and remove duplicate songs, organize files into structured folders, and edit metadata for better collection management.
Now available as a modern web application! The project has been migrated from JavaFX desktop to Spring Boot + React web interface.
- Directory-Based Duplicate Resolution - Group duplicates by directory and resolve entire folder conflicts at once (Issue #92)
- Smart Bulk Edit - Combobox inputs with suggestions showing values and frequency counts from selected files
- Audio Fingerprinting - Optional Chromaprint integration for acoustic duplicate detection
- Contextual Help System - Built-in documentation with OS-specific setup instructions
- Web UI Migration - Modern React frontend with Spring Boot REST API (Issue #69)
- SQLite Database - Migrated from Apache Derby for better portability (Issue #72)
- Java 21 LTS - Standardized on Java 21 for long-term support
- Real-time Scanning - WebSocket-based progress updates during directory scans
- Comprehensive API - Full REST API for music file management
- Advanced fuzzy matching algorithms find duplicates even when metadata differs slightly
- Audio fingerprinting (optional) uses Chromaprint for acoustic similarity detection
- Directory-based grouping to resolve entire folder conflicts at once
- Configurable similarity thresholds for title, artist, album, and duration
- Text normalization handles artist prefixes, featuring artists, album editions
- Multiple detection presets: Strict, Balanced, Lenient, or Custom settings
- Automatic folder structure creation: Artist/Album/Track-Title format
- Preserves original files while creating organized copies
- Batch processing for large collections
- File type filtering for selective organization
- Search and edit song information across your collection
- Smart bulk editing with combobox suggestions showing distinct values from selected files
- Frequency-based pre-selection automatically selects the most common value
- Year field support in bulk edit alongside artist, album, and genre
- Automatic metadata extraction from file tags
- Support for all common fields: title, artist, album, genre, year, track number
- Separate collections for different music types (personal, work, classical, etc.)
- Profile-specific settings for optimal duplicate detection
- Easy switching between collections
Supports all major audio formats:
- Lossless: FLAC, AIFF, APE, WAV
- Compressed: MP3, M4A (AAC), OGG Vorbis, OPUS, WMA
- Java 21 (LTS) - download from Adoptium or Oracle
- Node.js 18+ (for frontend development)
- Chromaprint (optional, for audio fingerprinting)
Audio fingerprinting requires the Chromaprint library:
macOS (Homebrew):
brew install chromaprintWindows:
- Download from https://acoustid.org/chromaprint
- Extract and add
fpcalc.exeto your PATH
Linux (Ubuntu/Debian):
sudo apt install libchromaprint-toolsLinux (Fedora/RHEL):
sudo dnf install chromaprint-toolsLinux (Arch):
sudo pacman -S chromaprint# With SDKMAN
sdk env
# With jenv
jenv localmacOS / Linux:
git clone https://github.com/richardahasting/MP3Org.git
cd MP3Org
./startWindows:
git clone https://github.com/richardahasting/MP3Org.git
cd MP3Org
start.cmdThis starts both backend and frontend, then opens http://localhost:5173 in your browser.
Press Ctrl+C to stop (or any key on Windows).
macOS / Linux:
./gradle21 buildWindows:
gradle21.cmd buildFrontend (all platforms):
cd frontend
npm run buildThe gradle21 scripts automatically locate Java 21 on your system:
| Platform | Locations Checked |
|---|---|
| macOS | /usr/libexec/java_home -v 21 (system utility) |
| Linux | SDKMAN (~/.sdkman), /usr/lib/jvm/java-21-*, /opt/java/jdk-21*, Homebrew |
| Windows | Program Files (Adoptium, Oracle, Microsoft, Amazon, Zulu, BellSoft) |
If Java 21 is already your default JAVA_HOME, you can use ./gradlew (or gradlew.bat) directly.
MP3Org uses a modern full-stack architecture:
┌─────────────────────────────────────────────────────────────┐
│ React Frontend │
│ ┌─────────┐ ┌──────────┐ ┌────────┐ ┌──────────┐ ┌───────┐ │
│ │Duplicate│ │ Metadata │ │ Import │ │ Organize │ │Config │ │
│ │ Manager │ │ Editor │ │ View │ │ View │ │ View │ │
│ └────┬────┘ └────┬─────┘ └───┬────┘ └────┬─────┘ └───┬───┘ │
└───────┼──────────┼─────────────┼───────────┼──────────┼─────┘
│ │ │ │ │
└──────────┴─────────────┴───────────┴──────────┘
│ HTTP/WebSocket
┌─────────────────────┴─────────────────────────┐
│ Spring Boot REST API │
│ ┌─────────────────────────────────────────┐ │
│ │ Service Layer │ │
│ │ MusicFileService, ScanningService, │ │
│ │ DuplicateService, OrganizationService │ │
│ └────────────────────┬────────────────────┘ │
└───────────────────────┼───────────────────────┘
│
┌───────┴───────┐
│ SQLite Database│
└───────────────┘
MP3Org/
├── src/main/java/org/hasting/
│ ├── MP3OrgWebApplication.java # Spring Boot entry point
│ ├── controller/ # REST API endpoints
│ │ ├── MusicFileController.java
│ │ ├── DuplicateController.java
│ │ └── ScanningController.java
│ ├── service/ # Business logic
│ │ ├── MusicFileService.java
│ │ ├── DuplicateService.java
│ │ └── ScanningService.java
│ ├── dto/ # Data transfer objects
│ │ ├── MusicFileDTO.java
│ │ ├── DirectoryConflictDTO.java
│ │ └── DuplicatePairDTO.java
│ ├── model/ # Domain models
│ └── util/ # Core utilities
├── frontend/
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── duplicates/ # Duplicate manager UI
│ │ │ ├── metadata/ # Metadata editor UI
│ │ │ └── common/ # Shared components
│ │ ├── hooks/ # Custom React hooks
│ │ ├── api/ # API client
│ │ └── types/ # TypeScript types
│ └── tests/ # Puppeteer E2E tests
└── build.gradle.kts # Gradle build configuration
| Endpoint | Method | Description |
|---|---|---|
/api/v1/music |
GET | List all (paginated) |
/api/v1/music/{id} |
GET | Get by ID |
/api/v1/music/{id} |
PUT | Update metadata |
/api/v1/music/{id} |
DELETE | Delete file |
/api/v1/music/{id}/stream |
GET | Stream audio file |
/api/v1/music/search |
GET | Search files |
/api/v1/music/count |
GET | Get total count |
/api/v1/music/bulk |
PUT | Bulk update (artist, album, genre, year) |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/duplicates |
GET | Get duplicate groups |
/api/v1/duplicates/by-directory |
GET | Get directory conflicts |
/api/v1/duplicates/resolve-directory/preview |
POST | Preview directory resolution |
/api/v1/duplicates/resolve-directory/execute |
POST | Execute directory resolution |
| Endpoint | Method | Description |
|---|---|---|
/api/v1/scanning/start |
POST | Start scan (returns sessionId) |
/api/v1/scanning/status/{id} |
GET | Get scan status |
/api/v1/scanning/cancel/{id} |
POST | Cancel scan |
/api/v1/scanning/browse |
GET | Browse server directories |
WebSocket: /ws with /topic/scanning/{sessionId} for real-time progress
macOS / Linux:
# Run backend tests
./gradle21 test
# Run frontend E2E tests
cd frontend
npm run build
npm run preview &
npm testWindows:
REM Run backend tests
gradle21.cmd test
REM Run frontend E2E tests
cd frontend
npm run build
npm run preview
REM In another terminal:
npm test| Setting | Description | Recommended |
|---|---|---|
| Title Similarity | How closely song titles must match | 85% |
| Artist Similarity | How closely artist names must match | 90% |
| Album Similarity | How closely album names must match | 85% |
| Duration Tolerance | Maximum time difference allowed | 10 seconds |
| Audio Fingerprinting | Use acoustic similarity (requires Chromaprint) | Optional |
When enabled, MP3Org uses Chromaprint to generate acoustic fingerprints of your music files. This allows detection of duplicates even when:
- Metadata is completely different
- Files are different encodings of the same recording
- Tags have been modified or corrupted
Requirements:
- Chromaprint must be installed (see installation instructions above)
fpcalcexecutable must be in your system PATH- Initial fingerprint generation may take time for large collections
Contributions are welcome! Please see our open issues:
- Issue #69 - Web UI Migration (completed)
- Issue #70 - API Test Suite
- Issue #72 - SQLite Migration (completed)
- Issue #92 - Directory-Based Duplicate Resolution (completed)
- Fork and clone the repository
- Set Java version:
sdk envorjenv local - Run tests:
./gradlew test - Create a feature branch:
git checkout -b feature/issue-XX-description - Submit a pull request
- Backend: Java 21, Spring Boot 3.4, SQLite, WebSocket
- Frontend: React 18, TypeScript, Vite
- Build: Gradle 8.12, npm
- Testing: JUnit 5, Puppeteer
- Audio: JAudioTagger, Chromaprint (optional)
MP3Org prioritizes your privacy:
- Local processing only - no data sent to external servers
- No telemetry or tracking
- Local database storage using SQLite
- Open source - audit the code yourself
- Spring Boot REST API (Phase 1)
- React frontend foundation (Phase 1)
- SQLite database migration
- Import/Scanning with WebSocket progress (Phase 2)
- Duplicate Detection UI (Phase 3)
- Directory-based duplicate resolution
- Metadata Editor with smart bulk edit (Phase 4)
- Audio fingerprinting support
- Contextual help system
- File Organization UI (Phase 5)
- Configuration UI improvements (Phase 6)
- UI Polish and accessibility (Phase 7)
This project is licensed under the MIT License - see the LICENSE file for details.
- JAudioTagger library for metadata extraction
- Chromaprint for audio fingerprinting
- SQLite for embedded database functionality
- Spring Boot for the backend framework
- React for the modern user interface
Made with care for music lovers who want organized collections
Star this repository if MP3Org helps you organize your music collection!