Merge pull request #801 from TheCaptain989/lidarr-flac2mp3

lidarr: flac2mp3 release 2.3.2
This commit is contained in:
aptalca
2023-12-17 11:55:24 -05:00
committed by GitHub
2 changed files with 118 additions and 39 deletions
+46 -14
View File
@@ -16,11 +16,32 @@ Development Container info:
2. Configure the Docker container with all the port, volume, and environment settings from the *original container documentation* here:
**[linuxserver/lidarr](https://hub.docker.com/r/linuxserver/lidarr "Docker container")**
1. Add a **DOCKER_MODS** environment variable to the `docker run` command, as follows:
- Stable release: `-e DOCKER_MODS=linuxserver/mods:lidarr-flac2mp3`
- Dev/test release: `-e DOCKER_MODS=thecaptain989/lidarr-flac2mp3:latest`
1. Add a **DOCKER_MODS** environment variable to your `compose.yml` file or `docker run` command, as follows:
- Stable release: `DOCKER_MODS=linuxserver/mods:lidarr-flac2mp3`
- Dev/test release: `DOCKER_MODS=thecaptain989/lidarr-flac2mp3:latest`
*Example Docker CLI Configuration*
*Example Docker Compose YAML Configuration*
```yaml
version: "2.1"
services:
lidarr:
image: lscr.io/linuxserver/lidarr
container_name: lidarr
environment:
- PUID=1000
- PGID=1000
- TZ=America/Chicago
- DOCKER_MODS=linuxserver/mods:lidarr-flac2mp3
volumes:
- /path/to/appdata/config:/config
- /path/to/music:/music
- /path/to/downloads:/downloads
ports:
- 8686:8686
restart: unless-stopped
```
*Example Docker Run Command*
```shell
docker run -d \
--name=lidarr \
@@ -34,10 +55,10 @@ Development Container info:
-v /path/to/downloads:/downloads \
--restart unless-stopped \
lscr.io/linuxserver/lidarr
```
```
*Example Synology Configuration*
![flac2mp3](.assets/lidarr-synology.png "Synology container settings")
![flac2mp3](.assets/lidarr-synology.png "Synology container settings")
2. Start the container.
@@ -66,13 +87,12 @@ To supply arguments to the script, you **must** either use one of the **[include
The script may be called with optional command line arguments.
The syntax for the command line is:
`flac2mp3 [{-d|--debug} [<level>]] [{-b|--bitrate} <bitrate> | {-v|--quality} <quality> | {-a|--advanced} "<options>" {-e|--extension} <extension>] [{-f|--file} <audio_file>] [{-k|--keepfile}] [{-o|--output} <directory>] [{-r|--regex} '<regex>'] [{-t|--tags} <taglist>]`
`flac2mp3 [{-b|--bitrate} <bitrate> | {-v|--quality} <quality> | {-a|--advanced} "<options>" {-e|--extension} <extension>] [{-f|--file} <audio_file>] [{-k|--keep-file}] [{-o|--output} <directory>] [{-r|--regex} '<regex>'] [{-t|--tags} <taglist>] [{-l|--log} <log_file>] [{-d|--debug} [<level>]]`
Where:
Option|Argument|Description
---|---|---
-d, --debug|\[\<level\>\]|Enables debug logging. Level is optional.<br/>Default of 1 (low).<br/>2 includes JSON and FFmpeg output.<br/>3 contains even more JSON output.
-b, --bitrate|\<bitrate\>|Sets the output quality in constant bits per second (CBR).<br/>Examples: 160k, 240k, 300000<br/>**Note:** May not be specified with `-v`, `-a`, or `-e`.
-v, --quality|\<quality\>|Sets the output variable bit rate (VBR).<br/>Specify a value between 0 and 9, with 0 being the highest quality.<br/>See the [FFmpeg MP3 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/MP3) for more details.<br/>**Note:** May not be specified with `-b`, `-a`, or `-e`.
-a, --advanced|\"\<options\>\"|Advanced ffmpeg options.<br/>The specified `options` replace all script defaults and are sent directly to ffmpeg.<br/>The `options` value must be enclosed in quotes.<br/>See [FFmpeg Options](https://ffmpeg.org/ffmpeg.html#Options) for details on valid options, and [Guidelines for high quality audio encoding](https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio) for suggested usage.<br/>**Note:** Requires the `-e` option to also be specified. May not be specified with `-v` or `-b`.<br/>![warning] **WARNING:** You must specify an audio codec (by including a `-c:a <codec>` ffmpeg option) or the resulting file will contain no audio!<br/>![warning] **WARNING:** Invalid `options` could result in script failure!
@@ -81,7 +101,9 @@ Option|Argument|Description
-o, --output|\<directory\>|Converted audio file(s) are saved to `directory` instead of being located in the same directory as the source audio file.<br/>The path will be created if it does not exist.
-k, --keep-file| |Do not delete the source file or move it to the Lidarr Recycle bin.<br/>**Note:** This also disables importing the new files into Lidarr after conversion.
-r, --regex|'\<regex\>'|Sets the regular expression used to select input files.<br/>The `regex` value should be enclosed in single quotes and escaped properly.<br/>Defaults to `[.]flac$`.
-l, --log|\<log_file\>|The log filename<br/>Default of /config/log/flac2mp3.txt
-t, --tags|\<taglist\>|Comma separated list of metadata tags to apply automated corrections to.<br/>See [Metadata Corrections](./README.md#metadata-corrections) section.
-d, --debug|\[\<level\>\]|Enables debug logging. Level is optional.<br/>Default of 1 (low).<br/>2 includes JSON and FFmpeg output.<br/>3 contains even more JSON output.
--help| |Display help and exit.
--version| |Display version and exit.
@@ -159,7 +181,7 @@ Then put `/config/flac2mp3-custom.sh` in the **Path** field in place of `/usr/lo
### Environment Variable
The `flac2mp3.sh` script also allows the use of arguments provided by the `FLAC2MP3_ARGS` environment variable. This allows advanced use cases without having to provide a custom script.
For example, the following value would convert any .mp3 to Opus:
For example, the following value in your `docker run` command would convert any .mp3 to Opus:
```
-e FLAC2MP3_ARGS='-a "-vn -c:a libopus -b:a 192k" -e .opus -r "[.]mp3$"'
```
@@ -186,7 +208,7 @@ Using this function, you can easily process all of your audio files in any subdi
#### Script Execution Differences in Batch Mode
Because the script is not called from within Lidarr, expect the following behavior while in Batch Mode:
* *The file name must be specified on the command line*<br/>(The `-f` option places the script in Batch Mode)
* *The filename must be specified on the command line*<br/>(The `-f` option places the script in Batch Mode)
* *Lidarr APIs are not called and its database is not updated.*<br/>This may require a manual import of converted music files or an artist rescan.
* *Original audio files are deleted.*<br/>The Recycle Bin function is not available. (Modifiable using the `-k` option.)
@@ -197,22 +219,23 @@ find /music/ -type f -name "*.flac" | while read file; do /usr/local/bin/flac2mp
```
### Logs
A log file is created for the script activity called:
By default, a log file is created for the script activity called:
`/config/logs/flac2mp3.txt`
This log can be downloaded from Lidarr under *System* > *Log Files*
This log can be downloaded from Lidarr under *System* > *Log Files*. The log filename can be modified with the `--log` command-line option.
Log rotation is performed, with 5 log files of 1MB each kept, matching Lidarr's log retention.
>![danger] **NOTE:** If debug logging is enabled with a level above 1, the log file can grow very large very quickly and is much more likely to be rotated. *Do not leave high-level debug logging enabled permanently.*
#### Metadata Corrections
This feature is not meant for general purpose use. It is only documented for completeness.
This feature is not meant for general purpose use. It is only documented here for completeness.
List of supported tags and metadata corrections that are applied:
|Tag|Original|Correction
|---|---|---
|title|Parenthesis for live\|remix, etc. "()"|Square brackets "\[]"
|disc|1|1/1
|genre|/Pop/|"Pop"
| |/Indie/|"Alternative & Indie"
@@ -221,7 +244,16 @@ List of supported tags and metadata corrections that are applied:
| |/Punk\|Alternative/|"Alternative & Punk"
| |/Rock/|"Rock"
## Credits
# Uninstall
To completely remove the mod:
1. Delete the custom script from Lidarr's *Settings* > *Connect* screen that you created in the [Installation](./README.md#installation) section above.
2. Stop and delete the Lidarr container.
3. Exclude the **DOCKER_MODS** environment variable from your `compose.yaml` file or the `docker run` command when re-creating the Lidarr container.
___
# Credits
This would not be possible without the following:
[Lidarr](https://lidarr.audio/ "Lidarr homepage")
+72 -25
View File
@@ -14,15 +14,18 @@
# stat
# nice
# basename
# dirname
# printenv
# chmod
# tr
# sed
# Exit codes:
# 0 - success; or test
# 1 - no audio tracks detected
# 2 - ffmpeg not found
# 3 - invalid command line arguments
# 4 - log file is not writable
# 5 - specified audio file not found
# 6 - error when creating output directory
# 7 - unknown eventtype environment variable
@@ -58,13 +61,9 @@ Audio conversion script designed for use with Lidarr
Source: https://github.com/TheCaptain989/lidarr-flac2mp3
Usage:
$0 [{-d|--debug} [<level>]] [{-b|--bitrate} <bitrate> | {-v|--quality} <quality> | {-a|--advanced} \"<options>\" {-e|--extension} <extension>] [{-f|--file} <audio_file>] [{-k|--keepfile}] [{-o|--output} <directory>] [{-r|--regex} '<regex>'] [{-t|--tags} <taglist>]
$0 [{-b|--bitrate} <bitrate> | {-v|--quality} <quality> | {-a|--advanced} \"<options>\" {-e|--extension} <extension>] [{-f|--file} <audio_file>] [{-k|--keep-file}] [{-o|--output} <directory>] [{-r|--regex} '<regex>'] [{-t|--tags} <taglist>] [{-l|--log} <log_file>] [{-d|--debug} [<level>]]
Options:
-d, --debug [<level>] Enable debug logging
level is optional, between 1-3
1 is lowest, 3 is highest
[default: 1]
-b, --bitrate <bitrate> Set output quality in constant bits per second
[default: 320k]
Ex: 160k, 240k, 300000
@@ -102,6 +101,12 @@ Options:
-t, --tags <taglist> Comma separated list of metadata tags to apply
automated corrections to.
Supports: disc, genre
-l, --log <log_file> log filename
[default: /config/log/flac2mp3.txt]
-d, --debug [<level>] Enable debug logging
level is optional, between 1-3
1 is lowest, 3 is highest
[default: 1]
--help Display this help and exit
--version Display script version and exit
@@ -163,6 +168,16 @@ while (( "$#" )); do
echo "$flac2mp3_script $flac2mp3_ver"
exit 0
;;
-l|--log ) # Log file
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
export flac2mp3_log="$2"
shift 2
else
echo "Error|Invalid option: $1 requires an argument." >&2
usage
exit 1
fi
;;
-f|--file ) # Batch Mode
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
# Overrides detected *_eventtype
@@ -277,7 +292,7 @@ while (( "$#" )); do
exit 3
fi
;;
-*|--*=) # Unknown option
-*) # Unknown option
echo "Error|Unknown option: $1" >&2
usage
exit 20
@@ -508,9 +523,9 @@ function import_tracks {
}
# Get track media info from ffprobe
function ffprobe {
[ $flac2mp3_debug -ge 2 ] && echo "Debug|Executing: /usr/bin/ffprobe -hide_banner -loglevel $flac2mp3_ffmpeg_log -print_format json=compact=1 -show_format -show_entries \"format=tags : format_tags=disc,genre\" -i \"$1\"" | log
[ $flac2mp3_debug -ge 2 ] && echo "Debug|Executing: /usr/bin/ffprobe -hide_banner -loglevel $flac2mp3_ffmpeg_log -print_format json=compact=1 -show_format -show_entries \"format=tags : format_tags=title,disc,genre\" -i \"$1\"" | log
unset flac2mp3_ffprobe_json
flac2mp3_ffprobe_json=$(/usr/bin/ffprobe -hide_banner -loglevel $flac2mp3_ffmpeg_log -print_format json=compact=1 -show_format -show_entries "format=tags : format_tags=disc,genre" -i "$1")
flac2mp3_ffprobe_json=$(/usr/bin/ffprobe -hide_banner -loglevel $flac2mp3_ffmpeg_log -print_format json=compact=1 -show_format -show_entries "format=tags : format_tags=title,disc,genre" -i "$1")
flac2mp3_return=$?; [ $flac2mp3_return -ne 0 ] && {
flac2mp3_message="Error|[$flac2mp3_return] ffprobe error when inspecting track: \"$1\""
echo "$flac2mp3_message" | log
@@ -524,20 +539,48 @@ function ffprobe {
fi
return $flac2mp3_return
}
# Exit program
function end_script {
# Cool bash feature
flac2mp3_message="Info|Completed in $((SECONDS/60))m $((SECONDS%60))s"
echo "$flac2mp3_message" | log
[ "$1" != "" ] && flac2mp3_exitstatus=$1
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Exit code ${flac2mp3_exitstatus:-0}" | log
exit ${flac2mp3_exitstatus:-0}
}
### End Functions
# Check that log path exists
if [ ! -d "$(dirname $flac2mp3_log)" ]; then
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Log file path does not exist: '$(dirname $flac2mp3_log)'. Using log file in current directory."
flac2mp3_log=./flac2mp3.txt
fi
# Check that the log file exists
if [ ! -f "$flac2mp3_log" ]; then
echo "Info|Creating a new log file: $flac2mp3_log"
touch "$flac2mp3_log" 2>&1
fi
# Check that the log file is writable
if [ ! -w "$flac2mp3_log" ]; then
echo "Error|Log file '$flac2mp3_log' is not writable or does not exist." >&2
flac2mp3_log=/dev/null
flac2mp3_exitstatus=4
fi
# Check for required binaries
if [ ! -f "/usr/bin/ffmpeg" ]; then
flac2mp3_message="Error|/usr/bin/ffmpeg is required by this script"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
exit 2
end_script 2
fi
if [ ! -f "/usr/bin/ffprobe" ]; then
flac2mp3_message="Error|/usr/bin/ffprobe is required by this script"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
exit 2
end_script 2
fi
# Log Debug state
@@ -563,7 +606,7 @@ if [[ "$lidarr_eventtype" = "Test" ]]; then
flac2mp3_message="Info|Script was test executed successfully."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message"
exit 0
end_script
fi
# Log Batch mode
@@ -588,7 +631,7 @@ elif [ -f "$flac2mp3_config" ]; then
[[ $flac2mp3_bindaddress = "*" ]] && flac2mp3_bindaddress=localhost
# Build URL to Lidarr API
flac2mp3_api_url="http://$flac2mp3_bindaddress:$flac2mp3_port$flac2mp3_urlbase/api/v1"
flac2mp3_api_url="http://$flac2mp3_bindaddress:$flac2mp3_port${flac2mp3_urlbase:+/$flac2mp3_urlbase}/api/v1"
# Check Lidarr version
if get_version; then
@@ -616,7 +659,7 @@ if [ "$flac2mp3_type" = "batch" -a ! -f "$flac2mp3_tracks" ]; then
flac2mp3_message="Error|Input file not found: \"$flac2mp3_tracks\""
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
exit 5
end_script 5
fi
# Check for empty tracks variable
@@ -624,7 +667,7 @@ if [ -z "$flac2mp3_tracks" ]; then
flac2mp3_message="Error|No audio tracks were detected or specified!"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
exit 1
end_script 1
fi
# If specified, check if destination folder exists and create if necessary
@@ -635,7 +678,7 @@ if [ "$flac2mp3_output" -a ! -d "$flac2mp3_output" ]; then
flac2mp3_message="Error|[$flac2mp3_return] mkdir returned an error. Unable to create output directory."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
exit 6
end_script 6
}
fi
@@ -724,15 +767,23 @@ for flac2mp3_track in $flac2mp3_tracks; do
if ffprobe "$flac2mp3_track"; then
for flac2mp3_tag in $(echo $flac2mp3_tags | tr ',' '|'); do
case "$flac2mp3_tag" in
title ) # Fix for parenthesis in titles for live and mix names
flac2mp3_tag_title=$(echo "$flac2mp3_ffprobe_json" | jq -crM '.format.tags | to_entries[] | select(.key | match("title"; "i")).value')
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Original metadata: title=$flac2mp3_tag_title" | log
flac2mp3_pattern='\([^)]+\)$' # Rough way to limit editing metadata for every track
if [[ "$flac2mp3_tag_title" =~ $flac2mp3_pattern ]]; then
flac2mp3_ffmpeg_metadata+="-metadata title=\"$(echo "$flac2mp3_tag_title" | sed -r 's/\((live|acoustic|demo|[^)]*((re)?mix(es)?|dub|version))\)$/[\1]/i')\" "
fi
;;
disc ) # Fix one disc by itself
flac2mp3_tag_disc=$(echo "$flac2mp3_ffprobe_json" | jq -crM '.format.tags.disc')
flac2mp3_tag_disc=$(echo "$flac2mp3_ffprobe_json" | jq -crM '.format.tags | to_entries[] | select(.key | match("disc"; "i")).value')
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Original metadata: disc=$flac2mp3_tag_disc" | log
if [ "$flac2mp3_tag_disc" == "1" ]; then
flac2mp3_ffmpeg_metadata+='-metadata disc="1/1" '
fi
;;
genre ) # Fix multiple genres
flac2mp3_tag_genre=$(echo "$flac2mp3_ffprobe_json" | jq -crM '.format.tags | to_entries[] | select(.key | match("genre";"i")).value')
flac2mp3_tag_genre=$(echo "$flac2mp3_ffprobe_json" | jq -crM '.format.tags | to_entries[] | select(.key | match("genre"; "i")).value')
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Original metadata: genre=$flac2mp3_tag_genre" | log
# Only trigger on multiple genres
if [[ $flac2mp3_tag_genre =~ \; ]]; then
@@ -821,9 +872,6 @@ for flac2mp3_track in $flac2mp3_tracks; do
flac2mp3_import_list+="${flac2mp3_newTrack}|"
done
IFS=$' \t\n'
# Remove trailing pipe
flac2mp3_import_list="${flac2mp3_import_list%|}"
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Track import list: \"$flac2mp3_import_list\"" | log
#### END MAIN
#### Call Lidarr API to update database
@@ -835,6 +883,9 @@ elif [ $flac2mp3_keep -eq 1 ]; then
elif [ -n "$flac2mp3_api_url" ]; then
# Check for artist ID
if [ -n "$lidarr_artist_id" ]; then
# Remove trailing pipe
flac2mp3_import_list="${flac2mp3_import_list%|}"
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Track import list: \"$flac2mp3_import_list\"" | log
# Scan for files to import into Lidarr
export flac2mp3_import_count=$(echo $flac2mp3_import_list | awk -F\| '{print NF}')
if [ $flac2mp3_import_count -ne 0 ]; then
@@ -906,8 +957,4 @@ else
flac2mp3_exitstatus=20
fi
# Cool bash feature
flac2mp3_message="Info|Completed in $(($SECONDS/60))m $(($SECONDS%60))s"
echo "$flac2mp3_message" | log
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Exit code ${flac2mp3_exitstatus:-0}" | log
exit ${flac2mp3_exitstatus:-0}
end_script