Merge pull request #276 from TheCaptain989/lidarr-flac2mp3

Lidarr: flac2mp3 release 1.3
This commit is contained in:
aptalca 2022-01-28 15:59:32 -05:00 committed by GitHub
commit e730be5f57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 247 additions and 122 deletions

View File

@ -1,5 +1,6 @@
# About
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 output quality is 320Kbps constant bit rate.
Advanced options act as a light wrapper to ffmpeg, allowing conversion to any supported audio format, including AAC, AC3, and Opus.
>**NOTE:** This mod supports Linux OSes only.
@ -15,6 +16,7 @@ Production Container info: ![Docker Image Size](https://img.shields.io/docker/im
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:
- Dev/test release: `-e DOCKER_MODS=thecaptain989/lidarr-flac2mp3:latest`
- Stable release: `-e DOCKER_MODS=linuxserver/mods:lidarr-flac2mp3`
*Example Docker CLI Configuration*
@ -58,22 +60,42 @@ If you've configured Lidarr's **Recycle Bin** path correctly, the original audio
>**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 three command line options:
The script accepts five command line options:
`[-d] [-b <bitrate> | -v <quality>]`
`[-d] [-b <bitrate> | -v <quality> | -a "<options>" -e <extension>]`
The `-b bitrate` option sets the output quality in constant bits per second (CBR).
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 `-a "options"` setting is used in conjunction with `-e` to set advanced ffmpeg options. The specified command line options replace all script defaults and are sent directly to ffmpeg. The `options` value must be enclosed in quotes.
![danger] **WARNING:** When using `-a`, you must specify an audio codec (via `-c:a`) or the resulting file will contain no audio.
![danger] **WARNING:** Invalid `options` could result in script failure!
See [FFmpeg Options](https://ffmpeg.org/ffmpeg.html#Options) for details on valid options.
See [Guidelines for high quality audio encoding](https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio) for more information.
The `-e extension` option sets the output file extension, and must be used in conjunction with `-a`. The `extension` may be prefixed by a dot (".") or not.
If neither `-b`, `-v`, `-a`, or `-e` options are specified, the script will default to a constant 320Kbps MP3.
The `-d` option enables debug logging.
#### Technical notes on `-a` advanced options
The `-a` option effectively makes the script a somewhat generic wrapper for ffmpeg. FFmpeg is executed once per track with only the loglevel, input filename, and output filename being set. All other options are passed unparsed to the command line.
The exact format of the executed ffmpeg command is:
```
ffmpeg -loglevel error -i "Original.flac" ${Options} "NewTrack${Extension}"
```
### Examples
```
-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
-v 0 # Output variable bitrate MP3, VBR 220-260 kbit/s
-d -b 160k # Enable debugging, and output a 160 kbit/s MP3
-a "-c:v libtheora -map 0 -q:v 10 -c:a libopus -b:a 192k" -e .opus # Convert to Opus format, VBR 192 kbit/s, cover art
-a "-y -map 0 -c:a aac -b:a 240k -c:v copy" -e mp4 # Convert to MP4 format, using AAC 240 kbit/s audio, cover art, overwrite file
```
### Included Wrapper Scripts
@ -82,11 +104,12 @@ You may use any of these scripts in place of the `flac2mp3.sh` mentioned in the
```
flac2mp3-debug.sh # Enable debugging
flac2mp3-vbr.sh # Use variable bit rate, quality 0
flac2mp3-vbr.sh # Use variable bit rate MP3, quality 0
flac2opus.sh # Convert to Opus format using .opus extension, 192 kbit/s, no covert art
```
### Example Wrapper Script
To configure the last entry from the [Examples](./README.md#examples) section above, create and save a file called `flac2mp3-custom.sh` to `/config` containing the following text:
To configure the middle entry from the [Examples](./README.md#examples) section above, create and save a file called `flac2mp3-custom.sh` to `/config` containing the following text:
```shell
#!/bin/bash
@ -120,8 +143,8 @@ 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
[LinuxServer.io Docker Mods](https://hub.docker.com/r/linuxserver/mods "Docker Mods containers") project
[ffmpeg](https://ffmpeg.org/ "FFMpeg homepage")
[ffmpeg](https://ffmpeg.org/ "FFmpeg homepage")
Icons made by [Freepik](https://www.freepik.com) from [Flaticon](https://www.flaticon.com/)
[warning]: .assets/warning.png "Warning"
[danger]: .assets/danger.png "Danger"
[danger]: .assets/danger.png "Danger"

View File

@ -6,8 +6,8 @@ Only the latest major and minor version are supported.
| Version | Supported |
| ------- | ------------------ |
| 1.2.x | :heavy_check_mark: |
| < 1.2 | :x: |
| 1.3.x | :heavy_check_mark: |
| < 1.3 | :x: |
## Reporting a Vulnerability

View File

@ -36,11 +36,12 @@ fi
# Change ownership
if [ $(stat -c '%G' /usr/local/bin/flac2mp3.sh) != "abc" ]; then
echo "Changing ownership on scripts."
chown abc:abc /usr/local/bin/flac2mp3*.sh
chown abc:abc /usr/local/bin/flac2*.sh
fi
# Make executable
if [ ! -x /usr/local/bin/flac2mp3.sh ]; then
echo "Making scripts executable."
chmod +x /usr/local/bin/flac2mp3*.sh
chmod +x /usr/local/bin/flac2*.sh
fi

View File

@ -1,6 +1,6 @@
#!/bin/bash
# Script to convert FLAC files to MP3 using FFMpeg
# Script to convert FLAC files to MP3 using FFmpeg
# Dev/test: https://github.com/TheCaptain989/lidarr-flac2mp3
# Prod: https://github.com/linuxserver/docker-mods/tree/lidarr-flac2mp3
# Resultant MP3s are fully tagged and retain same permissions as original file
@ -29,8 +29,6 @@ export flac2mp3_maxlog=4
export flac2mp3_debug=0
export flac2mp3_tracks="$lidarr_addedtrackpaths"
[ -z "$flac2mp3_tracks" ] && flac2mp3_tracks="$lidarr_trackfile_path" # For other event type
export flac2mp3_recyclebin=$(sqlite3 /config/lidarr.db 'SELECT Value FROM Config WHERE Key="recyclebin"')
RET=$?; [ "$RET" != 0 ] && >&2 echo "WARNING[$RET]: Unable to read recyclebin information from database \"/config/lidarr.db\""
### Functions
function usage {
@ -41,22 +39,34 @@ Audio conversion script designed for use with Lidarr
Source: https://github.com/TheCaptain989/lidarr-flac2mp3
Usage:
$0 [-d] [-b <bitrate> | -v <quality>]
$0 [-d] [-b <bitrate> | -v <quality> | -a \"<options>\" -e <extension>]
Options:
-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
-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
-a \"<options>\" advanced ffmpeg options enclosed in quotes
Specified options replace all script defaults and are sent as
entered to ffmpeg for processing.
See https://ffmpeg.org/ffmpeg.html#Options for details on valid options.
WARNING: You must specify an audio codec!
WARNING: Invalid options could result in script failure!
Requires -e option to also be specified
See https://github.com/TheCaptain989/lidarr-flac2mp3 for more details
-e <extension> file extension for output file, with or without dot
Required when -a is specified!
Examples:
$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
$flac2mp3_script -b 320k # Output 320 kbit/s MP3 (non VBR; same as default behavior)
$flac2mp3_script -v 0 # Output variable bitrate MP3, VBR 220-260 kbit/s
$flac2mp3_script -d -b 160k # Enable debugging and set output a 160 kbit/s MP3
$flac2mp3_script -a \"-vn -c:a libopus -b:a 192K\" -e .opus # Convert to Opus format, VBR 192 kbit/s, no cover art
$flac2mp3_script -a \"-y -map 0 -c:a aac -b:a 240K -c:v copy\" -e mp4 # Convert to MP4 format, using AAC 240 kbit/s audio, cover art, overwrite file
"
>&2 echo "$usage"
echo "$usage" >&2
}
# Can still go over flac2mp3_maxlog if read line is too long
# Must include whole function in subshell for read to work!
@ -64,14 +74,13 @@ function log {(
while read
do
echo $(date +"%y-%-m-%-d %H:%M:%S.%1N")\|"[$flac2mp3_pid]$REPLY" >>"$flac2mp3_log"
local FILESIZE=$(stat -c %s "$flac2mp3_log")
if [ $FILESIZE -gt $flac2mp3_maxlogsize ]
local flac2mp3_filesize=$(stat -c %s "$flac2mp3_log")
if [ $flac2mp3_filesize -gt $flac2mp3_maxlogsize ]
then
for i in `seq $((flac2mp3_maxlog-1)) -1 0`
do
for i in $(seq $((flac2mp3_maxlog-1)) -1 0); do
[ -f "${flac2mp3_log::-4}.$i.txt" ] && mv "${flac2mp3_log::-4}."{$i,$((i+1))}".txt"
done
[ -f "${flac2mp3_log::-4}.txt" ] && mv "${flac2mp3_log::-4}.txt" "${flac2mp3_log::-4}.0.txt"
[ -f "${flac2mp3_log::-4}.txt" ] && mv "${flac2mp3_log::-4}.txt" "${flac2mp3_log::-4}.0.txt"
touch "$flac2mp3_log"
fi
done
@ -79,62 +88,72 @@ function log {(
# Inspired by https://stackoverflow.com/questions/893585/how-to-parse-xml-in-bash
function read_xml {
local IFS=\>
read -d \< ENTITY CONTENT
read -d \< flac2mp3_xml_entity flac2mp3_xml_content
}
# Initiate API Rescan request
function rescan {
MSG="Info|Calling Lidarr API to rescan artist"
echo "$MSG" | log
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Forcing rescan of artist '$lidarr_artist_id'. Calling Lidarr API 'RefreshArtist' using POST and URL 'http://$flac2mp3_bindaddress:$flac2mp3_port$flac2mp3_urlbase/api/v1/command?apikey=(removed)'" | log
RESULT=$(curl -s -d "{name: 'RefreshArtist', artistId: $lidarr_artist_id}" -H "Content-Type: application/json" \
-X POST http://$flac2mp3_bindaddress:$flac2mp3_port$flac2mp3_urlbase/api/v1/command?apikey=$flac2mp3_apikey)
[ $flac2mp3_debug -eq 1 ] && echo "API returned: $RESULT" | awk '{print "Debug|"$0}' | log
JOBID="$(echo $RESULT | jq -crM .id)"
if [ "$JOBID" != "null" ]; then
local RET=0
flac2mp3_message="Info|Calling Lidarr API to rescan artist"
echo "$flac2mp3_message" | log
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Forcing rescan of artist '$lidarr_artist_id'. Calling Lidarr API 'RefreshArtist' using POST and URL '$flac2mp3_api_url/command'" | log
flac2mp3_result=$(curl -s -H "X-Api-Key: $flac2mp3_apikey" \
-d "{\"name\": 'RefreshArtist', \"artistId\": $lidarr_artist_id}" \
-X POST "$flac2mp3_api_url/command")
[ $flac2mp3_debug -eq 1 ] && echo "API returned: $flac2mp3_result" | awk '{print "Debug|"$0}' | log
flac2mp3_jobid="$(echo $flac2mp3_result | jq -crM .id)"
if [ "$flac2mp3_jobid" != "null" ]; then
local flac2mp3_return=0
else
local RET=1
local flac2mp3_return=1
fi
return $RET
return $flac2mp3_return
}
# Check result of rescan job
function check_rescan {
local i=0
for ((i=1; i <= 15; i++)); do
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Checking job $JOBID completion, try #$i. Calling Lidarr API using GET and URL 'http://$flac2mp3_bindaddress:$flac2mp3_port$flac2mp3_urlbase/api/command/$JOBID?apikey=(removed)'" | log
RESULT=$(curl -s -H "Content-Type: application/json" \
-X GET http://$flac2mp3_bindaddress:$flac2mp3_port$flac2mp3_urlbase/api/v1/command/$JOBID?apikey=$flac2mp3_apikey)
[ $flac2mp3_debug -eq 1 ] && echo "API returned: $RESULT" | awk '{print "Debug|"$0}' | log
if [ "$(echo $RESULT | jq -crM .status)" = "completed" ]; then
local RET=0
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Checking job $flac2mp3_jobid completion, try #$i. Calling Lidarr API using GET and URL '$flac2mp3_api_url/command/$flac2mp3_jobid'" | log
flac2mp3_result=$(curl -s -H "X-Api-Key: $flac2mp3_apikey" \
-X GET "$flac2mp3_api_url/command/$flac2mp3_jobid")
[ $flac2mp3_debug -eq 1 ] && echo "API returned: $flac2mp3_result" | awk '{print "Debug|"$0}' | log
if [ "$(echo $flac2mp3_result | jq -crM .status)" = "completed" ]; then
local flac2mp3_return=0
break
else
if [ "$(echo $RESULT | jq -crM .status)" = "failed" ]; then
local RET=2
if [ "$(echo $flac2mp3_result | jq -crM .status)" = "failed" ]; then
local flac2mp3_return=2
break
else
local RET=1
# It may have timed out, so let's wait a second
local flac2mp3_return=1
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Job not done. Waiting 1 second." | log
sleep 1
fi
fi
done
return $RET
return $flac2mp3_return
}
# Process options
while getopts ":db:v:" opt; do
while getopts ":db:v:a:e:" opt; do
case ${opt} in
d ) # For debug purposes only
MSG="Debug|Enabling debug logging."
echo "$MSG" | log
>&2 echo "$MSG"
flac2mp3_message="Debug|Enabling debug logging."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
flac2mp3_debug=1
printenv | sort | sed 's/^/Debug|/' | log
;;
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"
flac2mp3_message="Error|Both -b and -v options cannot be set at the same time."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
elif [ -n "$flac2mp3_ffmpegadv" -o -n "$flac2mp3_extension" ]; then
flac2mp3_message="Error|The -a and -e options cannot be set at the same time as either -v or -b options."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
else
@ -143,35 +162,107 @@ while getopts ":db:v:" opt; do
;;
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"
flac2mp3_message="Error|Both -v and -b options cannot be set at the same time."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
elif [ -n "$flac2mp3_ffmpegadv" -o -n "$flac2mp3_extension" ]; then
flac2mp3_message="Error|The -a and -e options cannot be set at the same time as either -v or -b options."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
else
flac2mp3_vbrquality="$OPTARG"
fi
;;
a ) # Set advanced options
if [ -n "$flac2mp3_vbrquality" -o -n "$flac2mp3_bitrate" ]; then
flac2mp3_message="Error|The -a and -e options cannot be set at the same time as either -v or -b options."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
else
flac2mp3_ffmpegadv="$OPTARG"
fi
;;
e ) # Set file extension
if [ -n "$flac2mp3_vbrquality" -o -n "$flac2mp3_bitrate" ]; then
flac2mp3_message="Error|The -a and -e options cannot be set at the same time as either -v or -b options."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
else
flac2mp3_extension="$OPTARG"
fi
# Test for dot
[ "${flac2mp3_extension:0:1}" != "." ] && flac2mp3_extension=".${flac2mp3_extension}"
;;
: ) # No required argument specified
MSG="Error|Invalid option: -${OPTARG} requires an argument"
echo "$MSG" | log
>&2 echo "$MSG"
flac2mp3_message="Error|Invalid option: -${OPTARG} requires an argument"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
;;
* ) # Unknown option
MSG="Error|Unknown option: -${OPTARG}"
echo "$MSG" | log
>&2 echo "$MSG"
flac2mp3_message="Error|Unknown option: -${OPTARG}"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
;;
esac
done
# Test for either -a and -e, but not both: logical XOR = non-equality
if [ "${flac2mp3_ffmpegadv:+data}" != "${flac2mp3_extension:+data}" ]; then
flac2mp3_message="Error|The -a and -e options must be specified together."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
exit 3
fi
shift $((OPTIND -1))
# Set default bit rate
[ -z "$flac2mp3_vbrquality" ] && [ -z "$flac2mp3_bitrate" ] && flac2mp3_bitrate="320k"
[ -z "$flac2mp3_vbrquality" -a -z "$flac2mp3_bitrate" -a -z "$flac2mp3_ffmpegadv" -a -z "$flac2mp3_extension" ] && flac2mp3_bitrate="320k"
# Check for config file
if [ -f "$flac2mp3_config" ]; then
# Read Lidarr config.xml
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Reading from Lidarr config file '$flac2mp3_config'" | log
while read_xml; do
[[ $flac2mp3_xml_entity = "Port" ]] && flac2mp3_port=$flac2mp3_xml_content
[[ $flac2mp3_xml_entity = "UrlBase" ]] && flac2mp3_urlbase=$flac2mp3_xml_content
[[ $flac2mp3_xml_entity = "BindAddress" ]] && flac2mp3_bindaddress=$flac2mp3_xml_content
[[ $flac2mp3_xml_entity = "ApiKey" ]] && flac2mp3_apikey=$flac2mp3_xml_content
done < $flac2mp3_config
[[ $flac2mp3_bindaddress = "*" ]] && flac2mp3_bindaddress=localhost
# Build URL to Lidarr API
flac2mp3_api_url="http://$flac2mp3_bindaddress:$flac2mp3_port$flac2mp3_urlbase/api/v1"
# Check Lidarr version
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Getting Lidarr version. Calling Lidarr API using GET and URL '$flac2mp3_api_url/system/status'" | log
flac2mp3_version=$(curl -s -H "X-Api-Key: $flac2mp3_apikey" \
-X GET "$flac2mp3_api_url/system/status" | jq -crM .version)
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Detected Lidarr version $flac2mp3_version" | log
# Get RecycleBin
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Getting Lidarr RecycleBin. Calling Lidarr API using GET and URL '$flac2mp3_api_url/config/mediamanagement'" | log
flac2mp3_recyclebin=$(curl -s -H "X-Api-Key: $flac2mp3_apikey" \
-X GET "$flac2mp3_api_url/config/mediamanagement" | jq -crM .recycleBin)
[ $flac2mp3_debug -eq 1 ] && echo "Debug|Detected Lidarr RecycleBin '$flac2mp3_recyclebin'" | log
else
# No config file means we can't call the API. Best effort at this point.
flac2mp3_message="Warn|Unable to locate Lidarr config file: '$flac2mp3_config'"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
fi
# Handle Lidarr Test event
if [[ "$lidarr_eventtype" = "Test" ]]; then
@ -182,18 +273,18 @@ fi
# Check if called from within Lidarr
if [ -z "$flac2mp3_tracks" ]; then
MSG="Error|No track file(s) specified! Not called from Lidarr?"
echo "$MSG" | log
>&2 echo "$MSG"
flac2mp3_message="Error|No track file(s) specified! Not called from Lidarr?"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
usage
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"
flac2mp3_message="Error|/usr/bin/ffmpeg is required by this script"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
exit 2
fi
@ -201,37 +292,54 @@ fi
#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:-$flac2mp3_vbrquality}, Tracks: $flac2mp3_tracks" | log
flac2mp3_message="Info|Lidarr event: ${lidarr_eventtype}, Artist: ${lidarr_artist_name} (${lidarr_artist_id}), Album: ${lidarr_album_title} (${lidarr_album_id}), "
if [ -z "$flac2mp3_ffmpegadv" ]; then
flac2mp3_message+="Export bitrate: ${flac2mp3_bitrate:-$flac2mp3_vbrquality}"
else
flac2mp3_message+="Advanced options: '${flac2mp3_ffmpegadv}', File extension: ${flac2mp3_extension}"
fi
flac2mp3_message+=", Tracks: ${flac2mp3_tracks}"
echo "${flac2mp3_message}" | log
echo "$flac2mp3_tracks" | awk -v Debug=$flac2mp3_debug \
-v Recycle="$flac2mp3_recyclebin" \
-v Bitrate=$flac2mp3_bitrate \
-v VBR=$flac2mp3_vbrquality '
-v Bitrate="$flac2mp3_bitrate" \
-v VBR="$flac2mp3_vbrquality" \
-v FFmpegADV="$flac2mp3_ffmpegadv" \
-v EXT="$flac2mp3_extension" '
BEGIN {
FFMpeg="/usr/bin/ffmpeg"
FFmpeg="/usr/bin/ffmpeg"
FS="|"
RS="|"
IGNORECASE=1
if (EXT == "") EXT=".mp3"
if (Bitrate) {
if (Debug) print "Debug|Using constant bitrate of "Bitrate
BrCommand="-b:a "Bitrate
} else {
} else if (VBR) {
if (Debug) print "Debug|Using variable quality of "VBR
BrCommand="-q:a "VBR
} else if (FFmpegADV) {
if (Debug) print "Debug|Using advanced ffmpeg options: \""FFmpegADV"\""
if (Debug) print "Debug|Exporting with file extension "EXT
}
}
/\.flac/ {
# Get each FLAC file name and create a new MP3 name
# Get each FLAC file name and create a new MP3 (or other) name
Track=$1
sub(/\n/,"",Track)
NewTrack=substr(Track, 1, length(Track)-5)".mp3"
NewTrack=substr(Track, 1, length(Track)-5) EXT
print "Info|Writing: "NewTrack
# Check for advanced options
if (FFmpegADV) FFmpegOPTS=FFmpegADV
else FFmpegOPTS="-c:v copy -map 0 -y -acodec libmp3lame "BrCommand" -write_id3v1 1 -id3v2_version 3"
# 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 (Debug) print "Debug|Executing: nice "FFmpeg" -loglevel error -i \""Track"\" "FFmpegOPTS" \""NewTrack"\""
Result=system("nice "FFmpeg" -loglevel error -i \""Track"\" "FFmpegOPTS" \""NewTrack"\" 2>&1")
if (Result) {
print "Error|Exit code "Result" converting \""Track"\""
} else {
if (Recycle=="") {
if (Recycle == "") {
# 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"\""
@ -244,7 +352,7 @@ BEGIN {
RecPath=substr(Track,RSTART+RLENGTH)
sub(/[^\/]+$/,"",RecPath)
RecPath=Recycle RecPath
if (Debug) print "Debug|Moving: \""Track"\" to \""RecPath"\" and setting permissions on \""NewTrack"\""
if (Debug) print "Debug|Recycling: \""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)
@ -256,55 +364,45 @@ BEGIN {
#### END MAIN
# Check for awk script completion
RET="${PIPESTATUS[1]}" # captures awk exit status
if [ $RET != "0" ]; then
MSG="Error|Script exited abnormally. File permissions issue?"
echo "$MSG" | log
>&2 echo "$MSG"
flac2mp3_return="${PIPESTATUS[1]}" # captures awk exit status
if [ $flac2mp3_return != "0" ]; then
flac2mp3_message="Error|Script exited abnormally. File permissions issue?"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
exit 10
fi
# Call Lidarr API to RescanArtist
if [ ! -z "$lidarr_artist_id" ]; then
if [ -f "$flac2mp3_config" ]; then
# Read Lidarr config.xml
while read_xml; do
[[ $ENTITY = "Port" ]] && flac2mp3_port=$CONTENT
[[ $ENTITY = "UrlBase" ]] && flac2mp3_urlbase=$CONTENT
[[ $ENTITY = "BindAddress" ]] && flac2mp3_bindaddress=$CONTENT
[[ $ENTITY = "ApiKey" ]] && flac2mp3_apikey=$CONTENT
done < $flac2mp3_config
[[ $flac2mp3_bindaddress = "*" ]] && flac2mp3_bindaddress=localhost
if [ -n "$flac2mp3_api_url" ]; then
if [ "$lidarr_artist_id" ]; then
# Scan the disk for the new audio tracks
if rescan; then
# Check that the rescan completed
if ! check_rescan; then
# Timeout or failure
MSG="Warn|Lidarr job ID $JOBID timed out or failed."
echo "$MSG" | log
>&2 echo "$MSG"
flac2mp3_message="Warn|Lidarr job ID $flac2mp3_jobid timed out or failed."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
fi
else
# Error from API
MSG="Error|The 'RefreshArtist' API with artist $lidarr_artist_id failed."
echo "$MSG" | log
>&2 echo "$MSG"
flac2mp3_message="Error|The 'RefreshArtist' API with artist $lidarr_artist_id failed."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
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"
# No Artist ID means we can't call the API
flac2mp3_message="Warn|Missing environment variable lidarr_artist_id"
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
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"
# No URL means we can't call the API
flac2mp3_message="Warn|Unable to determine Lidarr API URL."
echo "$flac2mp3_message" | log
echo "$flac2mp3_message" >&2
fi
# Cool bash feature
MSG="Info|Completed in $(($SECONDS/60))m $(($SECONDS%60))s"
echo "$MSG" | log
flac2mp3_message="Info|Completed in $(($SECONDS/60))m $(($SECONDS%60))s"
echo "$flac2mp3_message" | log

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/flac2mp3.sh -a "-vn -c:a libopus -b:a 192k" -e .opus