Console commands for automatically sorting music files (mp3, flac, m4a) by artists in separate folders and deduplicating audio.
Read this in Ukrainian: README_uk
-
composer install
-
chmod +x bin/console
-
php bin/console music:all <source_directory> [destination_directory] [--dry-run]
Order:
- music:resort (skipped if destination_directory not provided)
- music:fix-extensions
- music:deduplicate
- music:clean
- music:clean-empty-dirs
-
php bin/console music:resort <source_directory> <destination_directory> [--dry-run]
-
php bin/console music:deduplicate <source_directory> [--dry-run]
-
php bin/console music:fix-extensions <source_directory> [--dry-run]
-
php bin/console music:clean <source_directory> [--dry-run]
-
php bin/console music:clean-empty-dirs <source_directory> [--dry-run]
- Scans the source folder for MP3 files
- Reads metadata of each file
- Extracts artist information from tags
- Handles multiple artists — picks the first one
- Creates folders named after artists
- Moves files into corresponding folders
- Handles errors — skips corrupted files
- Does not change the file system — no files are moved
- Does not create folders — only simulates their creation
- Shows all messages — same as in normal execution
- Displays an action plan — what will be done with each file
- Safe test — check the result without risk
- Looks in tags:
artist
,albumartist
,band
,performer
- Splits multiple artists by:
;
,,
,/
,&
,feat.
,ft.
,featuring
- Sanitizes folder names (removes invalid characters)
- Limits folder name length (100 characters)
- Files without metadata — skipped
- Corrupted MP3 files — skipped
- Files without artist information — skipped
- Filename conflicts — automatically renamed
├── bin/
│ └── console # Console application entry point
├── config/
│ └── app.php # App configuration (locale, debug)
├── src/
│ ├── Command/
│ │ ├── ResortMp3Command.php # Resort music by artists
│ │ ├── DeduplicateMp3Command.php # Remove duplicate audio files
│ │ ├── CleanMp3Command.php # Clean invalid/corrupted files
│ │ ├── CleanEmptyDirsCommand.php # Remove empty directories
│ │ ├── FixExtensionsCommand.php # Fix file extensions by metadata
│ │ └── RunAllCommand.php # Run all steps sequentially
│ ├── Service/
│ ├── Exception/
│ └── Helpers/
├── lang/
├── samples/ # Example folders and files
├── composer.json # Project dependencies
├── LICENSE.md # License
└── README.md # Documentation
- PHP 8.4+ — minimum PHP version
- symfony/console — console interface
- symfony/finder — file search
- symfony/filesystem — filesystem operations
- All messages are localized via the global function
__()
and translation files in thelang
directory (e.g.,lang/en/console.php
). - Default locale —
en
(seeconfig/app.php
→default_lang
). - You can change the locale via .env:
DEFAULT_LANG=uk
, or in code:\MusicResort\Service\LocalizationService::setLocale('uk')
. - To add a new language: create the directory
lang/<locale>/
and the translation fileconsole.php
with the same keys.
Example .env:
# Force dry-run for all commands
DEBUG=true
# CLI interface locale
DEFAULT_LANG=en
MP3 File Resorting
==================
! [NOTE] Created artist folder: The Beatles
! [NOTE] Created artist folder: Queen
! [WARNING] Skipped file corrupted.mp3: No artist information found in metadata
3/3 [============================] 100%
[OK] MP3 resorting completed!
[OK] Processed files: 2
[OK] Skipped files (errors): 1
php bin/console music:resort --help
php bin/console music:deduplicate --help
php bin/console music:fix-extensions --help
php bin/console music:clean --help
php bin/console music:clean-empty-dirs --help
php bin/console music:resort <source> <destination> --dry-run
php bin/console music:deduplicate <source> --dry-run
php bin/console music:fix-extensions --dry-run
php bin/console music:clean --dry-run
php bin/console music:clean-empty-dirs --dry-run
php bin/console --version
php bin/console list
There are currently no automated tests in this repository. Below is the planned structure and scenarios that may be added later.
The project will include a full set of tests for code quality, written with the Pest framework.
tests/
├── Unit/ # Unit tests
│ └── ResortMp3CommandTest.php
├── Integration/ # Integration tests
│ └── ResortMp3CommandIntegrationTest.php
└── Fixtures/ # Helper classes for tests
└── Mp3TestHelper.php
-
composer install
-
php vendor/bin/pest
-
php vendor/bin/pest tests/Unit
-
php vendor/bin/pest tests/Integration
-
php vendor/bin/pest --verbose
Unit tests:
sanitizeFolderName()
— folder name sanitizationextractArtist()
— artist extraction- Handling special characters
- Handling multiple artists
- Handling long names
Integration tests:
- Full command execution flow
- Error handling (non-existent folders)
- Destination folder creation
- Handling empty folders
- Handling invalid MP3 files
- Command configuration
Test data:
- Generating valid MP3 files with metadata
- Testing edge cases
- Handling Unicode characters
- Files with different tag formats
Tests are configured via tests/Pest.php
:
- Autoloading through
vendor/autoload.php
- Using
PHPUnit\\Framework\\TestCase
for all tests - Colored output
- Support for datasets and functional tests
- Code coverage for the
src/
directory
- Back up your files before use
- Check permissions for destination folders
- Use absolute paths to avoid errors
- Files with errors may require manual handling