A multithreaded python script to recursively recompress or verify flac files and calculate replay gain tags
I wrote this because my music converter was out of date and updating the flac encoder was paywalled.
Initially this script only used the flac cli to recompress all .flac files in all subdirectories with the highest compression, verify their integrity and set a fixed padding.
When recompressing, temporary files are created and the original files are only overwritten if no decoding errors occurred.
Then I also included rsgain to calculate and write replay gain tags to all music files (not only flac files) in all subdirectories.
To speed things up I added multithreading support for recompression and replay gain calculation.
Finally when I was happy with the performance and pondered making this available to others, I added a progress bar, a separate test mode and logging as I suspect that most people don't like watching a blank command line for minutes while the script does its thing.
What can this script do?
- recursively scan for .flac files in a given directory
- scan for .flac files in a single given directory
- recompress all .flac files with max compression, a fixed padding of 4KB and verification via flac CLI
- test all .flac files for decoding errors via flac CLI
- calculate and save replay gain tags for all music files recursively via rsgain
- display a progress bar while scanning directories and recompressing/testing
- log errors while recompressing/testing to console or to file
Required:
Optional:
- when using -r to calculate replay gain tags, rsgain must be on PATH
- when using -p to show progress bars, tqdm must be installed, I used
pip3 install tqdm
If flac or rsgain are not on PATH, the script will complain and (if on Windows) open the environment variables settings with instructions on how to add them to PATH.
You can either download/clone the entire repository and extract "flacr.py" or you can copy the raw contents of flacr.py, paste them into a .py file and save it that way.
If you want to be able to call it from anywhere on your system (which is more convenient than supplying a path via -d), you can add it to your PATH.
usage: flacr.py [-h] [-d [DIRECTORY]] [-l] [-m [MULTI_THREADED]] [-p] [-Q] [-r] [-s] [-t]
Scan for .flac files in subdirectories, recompress them and optionally calculate replay gain tags.
options:
-h, --help show this help message and exit
-d [DIRECTORY], --directory [DIRECTORY]
The directory that will be recursively scanned for .lrc and .txt files.
-l, --log Log errors during recompression or testing to flacr.log.
-m [MULTI_THREADED], --multi_threaded [MULTI_THREADED]
The number of threads used during conversion and replay gain calculation, default: 1.
-p, --progress Show progress bars during scanning/recompression/testing. Useful for huge directories.
Requires tqdm, use "pip3 install tqdm" to install it.
-Q, --quick Equal to using -m with the max available threadcount, -r to calculate replay gain values and
-p to display a progress bar.
-r, --rsgain Calculate replay gain values with rsgain and save them in the audio file tags.
-s, --single_folder Only scan the current folder for flac files to recompress, no subdirectories.
-t, --test Skip recompression and only log decoding errors to console or log when used with -l.
When called without -t (overwrites music files)
Recompression mode:
Uses flac.exe to recompress all .flac files, creates temporary files in the same folder by appending ".tmp" to the filename and only replaces the original files if no errors occurred during decoding. If errors occurred, they are logged and the temporary file is deleted. In that case the original file remains untouched.
This mode uses the highest level of compression (8), verifies the written files via checksum and also adds a padding of 4096 bytes.
flac command used:
flac --best --verify --padding=4096 --silent
-m, --multi-threaded INT (optional, default=1, min=1, max=thread count of the CPU)
Specify the number of threads which will be used during recompression, verification and replay gain calculation.
Can drastically increase performance depending on the kind of storage the music resides on.
For SSDs I recommend using as many threads as your CPU has.
For HDDs, I would not go above 5-8 threads as that may decrease performance by increasing seek times.
When in doubt, try and compare performance.
Notice that rsgain will always be called with at least 2 threads (even if called with -m 1) because of a Windows cli limitation that decreases the performance of rsgain if it is called with only 1 thread.
-d, --directory PATH (optional, default=".")
When run without -d, the script will be called in the folder it was executed from.
If -d is supplied, it must be followed by a valid path to a directory, which will be scanned for .flac files.
-t, --test (optional, skips recompression, only reads music files)
Test Mode, all found .flac files are decoded via flac CLI with as many threads as specified via -m and errors are logged.
flac command used:
flac -t --silent
-r, --rsgain (optional, writes to tags of music files)
Calls rsgain in easy mode in the root directory with as many threads as specified via -m. Rsgain then recursively calculates and saves replay gain tags to all music files in all subdirectories. Consult the Easy Mode documentation to learn what it does.
rsgain command used:
rsgain easy
-l, --log
Log errors during recompression or testing to flacr.log.
-p, --progress (optional)
Show progress bars during scanning, testing and recompression. Useful for huge directories.
-Q, --quick (optional)
Alias for -r -p and -m with all available threads to quickly recompress and calculate replay gain tags.
-
log errors to console, 4 threads
flacr.py -t -m 4
-
log to file instead
flacr.py -tl -m 4"
-
with progress bar
flacr.py -tlp -m 4
-
with directory
flacr.py -tlp -m 4 -d "D:\Test"
-
log errors to console, 4 threads
flacr.py -m 4
-
log to file instead
flacr.py -l -m 4
-
with progress bar
flacr.py -lp -m 4
-
with directory
flacr.py -lp -m 4 -d "D:\Test"
-
use all available threads and display progress bars
flacr.py -Q
-
log errors to console, 4 threads
flacr.py -r -m 4
-
log to file instead
flacr.py -rl -m 4
-
with progress bar
flacr.py -rlp -m 4
-
with directory
flacr.py -rlp -m 4 -d "D:\Test"
If you want to use different encoding settings, search for this comment and edit the arguments that are passed to flac in the line below it:
# Define the re-encoding command
If you want to calculate replay gain in a different way, search for this comment and edit the arguments that are passed to rsgain in the line below it:
# Define the replay gain calculation command