Skip to content

Commit

Permalink
Resolves three issues
Browse files Browse the repository at this point in the history
Resolves issue #23, #24, and #25.
  • Loading branch information
TheCaptain989 committed Mar 6, 2021
1 parent e90d9ad commit 27bd7e5
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 52 deletions.
Binary file added .assets/danger.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .assets/warning.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 33 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
A [Docker Mod](https://github.com/linuxserver/docker-mods) for the LinuxServer.io Lidarr Docker container that adds a script to automatically convert downloaded FLAC files to MP3s using ffmpeg. Default quality is 320Kbps.
A [Docker Mod](https://github.com/linuxserver/docker-mods) for the LinuxServer.io Lidarr Docker container that uses ffmpeg and a script to automatically convert downloaded FLAC files to MP3s. Default quality is 320Kbps constant bit rate.

>**NOTE:** This mod support Linux OSes only.
>**NOTE:** This mod supports Linux OSes only.
Container info:
![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/thecaptain989/lidarr-flac2mp3)
![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/thecaptain989/lidarr-flac2mp3 "Image Size")
![Docker Pulls](https://img.shields.io/docker/pulls/thecaptain989/lidarr-flac2mp3 "Container Pulls")

# Installation
Expand All @@ -20,39 +20,50 @@ Container info:

2. Start the container.

3. After all of the above configuration is complete, to use ffmpeg, configure a custom script from the Settings->Connect screen and type the following in the **Path** field:
3. After the above configuration is complete, to use ffmpeg, configure a custom script from Lidarr's *Settings* > *Connect* screen and type the following in the **Path** field:
`/usr/local/bin/flac2mp3.sh`

*Example*
![lidarr-flac2mp3](.assets/lidarr-custom-script.png "Lidarr Custom Script dialog")

This will use the defaults to create a 320Kbps MP3 file.

*For any other setting, you **must** either user one of the [included wrapper scripts](./README.md#included-wrapper-scripts) or create a custom script with the command line options you desire. See the [Syntax](./README.md#syntax) section below.*

## Usage
New file(s) with an MP3 extension will be placed in the same directory as the original FLAC file(s). Existing MP3 files with the same track name will be overwritten.
New file(s) with an MP3 extension will be placed in the same directory as the original FLAC file(s) and have the same owner and permissions. Existing MP3 files with the same track name will be overwritten.

If you've configured the Lidarr Recycle Bin path correctly, the original video will be moved there.
![warning24] **NOTE:** If you have *not* configured the Recycle Bin, the original FLAC audio file(s) will be deleted and permanently lost.
If you've configured Lidarr's **Recycle Bin** path correctly, the original audio file will be moved there.
![danger] **NOTE:** If you have *not* configured the Recycle Bin, the original FLAC audio file(s) will be deleted and permanently lost.

### Syntax
>**Note:** The **Arguments** field for Custom Scripts was removed in Lidarr release [v0.7.0.1347](https://github.com/lidarr/Lidarr/commit/b9d240924f8965ebb2c5e307e36b810ae076101e "Lidarr commit notes") due to security concerns.
To support options with this version and later, a wrapper script can be manually created that will call *flac2mp3.sh* with the required arguments.

The script accepts two options which may be placed in the **Arguments** field:
The script accepts three command line options:

`[-d] [-b <bitrate>]`
`[-d] [-b <bitrate> | -v <quality>]`

The `-b bitrate` option, if specified, sets the output quality in bits per second. If no `-b` option is specified, the script will default to 320Kbps.
The `-b bitrate` option sets the output quality in constant bits per second (CBR).
The `-v quality` option sets the output quality using a variable bit rate (VBR) where `quality` is a value between 0 and 9, with 0 being the highest quality. See the [FFmpeg MP3 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/MP3) for more details.
If neither `-b` nor `-v` options are specified, the script will default to constant 320Kbps.

The `-d` option enables debug logging.

### Examples
```
-b 320k # Output 320 kilobits per second MP3 (same as default behavior)
-d -b 160k # Enable debugging, and output 160 kilobits per second MP3
-b 320k # Output 320 kbit/s MP3 (non VBR; same as default behavior)
-v 0 # Output variable bitrate, VBR 220-260 kbit/s
-d -b 160k # Enable debugging, and output 160 kbit/s MP3
```

### Included Wrapper Script
For your convenience, a wrapper script to enable debugging is included in the `/usr/local/bin/` directory.
Use this script in place of the `flac2mp3.sh` mentioned in the [Installation](./README.md#installation) section above.
### Included Wrapper Scripts
For your convenience, several wrapper scripts are included in the `/usr/local/bin/` directory.
You may use any of these scripts in place of the `flac2mp3.sh` mentioned in the [Installation](./README.md#installation) section above.

```
flac2mp3-debug.sh # Enable debugging
flac2mp3-vbr.sh # Use variable bit rate, quality 0
```

### Example Wrapper Script
Expand All @@ -67,24 +78,24 @@ Then put `/usr/local/bin/wrapper.sh` in the **Path** field in place of `/usr/loc
### Triggers
The only events/notification triggers that have been tested are **On Release Import** and **On Upgrade**

![lidarr-flac2mp3](.assets/lidarr-custom-script.png "Lidarr Custom Script dialog")

### Logs
A log file is created for the script activity called:

`/config/logs/flac2mp3.txt`

This log can be downloaded from the Lidarr GUI under System->Log Files
This log can be downloaded from Lidarr under *System* > *Log Files*

Log rotation is performed, with 5 log files of 1MB each kept, matching Lidarr's log retention.
>![warning24] **NOTE:** If debug logging is enabled, the log file can grow very large very quickly. *Do not leave debug logging enabled permanently.*
>![danger] **NOTE:** If debug logging is enabled, the log file can grow very large very quickly. *Do not leave debug logging enabled permanently.*
## Credits
This would not be possible without the following:

[Lidarr](https://lidarr.audio/ "Lidarr homepage")
[LinuxServer.io Lidarr](https://hub.docker.com/r/linuxserver/lidarr "Lidarr Docker container") container
[ffmpeg](https://ffmpeg.org/ "FFMpeg homepage")
[LinuxServer.io Docker Mods](https://hub.docker.com/r/linuxserver/mods "Docker Mods containers") project
[ffmpeg](https://ffmpeg.org/ "FFMpeg homepage")
Icons made by [Freepik](https://www.freepik.com) from [Flaticon](https://www.flaticon.com/)

[warning]: http://files.softicons.com/download/application-icons/32x32-free-design-icons-by-aha-soft/png/32/Warning.png "Warning"
[warning24]: http://files.softicons.com/download/toolbar-icons/24x24-free-pixel-icons-by-aha-soft/png/24x24/Warning.png "Warning"
[warning]: .assets/warning.png "Warning"
[danger]: .assets/danger.png "Danger"
3 changes: 3 additions & 0 deletions root/usr/local/bin/flac2mp3-vbr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

. /usr/local/bin/flac2mp3.sh -v 0
114 changes: 84 additions & 30 deletions root/usr/local/bin/flac2mp3.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
# Script to convert FLAC files to MP3 using FFMpeg
# https://github.com/TheCaptain989/lidarr-flac2mp3
# Can also process MP3s and tag them appropriately
# Resultant MP3s are fully tagged
# Resultant MP3s are fully tagged and retain same permissions as original file

# Dependencies:
# ffmpeg
# awk
# stat
# chmod

# Exit codes:
# 0 - success; or test
# 1 - no tracks files specified on command line
# 1 - no tracks files found in environment
# 2 - mkvmerge not found
# 3 - invalid command line arguments
# 10 - awk script generated an error

### Variables
Expand All @@ -33,25 +35,25 @@ RET=$?; [ "$RET" != 0 ] && >&2 echo "WARNING[$RET]: Unable to read recyclebin in
function usage {
usage="
$flac2mp3_script
Audio conversion script designed for use with Bazarr
Audio conversion script designed for use with Lidarr
Source: https://github.com/TheCaptain989/lidarr-flac2mp3
Usage:
$0 [-d] [-b <bitrate>]
Arguments:
bitrate # output quality in bits per second (SI units)
$0 [-d] [-b <bitrate> | -v <quality>]
Options:
-d # enable debug logging
-b # set bitrate; default 320K
-d enable debug logging
-b <bitrate> set output quality in constant bits per second [default: 320k]
Ex: 160k, 240k, 300000
-v <quality> set variable bitrate; quality between 0-9
0 is highest quality, 9 is lowest
See https://trac.ffmpeg.org/wiki/Encode/MP3 for more details
Examples:
$flac2mp3_script -b 320k # Output 320 kilobits per second MP3
(same as default behavior)
$flac2mp3_script -d -b 160k # Enable debugging, and output quality
160 kilobits per second
$flac2mp3_script -b 320k # Output 320 kbit/s MP3 (non VBR; same as default behavior)
$flac2mp3_script -v 0 # Output variable bitrate, VBR 220-260 kbit/s
$flac2mp3_script -d -b 160k # Enable debugging and set output to 160 kbit/s
"
>&2 echo "$usage"
}
Expand Down Expand Up @@ -118,7 +120,7 @@ function check_rescan {
return $RET
}
# Process options
while getopts ":db:" opt; do
while getopts ":db:v:" opt; do
case ${opt} in
d ) # For debug purposes only
MSG="Debug|Enabling debug logging."
Expand All @@ -127,27 +129,57 @@ while getopts ":db:" opt; do
flac2mp3_debug=1
printenv | sort | sed 's/^/Debug|/' | log
;;
b ) # Set bitrate
flac2mp3_bitrate="$OPTARG"
b ) # Set constant bit rate
if [ -n "$flac2mp3_vbrquality" ]; then
MSG="Error|Both -b and -v options cannot be set at the same time."
echo "$MSG" | log
>&2 echo "$MSG"
usage
exit 3
else
flac2mp3_bitrate="$OPTARG"
fi
;;
v ) # Set variable quality
if [ -n "$flac2mp3_bitrate" ]; then
MSG="Error|Both -v and -b options cannot be set at the same time."
echo "$MSG" | log
>&2 echo "$MSG"
usage
exit 3
else
flac2mp3_vbrquality="$OPTARG"
fi
;;
: ) # No required argument specified
MSG="Error|Invalid option: -${OPTARG} requires an argument"
echo "$MSG" | log
>&2 echo "$MSG"
usage
exit 3
;;
: )
MSG="Error|Invalid option: -$OPTARG requires an argument"
* ) # Unknown option
MSG="Error|Unknown option: -${OPTARG}"
echo "$MSG" | log
>&2 echo "$MSG"
usage
exit 3
;;
esac
done
shift $((OPTIND -1))

# Set default bitrate
[ -z "$flac2mp3_bitrate" ] && flac2mp3_bitrate="320k"
# Set default bit rate
[ -z "$flac2mp3_vbrquality" ] && [ -z "$flac2mp3_bitrate" ] && flac2mp3_bitrate="320k"

# Handle Lidarr Test event
if [[ "$lidarr_eventtype" = "Test" ]]; then
echo "Info|Lidarr event: $lidarr_eventtype" | log
echo "Info|Script was test executed successfully." | log
exit 0
fi

# Chick if called from within Lidarr
if [ -z "$flac2mp3_tracks" ]; then
MSG="Error|No track file(s) specified! Not called from Lidarr?"
echo "$MSG" | log
Expand All @@ -156,55 +188,75 @@ if [ -z "$flac2mp3_tracks" ]; then
exit 1
fi

# Check for required binaries
if [ ! -f "/usr/bin/ffmpeg" ]; then
MSG="Error|/usr/bin/ffmpeg is required by this script"
echo "$MSG" | log
>&2 echo "$MSG"
exit 2
fi

# Legacy one-liner script
# Legacy one-liner script for posterity
#find "$lidarr_artist_path" -name "*.flac" -exec bash -c 'ffmpeg -loglevel warning -i "{}" -y -acodec libmp3lame -b:a 320k "${0/.flac}.mp3" && rm "{}"' {} \;

#### MAIN
echo "Info|Lidarr event: $lidarr_eventtype, Artist: $lidarr_artist_name ($lidarr_artist_id), Album: $lidarr_album_title ($lidarr_album_id), Export bitrate: $flac2mp3_bitrate, Tracks: $flac2mp3_tracks" | log
echo "$flac2mp3_tracks" | awk -v Debug=$flac2mp3_debug \
-v Recycle="$flac2mp3_recyclebin" \
-v Bitrate=$flac2mp3_bitrate '
-v Bitrate=$flac2mp3_bitrate \
-v VBR=$flac2mp3_vbrquality '
BEGIN {
FFMpeg="/usr/bin/ffmpeg"
FS="|"
RS="|"
IGNORECASE=1
if (Bitrate) {
if (Debug) print "Debug|Using constant bitrate of "Bitrate
BrCommand="-b:a "Bitrate
} else {
if (Debug) print "Debug|Using variable quality of "VBR
BrCommand="-q:a "VBR
}
}
/\.flac/ {
# Get each FLAC file name and create a new MP3 name
Track=$1
sub(/\n/,"",Track)
NewTrack=substr(Track, 1, length(Track)-5)".mp3"
print "Info|Writing: "NewTrack
if (Debug) print "Debug|Executing: nice "FFMpeg" -loglevel error -i \""Track"\" "CoverCmds1"-map 0 -y -acodec libmp3lame -b:a "Bitrate" -write_id3v1 1 -id3v2_version 3 "CoverCmds2"\""NewTrack"\""
Result=system("nice "FFMpeg" -loglevel error -i \""Track"\" "CoverCmds1"-map 0 -y -acodec libmp3lame -b:a "Bitrate" -write_id3v1 1 -id3v2_version 3 "CoverCmds2"\""NewTrack"\" 2>&1")
# Convert the track
if (Debug) print "Debug|Executing: nice "FFMpeg" -loglevel error -i \""Track"\" -c:v copy -map 0 -y -acodec libmp3lame "BrCommand" -write_id3v1 1 -id3v2_version 3 \""NewTrack"\""
Result=system("nice "FFMpeg" -loglevel error -i \""Track"\" -c:v copy -map 0 -y -acodec libmp3lame "BrCommand" -write_id3v1 1 -id3v2_version 3 \""NewTrack"\" 2>&1")
if (Result) {
print "Error|"Result" converting \""Track"\""
print "Error|Exit code "Result" converting \""Track"\""
} else {
if (Recycle=="") {
if (Debug) print "Debug|Deleting: \""Track"\""
system("[ -s \""NewTrack"\" ] && [ -f \""Track"\" ] && rm \""Track"\"")
# No Recycle Bin, so check for non-zero size new file and delete the old one
if (Debug) print "Debug|Deleting: \""Track"\" and setting permissions on \""NewTrack"\""
#Command="[ -s \""NewTrack"\" ] && [ -f \""Track"\" ] && chown --reference=\""Track"\" \""NewTrack"\" && chmod --reference=\""Track"\" \""NewTrack"\" && rm \""Track"\""
Command="if [ -s \""NewTrack"\" ]; then if [ -f \""Track"\" ]; then chown --reference=\""Track"\" \""NewTrack"\"; chmod --reference=\""Track"\" \""NewTrack"\"; rm \""Track"\"; fi; fi"
if (Debug) print "Debug|Executing: "Command
system(Command)
} else {
# Recycle Bin is configured, so check if it exists, append a relative path to it from the track, check for non-zero size new file, and move the old one to the Recycle Bin
match(Track,/^\/?[^\/]+\//)
RecPath=substr(Track,RSTART+RLENGTH)
sub(/[^\/]+$/,"",RecPath)
RecPath=Recycle RecPath
if (Debug) print "Debug|Moving: \""Track"\" to \""RecPath"\""
system("[ ! -e \""RecPath"\" ] && mkdir -p \""RecPath"\"; [ -s \""NewTrack"\" ] && [ -f \""Track"\" ] && mv -t \""RecPath"\" \""Track"\"")
if (Debug) print "Debug|Moving: \""Track"\" to \""RecPath"\" and setting permissions on \""NewTrack"\""
Command="if [ ! -e \""RecPath"\" ]; then mkdir -p \""RecPath"\"; fi; if [ -s \""NewTrack"\" ]; then if [ -f \""Track"\" ]; then chown --reference=\""Track"\" \""NewTrack"\"; chmod --reference=\""Track"\" \""NewTrack"\"; mv -t \""RecPath"\" \""Track"\"; fi; fi"
if (Debug) print "Debug|Executing: "Command
system(Command)
}
}
}
' | log

#### END MAIN

# Check for awk script completion
RET="${PIPESTATUS[1]}" # captures awk exit status
if [ $RET != "0" ]; then
# Check for script completion and non-empty file
MSG="Error|Script exited abnormally. File permissions issue?"
echo "$MSG" | log
>&2 echo "$MSG"
Expand Down Expand Up @@ -240,11 +292,13 @@ if [ ! -z "$lidarr_artist_id" ]; then
>&2 echo "$MSG"
fi
else
# No config file means we can't call the API
MSG="Warn|Unable to locate Lidarr config file: '$flac2mp3_config'"
echo "$MSG" | log
>&2 echo "$MSG"
fi
else
# No Artist ID means we can't call the API
MSG="Warn|Missing environment variable lidarr_artist_id"
echo "$MSG" | log
>&2 echo "$MSG"
Expand Down

0 comments on commit 27bd7e5

Please sign in to comment.