mirror of
https://github.com/TrezOne/docker-mods-uptime-kuma-timeout-fix.git
synced 2026-07-19 09:53:02 -04:00
Merge pull request #528 from TheCaptain989/lidarr-flac2mp3
Lidarr: flac2mp3 Release 2.2
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
@@ -1,5 +1,5 @@
|
|||||||
# About
|
# 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.
|
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 (or other format) 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, Opus, and many others.
|
Advanced options act as a light wrapper to ffmpeg, allowing conversion to any supported audio format, including AAC, AC3, Opus, and many others.
|
||||||
A [Batch Mode](./README.md#batch-mode) is also supported that allows usage outside of Lidarr.
|
A [Batch Mode](./README.md#batch-mode) is also supported that allows usage outside of Lidarr.
|
||||||
|
|
||||||
@@ -49,25 +49,24 @@ Production Container info:  or create a custom script with the command line options you desire. See the [Syntax](./README.md#syntax) section below.*
|
*For any other setting, you **must** use one of the supported methods to pass arguments to the script. See the [Syntax](./README.md#syntax) section below.*
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
New file(s) with will be placed in the same directory as the original FLAC file(s) (unless redirected with the `--output` option below) and have the same owner and permissions. Existing files with the same track name will be overwritten.
|
New file(s) will be placed in the same directory as the original FLAC file(s) (unless redirected with the `--output` option below) and have the same owner and permissions. Existing files with the same track name will be overwritten.
|
||||||
|
|
||||||
By default, if you've configured Lidarr's **Recycle Bin** path correctly, the original audio file will be moved there.
|
By default, 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. This behavior may be modifed with the `--keep-file` option.
|
![danger] **NOTE:** If you have *not* configured the Recycle Bin, the original FLAC audio file(s) will be deleted and permanently lost. This behavior may be modified with the `--keep-file` option.
|
||||||
|
|
||||||
### Syntax
|
### 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.
|
>**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.
|
|
||||||
|
To supply arguments to the script, you **must** either use one of the **[included wrapper scripts](./README.md#included-wrapper-scripts)**, create a **[custom wrapper script](./README.md#example-wrapper-script)**, or set the `FLAC2MP3_ARGS` **[environment variable](./README.md#environment-variable)**.
|
||||||
|
|
||||||
#### Command Line Options and Arguments
|
#### Command Line Options and Arguments
|
||||||
The script may be called with optional command line arguments.
|
The script may be called with optional command line arguments.
|
||||||
|
|
||||||
The syntax for the command line is:
|
The syntax for the command line is:
|
||||||
`flac2mp3 [OPTIONS] [{-b|--bitrate} <bitrate> | {-v|--quality} <quality> | {-a|--advanced} "<options>" {-e|--extension} <extension>]`
|
`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>]`
|
||||||
OR
|
|
||||||
`flac2mp3 [OPTIONS] {-f|--file} <audio_file>`
|
|
||||||
|
|
||||||
Where:
|
Where:
|
||||||
|
|
||||||
@@ -76,11 +75,13 @@ Option|Argument|Description
|
|||||||
-d, --debug|\[\<level\>\]|Enables debug logging. Level is optional.<br/>Default of 1 (low).<br/>2 includes API and FFmpeg output.
|
-d, --debug|\[\<level\>\]|Enables debug logging. Level is optional.<br/>Default of 1 (low).<br/>2 includes API and FFmpeg 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`.
|
-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`.
|
-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/>![danger] **WARNING:** You must specify an audio codec (by including a `-c:a <codec>` ffmpeg option) or the resulting file will contain no audio!<br/>![danger] **WARNING:** Invalid `options` could result in script failure!
|
-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!
|
||||||
-e, --extension|\<extension\>|Sets the output file extension<br/>The extension may be prefixed by a dot (".") or not.<br/>**Note:** Requires the `-a` option to also be specified. May not be specified with `-v` or `-b`.
|
-e, --extension|\<extension\>|Sets the output file extension.<br/>The extension may be prefixed by a dot (".") or not.<br/>Example: .ogg<br/>**Note:** Requires the `-a` option to also be specified. May not be specified with `-v` or `-b`.
|
||||||
-f, --file|<audio_file>|If included, the script enters **[Batch Mode](./README.md#batch-mode)** and converts the specified audio file.<br/>![danger] **WARNING:** Do not use this argument when called from Lidarr!
|
-f, --file|<audio_file>|If included, the script enters **[Batch Mode](./README.md#batch-mode)** and converts the specified audio file.<br/>![warning] **WARNING:** Do not use this argument when called from Lidarr!
|
||||||
-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.
|
-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 triggering a Lidarr rescan after conversion.
|
-k, --keep-file| |Do not delete the source file or move it to the Lidarr Recycle bin.<br/>**Note:** This also disables triggering a Lidarr rescan 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$"`.
|
||||||
|
-t, --tags|\<taglist\>|Comma separated list of metadata tags to apply automated corrections to.<br/>See [Metadata Corrections](./README.md#metadata-corrections) section.
|
||||||
--help| |Display help and exit.
|
--help| |Display help and exit.
|
||||||
--version| |Display version and exit.
|
--version| |Display version and exit.
|
||||||
|
|
||||||
@@ -91,28 +92,42 @@ The `-a` option effectively makes the script a generic wrapper for ffmpeg. FFmp
|
|||||||
|
|
||||||
The exact format of the executed ffmpeg command is:
|
The exact format of the executed ffmpeg command is:
|
||||||
```
|
```
|
||||||
ffmpeg -loglevel error -i "input.flac" ${options} "output.${extension}"
|
ffmpeg -loglevel error -nostdin -i "input.flac" ${options} "output.${extension}"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Technical notes on regex
|
||||||
|
By default, the script only matches and interacts with FLAC files (specifically, files ending in ".flac"). The `-r` option allows the script to match on a user specified regular expression (i.e. "regex") pattern.
|
||||||
|
|
||||||
|
Files are passed to the script with the full Linux path intact. (Ex: `/path/to/audio/a-ha/Hunting High and Low/01 Take on Me.mp3`). Craft your regex with this in mind.
|
||||||
|
|
||||||
|
![warning] **NOTE:** Escaping special regex characters (like a dot `.`) requires a double backslash, _even when single quoted!_ This is because **awk** (the program that processes audio files in the script) in most cases [strips a single backslash](https://www.gnu.org/software/gawk/manual/html_node/Escape-Sequences.html "GNU awk reference") from strings. Double quoted or unquoted strings require _four_ backslashes to preserve a regex escape because the bash shell will process the escapes first.
|
||||||
|
|
||||||
|
For example, to convert all audio files to AAC audio files, use the following options:
|
||||||
|
```
|
||||||
|
-a "-y -map 0 -c:a aac -b:a 240k -c:v copy" -e m4a --regex '\\.[^.]*$'
|
||||||
|
```
|
||||||
|
|
||||||
|
Regular expression syntax is beyond the scope of this document. See this [tutorial](https://www.regular-expressions.info/tutorial.html "Regular Expressions Tutorial") for more information. Regex patterns may be tested [here](http://regexstorm.net/tester "regex tester").
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
```
|
```
|
||||||
-b 320k # Output 320 kbit/s MP3 (non-VBR; same as default behavior)
|
-b 320k # Output 320 kbit/s MP3 (non-VBR; same as default behavior)
|
||||||
-v 0 # Output variable bitrate MP3, VBR 220-260 kbit/s
|
-v 0 # Output variable bitrate MP3, VBR 220-260 kbit/s
|
||||||
-d -b 160k # Enable debugging level 1, and output a 160 kbit/s MP3
|
-d -b 160k # Enable debugging level 1, and output a 160 kbit/s MP3
|
||||||
|
-r '\\.[^.]*$' # Convert any file to MP3 (not just FLAC)
|
||||||
-a "-c:v libtheora -map 0 -q:v 10 -c:a libopus -b:a 192k" -e .opus
|
-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, no overwright
|
# Convert to Opus format, 192 kbit/s, cover art
|
||||||
|
-a "-vn -c:a libopus -b:a 192K" -e .opus -r '\.mp3$'
|
||||||
|
# Convert .mp3 files to Opus format, 192 kbit/s, no cover art
|
||||||
-a "-y -map 0 -c:a aac -b:a 240k -c:v copy" -e mp4
|
-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
|
# Convert to MP4 format, using AAC 240 kbit/s audio, cover art, overwrite file
|
||||||
--file "/path/to/audio/a-ha/Hunting High and Low/01 Take on Me.flac"
|
--file "/path/to/audio/a-ha/Hunting High and Low/01 Take on Me.flac"
|
||||||
# Batch Mode
|
# Batch Mode
|
||||||
# Output 320kbit/s MP3
|
# Output 320kbit/s MP3
|
||||||
-o "/path/to/audio" -k
|
-o "/path/to/audio" -k
|
||||||
# Place the converted file(s) in the specified directory and do not delete the original audio file(s).
|
# Place the converted file(s) in the specified directory and do not delete the original audio file(s)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Wrapper Scripts
|
|
||||||
To supply arguments to the script, one of the included wrapper scripts may be used or a custom wrapper script must be created.
|
|
||||||
|
|
||||||
#### Included Wrapper Scripts
|
#### Included Wrapper Scripts
|
||||||
For your convenience, several wrapper scripts are included in the `/usr/local/bin/` directory.
|
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.
|
You may use any of these scripts in place of the `flac2mp3.sh` mentioned in the [Installation](./README.md#installation) section above.
|
||||||
@@ -141,6 +156,26 @@ Then put `/config/flac2mp3-custom.sh` in the **Path** field in place of `/usr/lo
|
|||||||
|
|
||||||
>**Note:** If you followed the Linuxserver.io recommendations when configuring your container, the `/config` directory will be mapped to an external storage location. It is therefore recommended to place custom scripts in the `/config` directory so they will survive container updates, but they may be placed anywhere that is accessible by Lidarr.
|
>**Note:** If you followed the Linuxserver.io recommendations when configuring your container, the `/config` directory will be mapped to an external storage location. It is therefore recommended to place custom scripts in the `/config` directory so they will survive container updates, but they may be placed anywhere that is accessible by Lidarr.
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
```
|
||||||
|
-e FLAC2MP3_ARGS='-a "-vn -c:a libopus -b:a 192k" -e .opus -r "\\.mp3$"'
|
||||||
|
```
|
||||||
|
|
||||||
|
Make sure to correctly use quotes and/or escape special characters when using this method. (See [regex notes](./README.md#technical-notes-on-regex) above.)
|
||||||
|
In Docker Compose, the previous command would need an extra `$` to match the end-of-line:
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
- FLAC2MP3_ARGS=-a "-vn -c:a libopus -b:a 192k" -e .opus -r '\\.mp3$$'
|
||||||
|
```
|
||||||
|
|
||||||
|
*Example Synology Configuration*
|
||||||
|

|
||||||
|
|
||||||
|
>**NOTE:** The environment variable settings are _only_ used when **no** command line arguments are present. **Any** command line argument will disable the use of the environment variable.
|
||||||
|
|
||||||
### Triggers
|
### Triggers
|
||||||
The only events/notification triggers that are supported are **On Release Import** and **On Upgrade**
|
The only events/notification triggers that are supported are **On Release Import** and **On Upgrade**
|
||||||
|
|
||||||
@@ -171,6 +206,21 @@ 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.
|
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.*
|
>![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.
|
||||||
|
|
||||||
|
List of supported tags and metadata corrections that are applied:
|
||||||
|
|
||||||
|
|Tag|Original|Correction
|
||||||
|
|---|---|---
|
||||||
|
|disc|1|1/1
|
||||||
|
|genre|/Pop/|"Pop"
|
||||||
|
| |/Indie/|"Alternative & Indie"
|
||||||
|
| |/Industrial/|"Industrial Rock"
|
||||||
|
| |/Electronic/|"Electronica & Dance"
|
||||||
|
| |/Punk\|Alternative/|"Alternative & Punk"
|
||||||
|
| |/Rock/|"Rock"
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
This would not be possible without the following:
|
This would not be possible without the following:
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -6,8 +6,8 @@ Only the latest major and minor version are supported.
|
|||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| ------- | ------------------ |
|
| ------- | ------------------ |
|
||||||
| 2.0.x | :heavy_check_mark: |
|
| 2.2.x | :heavy_check_mark: |
|
||||||
| < 2.0 | :x: |
|
| < 2.2 | :x: |
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
|||||||
@@ -44,4 +44,3 @@ if [ ! -x /usr/local/bin/flac2mp3.sh ]; then
|
|||||||
echo "Making scripts executable."
|
echo "Making scripts executable."
|
||||||
chmod +x /usr/local/bin/flac2*.sh
|
chmod +x /usr/local/bin/flac2*.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -15,17 +15,22 @@ EOF
|
|||||||
if [ ! -f /usr/bin/ffmpeg ]; then
|
if [ ! -f /usr/bin/ffmpeg ]; then
|
||||||
echo "**** Adding ffmpeg to package install list ****"
|
echo "**** Adding ffmpeg to package install list ****"
|
||||||
echo "ffmpeg" >> /mod-repo-packages-to-install.list
|
echo "ffmpeg" >> /mod-repo-packages-to-install.list
|
||||||
|
else
|
||||||
|
echo "**** flac2mp3 deps already installed, skipping ****"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check ownership and attributes on each script file
|
||||||
|
for file in /usr/local/bin/flac2mp3*.sh
|
||||||
|
do
|
||||||
# Change ownership
|
# Change ownership
|
||||||
if [ $(stat -c '%G' /usr/local/bin/flac2mp3.sh) != "abc" ]; then
|
if [ $(stat -c '%G' $file) != "abc" ]; then
|
||||||
echo "Changing ownership on scripts."
|
echo "Changing ownership on $file script."
|
||||||
chown abc:abc /usr/local/bin/flac2*.sh
|
chown abc:abc $file
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make executable
|
# Make executable
|
||||||
if [ ! -x /usr/local/bin/flac2mp3.sh ]; then
|
if [ ! -x $file ]; then
|
||||||
echo "Making scripts executable."
|
echo "Making $file script executable."
|
||||||
chmod +x /usr/local/bin/flac2*.sh
|
chmod +x $file
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. /usr/local/bin/flac2mp3.sh --tags disc,genre
|
||||||
+203
-45
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
# Dependencies:
|
# Dependencies:
|
||||||
# ffmpeg
|
# ffmpeg
|
||||||
|
# ffprobe
|
||||||
# awk
|
# awk
|
||||||
# curl
|
# curl
|
||||||
# jq
|
# jq
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
|
|
||||||
# Exit codes:
|
# Exit codes:
|
||||||
# 0 - success; or test
|
# 0 - success; or test
|
||||||
# 1 - no audio file specified on command line
|
# 1 - no audio tracks detected
|
||||||
# 2 - ffmpeg not found
|
# 2 - ffmpeg not found
|
||||||
# 3 - invalid command line arguments
|
# 3 - invalid command line arguments
|
||||||
# 5 - specified audio file not found
|
# 5 - specified audio file not found
|
||||||
@@ -48,20 +49,21 @@ Audio conversion script designed for use with Lidarr
|
|||||||
Source: https://github.com/TheCaptain989/lidarr-flac2mp3
|
Source: https://github.com/TheCaptain989/lidarr-flac2mp3
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
$0 [OPTIONS] [-b <bitrate> | -v <quality> | -a \"<options>\" -e <extension>]
|
$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 [OPTIONS] {-f|--file} <audio_file>
|
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-d, --debug [<level>] enable debug logging
|
-d, --debug [<level>] Enable debug logging
|
||||||
Level is optional, default of 1 (low)
|
level is optional, between 1-3
|
||||||
-b, --bitrate <bitrate> set output quality in constant bits per second
|
1 is lowest, 3 is highest
|
||||||
|
[default: 1]
|
||||||
|
-b, --bitrate <bitrate> Set output quality in constant bits per second
|
||||||
[default: 320k]
|
[default: 320k]
|
||||||
Ex: 160k, 240k, 300000
|
Ex: 160k, 240k, 300000
|
||||||
-v, --quality <quality> set variable bitrate; quality between 0-9
|
-v, --quality <quality> Set variable bitrate; quality between 0-9
|
||||||
0 is highest quality, 9 is lowest
|
0 is highest quality, 9 is lowest
|
||||||
For more details, see:
|
For more details, see:
|
||||||
https://trac.ffmpeg.org/wiki/Encode/MP3
|
https://trac.ffmpeg.org/wiki/Encode/MP3
|
||||||
-a, --advanced \"<options>\" advanced ffmpeg options enclosed in quotes
|
-a, --advanced \"<options>\" Advanced ffmpeg options enclosed in quotes
|
||||||
Specified options replace all script defaults
|
Specified options replace all script defaults
|
||||||
and are sent as entered to ffmpeg for
|
and are sent as entered to ffmpeg for
|
||||||
processing.
|
processing.
|
||||||
@@ -73,32 +75,40 @@ Options:
|
|||||||
Requires -e option to also be specified
|
Requires -e option to also be specified
|
||||||
For more details, see:
|
For more details, see:
|
||||||
https://github.com/TheCaptain989/lidarr-flac2mp3
|
https://github.com/TheCaptain989/lidarr-flac2mp3
|
||||||
-e, --extension <extension> file extension for output file, with or without
|
-e, --extension <extension> File extension for output file, with or without
|
||||||
dot
|
dot
|
||||||
Required when -a is specified!
|
Required when -a is specified!
|
||||||
-f, --file <audio_file> the script enters batch mode, using the
|
-f, --file <audio_file> The script enters batch mode, using the
|
||||||
specified audio file as input
|
specified audio file as input
|
||||||
WARNING: Do not use this argument when called
|
WARNING: Do not use this argument when called
|
||||||
from Lidarr!
|
from Lidarr!
|
||||||
-o, --output <directory> specify a directory for the converted audio
|
-o, --output <directory> Specify a destination directory for the
|
||||||
file(s)
|
converted audio file(s)
|
||||||
This will be created if it does not exist.
|
It will be created if it does not exist.
|
||||||
-k, --keep-file do not delete the source file or move it to the
|
-k, --keep-file Do not delete the source file or move it to the
|
||||||
Lidarr Recycle bin
|
Lidarr Recycle bin
|
||||||
This also disables the Lidarr rescan.
|
This also disables the Lidarr rescan.
|
||||||
--help display this help and exit
|
-r, --regex '<regex>' Regular expression used to select input files
|
||||||
--version display script version and exit
|
[default: \.flac$]
|
||||||
|
-t, --tags <taglist> Comma separated list of metadata tags to apply
|
||||||
|
automated corrections to.
|
||||||
|
Supports: disc, genre
|
||||||
|
--help Display this help and exit
|
||||||
|
--version Display script version and exit
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
$flac2mp3_script -b 320k # Output 320 kbit/s MP3 (non-VBR; same as
|
$flac2mp3_script -b 320k # Output 320 kbit/s MP3 (non-VBR; same as
|
||||||
default behavior)
|
default behavior)
|
||||||
$flac2mp3_script -v 0 # Output variable bitrate MP3, VBR 220-260
|
$flac2mp3_script -v 0 # Output variable bitrate MP3, VBR 220-260
|
||||||
kbit/s
|
kbit/s
|
||||||
$flac2mp3_script -d -b 160k # Enable debugging level 1 and set output a
|
$flac2mp3_script -d -b 160k # Enable debugging level 1 and output a
|
||||||
160 kbit/s MP3
|
160 kbit/s MP3
|
||||||
$flac2mp3_script -a \"-vn -c:a libopus -b:a 192K\" -e .opus
|
$flac2mp3_script -r '\\\\.[^.]*$' # Convert any file to MP3 (not just FLAC)
|
||||||
# Convert to Opus format, VBR 192 kbit/s, no
|
$flac2mp3_script -a \"-c:v libtheora -map 0 -q:v 10 -c:a libopus -b:a 192k\" -e .opus
|
||||||
cover art
|
# Convert to Opus format, 192 kbit/s, cover art
|
||||||
|
$flac2mp3_script -a \"-vn -c:a libopus -b:a 192K\" -e .opus -r '\.mp3$'
|
||||||
|
# Convert .mp3 files to Opus format, 192 kbit/s
|
||||||
|
no cover art
|
||||||
$flac2mp3_script -a \"-y -map 0 -c:a aac -b:a 240K -c:v copy\" -e mp4
|
$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
|
# Convert to MP4 format, using AAC 240 kbit/s
|
||||||
audio, cover art, overwrite file
|
audio, cover art, overwrite file
|
||||||
@@ -107,12 +117,23 @@ Examples:
|
|||||||
Output 320 kbit/s MP3
|
Output 320 kbit/s MP3
|
||||||
$flac2mp3_script -o \"/path/to/audio\" -k
|
$flac2mp3_script -o \"/path/to/audio\" -k
|
||||||
# Place the converted file(s) in specified
|
# Place the converted file(s) in specified
|
||||||
directory and do not delete the original audio
|
directory and do not delete the original
|
||||||
file(s).
|
audio file(s)
|
||||||
"
|
"
|
||||||
echo "$usage" >&2
|
echo "$usage" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check for environment variable arguments
|
||||||
|
if [ -n "$FLAC2MP3_ARGS" ]; then
|
||||||
|
if [ $# -ne 0 ]; then
|
||||||
|
flac2mp3_prelogmessage="Warning|FLAC2MP3_ARGS environment variable set but will be ignored because command line arguments were also specified."
|
||||||
|
else
|
||||||
|
# Move the environment variable arguments to the command line for processing
|
||||||
|
flac2mp3_prelogmessage="Info|Using settings from environment variable."
|
||||||
|
eval set -- "$FLAC2MP3_ARGS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Process arguments
|
# Process arguments
|
||||||
while (( "$#" )); do
|
while (( "$#" )); do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@@ -142,7 +163,7 @@ while (( "$#" )); do
|
|||||||
else
|
else
|
||||||
echo "Error|Invalid option: $1 requires an argument." >&2
|
echo "Error|Invalid option: $1 requires an argument." >&2
|
||||||
usage
|
usage
|
||||||
exit 1
|
exit 3
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
-b|--bitrate ) # Set constant bit rate
|
-b|--bitrate ) # Set constant bit rate
|
||||||
@@ -220,13 +241,33 @@ while (( "$#" )); do
|
|||||||
usage
|
usage
|
||||||
exit 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
# Test for trailing slash
|
# Test for trailing backslash
|
||||||
[ "${flac2mp3_output: -1:1}" != "/" ] && flac2mp3_output="${flac2mp3_output}/"
|
[ "${flac2mp3_output: -1:1}" != "/" ] && flac2mp3_output="${flac2mp3_output}/"
|
||||||
;;
|
;;
|
||||||
-k|--keep-file ) # Do not delete source file(s)
|
-k|--keep-file ) # Do not delete source file(s)
|
||||||
export flac2mp3_keep=1
|
export flac2mp3_keep=1
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
-r|--regex ) # Sets the regex used to match input files
|
||||||
|
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
|
||||||
|
export flac2mp3_regex="$2"
|
||||||
|
shift 2
|
||||||
|
else
|
||||||
|
echo "Error|Invalid option: $1 requires an argument." >&2
|
||||||
|
usage
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-t|--tags ) # Metadata tags to correct
|
||||||
|
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
|
||||||
|
export flac2mp3_tags="$2"
|
||||||
|
shift 2
|
||||||
|
else
|
||||||
|
echo "Error|Invalid option: $1 requires an argument." >&2
|
||||||
|
usage
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
;;
|
||||||
-*|--*=) # Unknown option
|
-*|--*=) # Unknown option
|
||||||
echo "Error|Unknown option: $1" >&2
|
echo "Error|Unknown option: $1" >&2
|
||||||
usage
|
usage
|
||||||
@@ -258,7 +299,7 @@ elif [[ "${flac2mp3_type,,}" = "lidarr" ]]; then
|
|||||||
[ -z "$flac2mp3_tracks" ] && flac2mp3_tracks="$lidarr_trackfile_path"
|
[ -z "$flac2mp3_tracks" ] && flac2mp3_tracks="$lidarr_trackfile_path"
|
||||||
else
|
else
|
||||||
# Called in an unexpected way
|
# Called in an unexpected way
|
||||||
echo -e "Error|Unknown or missing 'lidarr_eventtype' environment variable: ${flac2mp3_type}\nNot called within Lidarr?\nTry using Batch Mode option: -f <file>"
|
echo -e "Error|Unknown or missing 'lidarr_eventtype' environment variable: ${flac2mp3_type}\nNot called from Lidarr.\nTry using Batch Mode option: -f <file>"
|
||||||
exit 7
|
exit 7
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -330,6 +371,7 @@ function check_rescan {
|
|||||||
done
|
done
|
||||||
return $flac2mp3_return
|
return $flac2mp3_return
|
||||||
}
|
}
|
||||||
|
### End Functions
|
||||||
|
|
||||||
# Check for required binaries
|
# Check for required binaries
|
||||||
if [ ! -f "/usr/bin/ffmpeg" ]; then
|
if [ ! -f "/usr/bin/ffmpeg" ]; then
|
||||||
@@ -338,12 +380,25 @@ if [ ! -f "/usr/bin/ffmpeg" ]; then
|
|||||||
echo "$flac2mp3_message" >&2
|
echo "$flac2mp3_message" >&2
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
# Log Debug state
|
# Log Debug state
|
||||||
if [ $flac2mp3_debug -ge 1 ]; then
|
if [ $flac2mp3_debug -ge 1 ]; then
|
||||||
flac2mp3_message="Debug|Enabling debug logging level ${flac2mp3_debug}. Starting ${lidarr_eventtype^} run."
|
flac2mp3_message="Debug|Enabling debug logging level ${flac2mp3_debug}. Starting ${lidarr_eventtype^} run."
|
||||||
echo "$flac2mp3_message" | log
|
echo "$flac2mp3_message" | log
|
||||||
echo "$flac2mp3_message" >&2
|
echo "$flac2mp3_message"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Log FLAC2MP3_ARGS usage
|
||||||
|
if [ -n "$flac2mp3_prelogmessage" ]; then
|
||||||
|
# flac2mp3_prelogmessage is set above, before argument processing
|
||||||
|
echo "$flac2mp3_prelogmessage" | log
|
||||||
|
[ $flac2mp3_debug -ge 1 ] && echo "Debug|FLAC2MP3_ARGS: ${FLAC2MP3_ARGS}" | log
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Log environment
|
# Log environment
|
||||||
@@ -392,13 +447,30 @@ elif [ -f "$flac2mp3_config" ]; then
|
|||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-X GET "$flac2mp3_api_url/config/mediamanagement")
|
-X GET "$flac2mp3_api_url/config/mediamanagement")
|
||||||
flac2mp3_return=$?; [ "$flac2mp3_return" != 0 ] && {
|
flac2mp3_return=$?; [ "$flac2mp3_return" != 0 ] && {
|
||||||
flac2mp3_message="Error|[$flac2mp3_return] curl error when parsing: \"$flac2mp3_api_url/v3/config/mediamanagement\""
|
flac2mp3_message="Error|[$flac2mp3_return] curl error when parsing: \"$flac2mp3_api_url/config/mediamanagement\""
|
||||||
echo "$flac2mp3_message" | log
|
echo "$flac2mp3_message" | log
|
||||||
echo "$flac2mp3_message" >&2
|
echo "$flac2mp3_message" >&2
|
||||||
}
|
}
|
||||||
[ $flac2mp3_debug -ge 2 ] && echo "API returned: $flac2mp3_result" | awk '{print "Debug|"$0}' | log
|
[ $flac2mp3_debug -ge 2 ] && echo "API returned: $flac2mp3_result" | awk '{print "Debug|"$0}' | log
|
||||||
flac2mp3_recyclebin="$(echo $flac2mp3_result | jq -crM .recycleBin)"
|
flac2mp3_recyclebin="$(echo $flac2mp3_result | jq -crM .recycleBin)"
|
||||||
|
# Test for trailing backslash
|
||||||
|
[ "${flac2mp3_recyclebin: -1:1}" != "/" ] && flac2mp3_recyclebin="${flac2mp3_recyclebin}/"
|
||||||
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Detected Lidarr RecycleBin '$flac2mp3_recyclebin'" | log
|
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Detected Lidarr RecycleBin '$flac2mp3_recyclebin'" | log
|
||||||
|
|
||||||
|
# Get root folder path from Artist info
|
||||||
|
if [ "$lidarr_artist_id" != "" ]; then
|
||||||
|
flac2mp3_result=$(curl -s -H "X-Api-Key: $flac2mp3_apikey" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-X GET $flac2mp3_api_url/artist/$lidarr_artist_id)
|
||||||
|
flac2mp3_return=$?; [ "$flac2mp3_return" != 0 ] && {
|
||||||
|
flac2mp3_message="Error|[$flac2mp3_return] curl error when parsing: \"$flac2mp3_api_url/artist/$lidarr_artist_id\""
|
||||||
|
echo "$flac2mp3_message" | log
|
||||||
|
echo "$flac2mp3_message" >&2
|
||||||
|
}
|
||||||
|
[ $flac2mp3_debug -ge 2 ] && echo "API returned: $flac2mp3_result" | awk '{print "Debug|"$0}' | log
|
||||||
|
flac2mp3_root="$(echo $flac2mp3_result | jq -crM .rootFolderPath)"
|
||||||
|
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Detected Lidarr Root Folder '$flac2mp3_root'" | log
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
# No config file means we can't call the API. Best effort at this point.
|
# 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'"
|
flac2mp3_message="Warn|Unable to locate Lidarr config file: '$flac2mp3_config'"
|
||||||
@@ -411,7 +483,7 @@ if [[ "$lidarr_eventtype" = "Test" ]]; then
|
|||||||
echo "Info|Lidarr event: $lidarr_eventtype" | log
|
echo "Info|Lidarr event: $lidarr_eventtype" | log
|
||||||
flac2mp3_message="Info|Script was test executed successfully."
|
flac2mp3_message="Info|Script was test executed successfully."
|
||||||
echo "$flac2mp3_message" | log
|
echo "$flac2mp3_message" | log
|
||||||
echo "$flac2mp3_message" >&2
|
echo "$flac2mp3_message"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -423,6 +495,14 @@ if [ "$flac2mp3_type" = "batch" -a ! -f "$flac2mp3_tracks" ]; then
|
|||||||
exit 5
|
exit 5
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check for empty track variable
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
# If specified, check if destination folder exists and create if necessary
|
# If specified, check if destination folder exists and create if necessary
|
||||||
if [ "$flac2mp3_output" -a ! -d "$flac2mp3_output" ]; then
|
if [ "$flac2mp3_output" -a ! -d "$flac2mp3_output" ]; then
|
||||||
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Destination directory does not exist. Creating: $flac2mp3_output" | log
|
[ $flac2mp3_debug -ge 1 ] && echo "Debug|Destination directory does not exist. Creating: $flac2mp3_output" | log
|
||||||
@@ -439,6 +519,7 @@ fi
|
|||||||
#find "$lidarr_artist_path" -name "*.flac" -exec bash -c 'ffmpeg -loglevel warning -i "{}" -y -acodec libmp3lame -b:a 320k "${0/.flac}.mp3" && rm "{}"' {} \;
|
#find "$lidarr_artist_path" -name "*.flac" -exec bash -c 'ffmpeg -loglevel warning -i "{}" -y -acodec libmp3lame -b:a 320k "${0/.flac}.mp3" && rm "{}"' {} \;
|
||||||
|
|
||||||
#### BEGIN MAIN
|
#### BEGIN MAIN
|
||||||
|
# Build dynamic log message
|
||||||
flac2mp3_message="Info|Lidarr event: ${lidarr_eventtype}"
|
flac2mp3_message="Info|Lidarr event: ${lidarr_eventtype}"
|
||||||
if [ "$flac2mp3_type" != "batch" ]; then
|
if [ "$flac2mp3_type" != "batch" ]; then
|
||||||
flac2mp3_message+=", Artist: ${lidarr_artist_name} (${lidarr_artist_id}), Album: ${lidarr_album_title} (${lidarr_album_id})"
|
flac2mp3_message+=", Artist: ${lidarr_artist_name} (${lidarr_artist_id}), Album: ${lidarr_album_title} (${lidarr_album_id})"
|
||||||
@@ -454,23 +535,32 @@ fi
|
|||||||
if [ $flac2mp3_keep = 1 ]; then
|
if [ $flac2mp3_keep = 1 ]; then
|
||||||
flac2mp3_message+=", Keep source"
|
flac2mp3_message+=", Keep source"
|
||||||
fi
|
fi
|
||||||
|
if [ -n "$flac2mp3_regex" ]; then
|
||||||
|
flac2mp3_message+=", Matching regex: '${flac2mp3_regex}'"
|
||||||
|
fi
|
||||||
flac2mp3_message+=", Track(s): ${flac2mp3_tracks}"
|
flac2mp3_message+=", Track(s): ${flac2mp3_tracks}"
|
||||||
echo "${flac2mp3_message}" | log
|
echo "${flac2mp3_message}" | log
|
||||||
|
|
||||||
|
# Process tracks
|
||||||
echo -n "$flac2mp3_tracks" | awk -v Debug=$flac2mp3_debug \
|
echo -n "$flac2mp3_tracks" | awk -v Debug=$flac2mp3_debug \
|
||||||
-v Recycle="$flac2mp3_recyclebin" \
|
-v Recycle="$flac2mp3_recyclebin" \
|
||||||
-v Bitrate="$flac2mp3_bitrate" \
|
-v Bitrate="$flac2mp3_bitrate" \
|
||||||
-v VBR="$flac2mp3_vbrquality" \
|
-v VBR="$flac2mp3_vbrquality" \
|
||||||
-v FFmpegADV="$flac2mp3_ffmpegadv" \
|
-v FFmpegADV="$flac2mp3_ffmpegadv" \
|
||||||
-v EXT="$flac2mp3_extension" \
|
-v Ext="$flac2mp3_extension" \
|
||||||
-v Output="$flac2mp3_output" \
|
-v Output="$flac2mp3_output" \
|
||||||
-v Keep="$flac2mp3_keep" '
|
-v Keep=$flac2mp3_keep \
|
||||||
|
-v Pat="$flac2mp3_regex" \
|
||||||
|
-v Root="$flac2mp3_root" \
|
||||||
|
-v Taglist="$flac2mp3_tags" '
|
||||||
BEGIN {
|
BEGIN {
|
||||||
FFmpeg = "/usr/bin/ffmpeg"
|
FFmpeg = "/usr/bin/ffmpeg"
|
||||||
FS = "|"
|
FS = "|"
|
||||||
RS = "|"
|
RS = "|"
|
||||||
IGNORECASE = 1
|
IGNORECASE = 1
|
||||||
if (EXT == "") EXT=".mp3"
|
# Set default extension, pattern, and logging values
|
||||||
|
if (Ext == "") Ext = ".mp3"
|
||||||
|
if (Pat == "") Pat = "\\.flac$"
|
||||||
if (Debug == 0) FFmpegLOG = "error"
|
if (Debug == 0) FFmpegLOG = "error"
|
||||||
else if (Debug == 1) FFmpegLOG = "warning"
|
else if (Debug == 1) FFmpegLOG = "warning"
|
||||||
else if (Debug >= 2) FFmpegLOG = "info"
|
else if (Debug >= 2) FFmpegLOG = "info"
|
||||||
@@ -481,27 +571,77 @@ BEGIN {
|
|||||||
if (Debug >= 1) print "Debug|Using variable quality of "VBR
|
if (Debug >= 1) print "Debug|Using variable quality of "VBR
|
||||||
BrCommand = "-q:a "VBR
|
BrCommand = "-q:a "VBR
|
||||||
} else if (FFmpegADV) {
|
} else if (FFmpegADV) {
|
||||||
if (Debug >= 1) print "Debug|Using advanced ffmpeg options: \""FFmpegADV"\""
|
if (Debug >= 1) print "Debug|Using advanced ffmpeg options \""FFmpegADV"\""
|
||||||
if (Debug >= 1) print "Debug|Exporting with file extension "EXT
|
if (Debug >= 1) print "Debug|Exporting with file extension \""Ext"\""
|
||||||
|
FFmpegOPTS = FFmpegADV
|
||||||
}
|
}
|
||||||
|
if (Debug >= 1) print "Debug|Matching tracks against regex \""Pat"\""
|
||||||
|
# Set default ffmpeg options
|
||||||
|
if (FFmpegOPTS == "") FFmpegOPTS = "-c:v copy -map 0 -y -acodec libmp3lame "BrCommand" -write_id3v1 1 -id3v2_version 3"
|
||||||
}
|
}
|
||||||
/\.flac$/ {
|
$0 !~ Pat {
|
||||||
# Get each FLAC file name and create a new MP3 (or other) name
|
if (Debug >= 1) print "Debug|Skipping track that did not match regex: "$0
|
||||||
Track=$1
|
}
|
||||||
NewTrack=substr(Track, 1, length(Track)-5) EXT
|
$0 ~ Pat {
|
||||||
|
# Get each audio file name and create a new track name with the given extension
|
||||||
|
Track = $0
|
||||||
|
Last = split(Track, Parts, ".")
|
||||||
|
NewTrack = substr(Track, 1, length(Track) - length(Parts[Last]) - 1) Ext
|
||||||
# Redirect output if asked
|
# Redirect output if asked
|
||||||
if (Output) sub(/^.*\//, Output, NewTrack)
|
if (Output) sub(/^.*\//, Output, NewTrack)
|
||||||
|
# Check for same track name
|
||||||
|
if (Track == NewTrack) {
|
||||||
|
print "Error|The original track name and new name are the same! Skipping track: "Track
|
||||||
|
next
|
||||||
|
}
|
||||||
|
# Set metadata options to fix tags if asked
|
||||||
|
if (Taglist) {
|
||||||
|
Metadata = ""; JSON = ""
|
||||||
|
NumTags = split(Taglist, Tag, ",")
|
||||||
|
if (Debug >= 1) print "Debug|Detecting and fixing common problems with the following metadata tags: "Taglist
|
||||||
|
Command = "/usr/bin/ffprobe -hide_banner -loglevel fatal -print_format json=compact=1 -show_format -show_entries \"format=tags : format_tags=disc,genre\" -i \""Track"\" 2>&1"
|
||||||
|
if (Debug >= 2) print "Debug|Executing: "Command
|
||||||
|
# Concatenate FFprobe output into one line
|
||||||
|
while (Command | getline Line) JSON = JSON Line
|
||||||
|
for (i = 1; i <= NumTags; i++) {
|
||||||
|
if (Tag[i] == "disc") {
|
||||||
|
# Fix one disc by itself (\47 is single quote in octal)
|
||||||
|
Command = "echo \47"JSON"\47 | jq -crM \47.format.tags.disc\47 2>&1"
|
||||||
|
if (Debug >= 2) print "Debug|Executing: "Command
|
||||||
|
Command | getline Disc
|
||||||
|
sub(/\n/, "", Disc) # I do not yet know why this is needed
|
||||||
|
if (Debug >= 1) print "Debug|Discovered disc: "Disc
|
||||||
|
if (Disc ~ /^1$/) Metadata = "-metadata disc=\"1/1\" "Metadata
|
||||||
|
}
|
||||||
|
if (Tag[i] == "genre") {
|
||||||
|
# Fix multiple genres
|
||||||
|
Command = "echo \47"JSON"\47 | jq -crM \47.format.tags | to_entries[] | select(.key | match(\"genre\";\"i\")).value\47 2>&1"
|
||||||
|
if (Debug >= 2) print "Debug|Executing: "Command
|
||||||
|
Command | getline Genre
|
||||||
|
sub(/\n/, "", Genre) # I do not yet know why this is needed
|
||||||
|
if (Debug >= 1) print "Debug|Discovered genre: "Genre
|
||||||
|
if (Genre ~ /;/) {
|
||||||
|
if (Genre ~ /Pop/) Metadata = "-metadata genre=\"Pop\" "Metadata
|
||||||
|
else if (Genre ~ /Indie/) Metadata = "-metadata genre=\"Alternative & Indie\" "Metadata
|
||||||
|
else if (Genre ~ /Industrial/) Metadata = "-metadata genre=\"Industrial Rock\" "Metadata
|
||||||
|
else if (Genre ~ /Electronic/) Metadata = "-metadata genre=\"Electronica & Dance\" "Metadata
|
||||||
|
else if (Genre ~ /Punk|Alternative/) Metadata = "-metadata genre=\"Alternative & Punk\" "Metadata
|
||||||
|
else if (Genre ~ /Rock/) Metadata = "-metadata genre=\"Rock\" "Metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Debug >= 2) print "Debug|Metadata on pass "i"/"NumTags": "Metadata
|
||||||
|
}
|
||||||
|
}
|
||||||
print "Info|Writing: "NewTrack
|
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
|
# Convert the track
|
||||||
if (Debug >= 1) print "Debug|Executing: nice "FFmpeg" -loglevel "FFmpegLOG" -nostdin -i \""Track"\" "FFmpegOPTS" \""NewTrack"\""
|
Command = "nice "FFmpeg" -loglevel "FFmpegLOG" -nostdin -i \""Track"\" "FFmpegOPTS" "Metadata"\""NewTrack"\" 2>&1"
|
||||||
Result=system("nice "FFmpeg" -loglevel "FFmpegLOG" -nostdin -i \""Track"\" "FFmpegOPTS" \""NewTrack"\" 2>&1")
|
if (Debug >= 1) print "Debug|Executing: "Command
|
||||||
|
Result = system(Command)
|
||||||
if (Debug >= 2) print "Debug|ffmpeg exited"
|
if (Debug >= 2) print "Debug|ffmpeg exited"
|
||||||
if (Result) {
|
if (Result) {
|
||||||
print "Error|Exit code "Result" converting \""Track"\""
|
print "Error|Exit code "Result" converting \""Track"\""
|
||||||
} else {
|
} else {
|
||||||
|
# Build system command to set owner and permissions, etc.
|
||||||
if (Keep == 1) {
|
if (Keep == 1) {
|
||||||
# Do not delete the source file
|
# Do not delete the source file
|
||||||
if (Debug >= 1) print "Debug|Keeping original: \""Track"\" and setting permissions on \""NewTrack"\""
|
if (Debug >= 1) print "Debug|Keeping original: \""Track"\" and setting permissions on \""NewTrack"\""
|
||||||
@@ -513,20 +653,38 @@ BEGIN {
|
|||||||
Command = "if [ -s \""NewTrack"\" ]; then if [ -f \""Track"\" ]; then chown --reference=\""Track"\" \""NewTrack"\"; chmod --reference=\""Track"\" \""NewTrack"\"; rm \""Track"\"; fi; fi"
|
Command = "if [ -s \""NewTrack"\" ]; then if [ -f \""Track"\" ]; then chown --reference=\""Track"\" \""NewTrack"\"; chmod --reference=\""Track"\" \""NewTrack"\"; rm \""Track"\"; fi; fi"
|
||||||
} else {
|
} 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
|
# 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
|
||||||
|
if (Root == "") {
|
||||||
|
# Legacy way in case the Root music folder cannot be determined
|
||||||
|
print "Warning|Root music folder is blank. Falling back to legacy split method."
|
||||||
match(Track, /^\/?[^\/]+\//)
|
match(Track, /^\/?[^\/]+\//)
|
||||||
|
} else {
|
||||||
|
# The following logic tests that the Root folder is a substring of the Track folder, though based on the observed Lidarr behavior this should be a safe assumption. A warning is displayed just in case.
|
||||||
|
RSTART = index(Track, Root)
|
||||||
|
if (RSTART) {
|
||||||
|
RLENGTH = length(Root)
|
||||||
|
} else {
|
||||||
|
print "Warning|The root music folder \""Root"\" is not part of \""Track"\". Recycled tracks may not appear as expected."
|
||||||
|
RLENGTH = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Debug >= 2) print "Debug|Splitting track name on RSTART: "RSTART", RLENGTH: "RLENGTH" to prepend recycle path."
|
||||||
RecPath = substr(Track, RSTART + RLENGTH)
|
RecPath = substr(Track, RSTART + RLENGTH)
|
||||||
sub(/[^\/]+$/,"",RecPath)
|
sub(/^\/+/, "", RecPath) # remove trailing track name
|
||||||
|
sub(/[^\/]+$/, "", RecPath) # remove leading backslash
|
||||||
RecPath = Recycle RecPath
|
RecPath = Recycle RecPath
|
||||||
if (Debug >= 1) print "Debug|Recycling: \""Track"\" to \""RecPath"\" and setting permissions on \""NewTrack"\""
|
if (Debug >= 1) 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"
|
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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# Set owner, permissions, etc.
|
||||||
if (Debug >= 2) print "Debug|Executing: "Command
|
if (Debug >= 2) print "Debug|Executing: "Command
|
||||||
system(Command)
|
Result = system(Command)
|
||||||
|
if (Result) {
|
||||||
|
print "Error|Exit code "Result" setting permissions and/or recycling on \""NewTrack"\""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
' | log
|
' | log
|
||||||
|
|
||||||
#### END MAIN
|
#### END MAIN
|
||||||
|
|
||||||
# Check for awk script completion
|
# Check for awk script completion
|
||||||
|
|||||||
Reference in New Issue
Block a user