amusic is a command-line music utility for the care and feeding of local music
libraries.
Initially inspired by rsgain (especially its easy mode), its early evolution
is focused on augmenting its capabilities with generating and embedding AcoustID
fingerprints.
- ReplayGain generation β Calculates and embeds ReplayGain metadata. This helps audio players avoid the common problem of having to manually adjust volume levels between tracks when playing audio from albums that have been mastered at different loudness levels.
- AcoustID Fingerprint Generation β Calculates and embeds an AcoustID
fingerprint (
ACOUSTID_FINGERPRINTtag). This uniquely identifies an audio file (typically a music track), which will later help associate the audio file with metadata including Title, Artist, Album, and lots more. - High-quality AAC encoding β On macOS,
amusiccan encode lossless audio (FLAC, WAV, ALAC) to audibly-transparent.m4afiles using Apple's Core Audio framework. - Intelligent Folder Processing β Automatically treats folders as albums by default, with support for processing entire music libraries organized by artist/album hierarchy.
- Parallel Processing β Uses worker pools to process multiple tracks concurrently for improved performance.
- Unified Processing β Process tracks once with multiple operations (encoding, ReplayGain, AcoustID) in a single pass.
- Force Overwrite β Optionally, users can force AcoustID fingerprints to be
re-calculated and overwritten even for files that already have them using the
--forceflag. - Quiet Mode β Use the
-q/--quietflag to suppress detail displayed during processing. Errors and the final summary report are still displayed. - Summary Report β After all files are processed, a summary is shown detailing the number of files successfully processed, skipped, or failed.
- π§ Apple SoundCheck generation β Calculates and embeds Apple SoundCheck metadata, which is Apple's equivalent of ReplayGain.
The script queries the AcoustID web service using the generated fingerprint and
an AcoustID API key. You can provide your API key via the --api-key <key>
option or by setting the ACOUSTID_API_KEY environment variable:
# Set your key in the environment (once per session)
export ACOUSTID_API_KEY=your_api_key_here
# Then run without repeating the flag:
amusic <file1> [file2 ...]Alternatively, you can pass the key directly:
amusic --api-key $ACOUSTID_API_KEY <file1> [file2 ...]It retrieves and embeds the ACOUSTID_ID (the UUID from the AcoustID database);
it does NOT fetch or embed other metadata (like track title, artist, album), but
this may be supported in a future release.
amusic requires only Deno to run. All audio metadata operations are handled by
the built-in taglib-wasm library, and the required external tools are included
as vendor binaries:
- Deno: The runtime for the script. Installation instructions can be found at https://deno.land/.
- taglib-wasm: Universal audio metadata library (included as npm dependency). Handles all tag reading/writing operations for MP3, M4A/MP4, FLAC, OGG, WAV, and more.
- fpcalc: Used for generating AcoustID fingerprints. Native binaries are
included in the
vendordirectory for all supported platforms. - rsgain: Used for ReplayGain analysis and metadata tagging. Native binaries
are included in the
vendordirectory for all supported platforms.
No external tools need to be installed - everything is self-contained within the project.
Once the Homebrew tap is set up, you can install amusic with:
brew tap CharlesWiltgen/tap
brew install amusicTo update to the latest version:
brew update
brew upgrade amusicDownload the latest release for your platform from the Releases page. Pre-built binaries are available for:
- macOS (Apple Silicon M1/M2/M3 and Intel)
- Linux (x86_64)
- Windows (x86_64)
Extract the archive and optionally move the binary to a location in your PATH.
-
Ensure Deno is installed.
-
Clone this repository:
git clone https://github.com/CharlesWiltgen/amusic.git cd amusic -
(Optional) Build a standalone executable (includes the platform-specific vendor binaries):
deno task build
Note (macOS)
The build task will automatically remove any quarantine attributes and perform an ad-hoc code signing of the generateddist/amusicbinary so that the embedded vendor tools (fpcalc/rsgain) can be executed without encountering "No such file or directory (os error 2)".
Note: If you've built a standalone executable using
deno task build, you can run it directly fromdist/amusic:
./dist/amusic [options] <file1> [file2 ...]To use amusic, navigate to the directory containing amusic.ts and run the
script using deno run. Provide the paths to the audio files you want to
process as arguments.
Syntax:
deno run --allow-read --allow-run --allow-write --allow-env --allow-net amusic.ts [options] <file1> [file2 ...]--allow-read: Required to read audio files.--allow-run: Required to execute vendor binaries (fpcalcandrsgain).--allow-write: Required to write updated audio files with new tags.--allow-env: Required to read environment variables likeACOUSTID_API_KEY.--allow-net: Required for AcoustID API lookups (optional, only needed when using API key).<file1> [file2 ...]: One or more paths to audio files to be processed.
Options:
-f, --force: Force recalculation and saving of the AcoustID fingerprint even if existing AcoustID tags are found in the file. Without this flag, files with existing tags will be skipped.-q, --quiet: Suppress informational output during processing. Error messages and the final summary report will still be displayed.--show-tags: Display existingACOUSTID_IDandACOUSTID_FINGERPRINTtags for the specified files and then exit. This option does not modify files or perform any online lookups.--dry-run: Simulate the entire tagging process, including fingerprint generation and AcoustID API lookups (if an--api-keyis provided), but do not make any actual changes to the audio files. This is useful for testing or previewing what actions would be performed. A notice will be shown in the summary report if a dry run was performed.
After processing all files, a summary report is displayed, showing the number of files successfully processed, skipped, and failed.
Process files to generate and embed AcoustID fingerprints:
amusic [options] <files...>Process a music library organized by album folders. Calculates ReplayGain for each album and AcoustID for each track:
amusic easy <library> [options]Process audio files with multiple operations in a single pass. By default, folders are treated as albums:
amusic process [options] <paths...>Options:
--encode: Encode files to M4A/AAC format--replay-gain: Calculate and apply ReplayGain metadata--acoust-id: Generate and embed AcoustID fingerprints--singles <patterns...>: Folder patterns to treat as singles instead of albums-o, --output-dir <dir>: Output directory for encoded files--force-lossy-transcodes: Allow encoding from lossy formats (not recommended)
Encode lossless audio files to M4A/AAC format (macOS only):
amusic encode [options] <files...>Options:
-o, --output-dir <dir>: Output directory for encoded files--flatten-output: Put all output files in a single directory--force-lossy-transcodes: Allow encoding from lossy formats (MP3, OGG)
By default, amusic intelligently processes folders:
- Leaf folders (containing audio files but no subfolders) are treated as albums
- Parent folders (containing subfolders) have each subfolder processed as potential albums
- Singles override: Use
--singlespatterns to treat specific folders as collections of individual tracks
This makes it easy to process entire music libraries organized by artist/album hierarchy.
amusic uses both directory structure and metadata to determine whether tracks
should be processed as albums or singles:
Core Principle: An album is a group of 2+ audio files that share the same album tag.
Detection Rules:
-
Album Requirements
- Must have 2+ files with identical album tags (non-empty)
- Artist can vary (supports compilation albums)
- Files must be in the same directory
-
Single Classification A file is treated as a single if:
- It has no album tag (empty/missing)
- It's the only file with that album tag in its directory
- It's in a directory but doesn't meet album requirements
-
Directory Scanning
- When scanning a directory, files are grouped by album tag
- Each group with 2+ files becomes an album
- Remaining files become singles
-
Special Cases
- Mixed content: A directory can contain multiple albums AND singles
- Compilation albums: Different artists + same album tag = valid album
Example Scenarios:
/Music/Album1/
βββ track1.mp3 (album: "Greatest Hits")
βββ track2.mp3 (album: "Greatest Hits")
βββ track3.mp3 (album: "Greatest Hits")
β Result: 1 album with 3 tracks
/Music/Mixed/
βββ song1.mp3 (album: "Album A")
βββ song2.mp3 (album: "Album A")
βββ song3.mp3 (album: "Album B")
βββ song4.mp3 (no album tag)
βββ song5.mp3 (album: "Album C")
β Result: 1 album ("Album A" with 2 tracks) + 3 singles
/Music/Singles/
βββ track1.mp3 (album: "Solo Album")
βββ track2.mp3 (album: "Different Album")
β Result: 2 singles
-
Generate and add fingerprint to an audio file:
amusic "./path/to/your/music file.mp3" -
Process an album folder: Calculate and embed ReplayGain metadata and generate AcoustID fingerprints for all tracks in a single folder:
amusic process --replay-gain --acoust-id "/path/to/album_folder" -
Process multiple artists with some singles folders:
amusic process --encode --replay-gain --acoust-id \ --singles "Singles" --singles "Compilations" \ "/Music/Prince" "/Music/Madonna" "/Music/Singles"
-
Encode a library to a new location preserving structure:
amusic encode -o "/path/to/output" "/path/to/lossless/library"
-
Easy Mode: Process entire music library:
amusic easy /path/to/music/library --api-key $ACOUSTID_API_KEY -
Process with unified command for maximum efficiency:
# Process everything in one pass: encode to M4A, calculate ReplayGain, and add AcoustID amusic process --encode --replay-gain --acoust-id \ --output-dir "/Music/Encoded" \ "/Music/Lossless/Artist1" "/Music/Lossless/Artist2"
Contributions are welcome! If you'd like to help improve amusic or add new
features, please feel free to:
- Report a bug or suggest a feature by opening an issue.
- Check existing issues for ideas or ongoing discussions.
- Submit a pull request with your improvements.
When contributing code, please ensure you run deno fmt and deno lint before
submitting.
# Run from source
deno task start [options] <files>
# Run tests
deno task test
# Check formatting and linting
deno task check
# Fix formatting
deno task fix
# Build executable
deno task build
# Bump version (patch, minor, major, or specific version)
deno task bump patchReleases are automated via GitHub Actions. See RELEASING.md for details.
This project is licensed under the MIT License - see the LICENSE file for details.