Unified CLI for reading, embedding, extracting, cleaning, and inspecting LRC lyrics in MP3 files.
- Python 3.10+
- mutagen - audio metadata library
Note
Pre-built binaries for Linux, Windows, and macOS are available on the releases page.
Create a virtual environment, install dependencies, and build with PyInstaller:
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pyinstaller lrc_tools.specThe binary will be at dist/lrc_tools. Copy it anywhere on your PATH:
cp dist/lrc_tools ~/.local/bin/Each script can be run without building:
python3 src/lrc_tools.py --helpAll examples below assume the binary lrc_tools is on your PATH.
Replace lrc_tools with python3 src/lrc_tools.py if running from source.
# Show available subcommands
lrc_tools --help
# Get help for a specific subcommand
lrc_tools read --help
lrc_tools embed --help
lrc_tools extract --help
lrc_tools clean --help
lrc_tools inspect --helpRead embedded lyrics from an MP3 directly to stdout. Ideal for piping into other tools.
# Print summary of available lyrics (to stderr)
lrc_tools read song.mp3
# Output timed lyrics (SYLT) as LRC format
lrc_tools read song.mp3 timed
# Output plain lyrics (USLT) as plain text
lrc_tools read song.mp3 plain
# Include language code header on the first line
lrc_tools read song.mp3 timed --include-lang
lrc_tools read song.mp3 plain --include-lang
# Pipe
lrc_tools read song.mp3 timed | grep "love"When no kind is specified, a summary is printed to stderr showing which lyric types are available.
The --include-lang flag prepends a Language: xx header line using the resolved
2-letter ISO 639-1 code (e.g. Language: ja for Japanese, Language: en for English).
Embed LRC lyrics into an MP3 as SYLT (synchronized) and/or USLT (unsynchronized) frames.
# Embed with auto-discovered LRC file
lrc_tools embed song.mp3
# Specify LRC file explicitly
lrc_tools embed song.mp3 lyrics.lrc
# Override language (3-letter ISO 639-2 code)
lrc_tools embed song.mp3 --lang kor
# Modify original MP3 instead of creating a copy
lrc_tools embed song.mp3 --in-place
# Write to a specific output file
lrc_tools embed song.mp3 --output tagged.mp3
# Skip embedding timed (SYLT) or plain (USLT) lyrics
lrc_tools embed song.mp3 --no-timed
lrc_tools embed song.mp3 --no-plain
# Preview without writing
lrc_tools embed song.mp3 --dry-runIf no LRC file is provided, it auto-discovers one by globbing {stem}*.lrc (e.g. song.ko.lrc for song.mp3). Language is auto-detected from the filename suffix (e.g. .ko.lrc -> kor), and defaults to eng.
Extract embedded SYLT/USLT lyrics from an MP3 to an LRC file.
# Extract to auto-named file (e.g. song.en.lrc)
lrc_tools extract song.mp3
# Specify output path
lrc_tools extract song.mp3 --output lyrics.lrc
# Preview what would be written
lrc_tools extract song.mp3 --dry-runOutput is named {stem}.{lang_2letter}.lrc by default (e.g. song.en.lrc). SYLT is preferred over USLT when both are present.
Remove SYLT/USLT frames from an MP3.
# Remove all lyrics frames
lrc_tools clean song.mp3
# Remove only timed (SYLT) or only plain (USLT) lyrics
lrc_tools clean song.mp3 --timed-only
lrc_tools clean song.mp3 --plain-only
# Skip confirmation prompt
lrc_tools clean song.mp3 --yes
# Preview what would be removed
lrc_tools clean song.mp3 --dry-runConfirms before modifying by default. Use --yes or -y to skip.
Inspect an MP3 or LRC file and print its type classification.
# Check an MP3
lrc_tools inspect song.mp3
# SYLT+USLT: song.mp3
# SYLT: song.mp3
# USLT: song.mp3
# NO_LYRICS: song.mp3
# Check an LRC file
lrc_tools inspect lyrics.lrc
# TIMED: lyrics.lrc
# PLAIN: lyrics.lrc
# EMPTY: lyrics.lrc