diff --git a/.assets/lidarr-custom-script.png b/.assets/lidarr-custom-script.png new file mode 100644 index 0000000..6a68132 Binary files /dev/null and b/.assets/lidarr-custom-script.png differ diff --git a/.assets/lidarr-synology.png b/.assets/lidarr-synology.png new file mode 100644 index 0000000..d29fe58 Binary files /dev/null and b/.assets/lidarr-synology.png differ diff --git a/.assets/striptracks-synology.png b/.assets/striptracks-synology.png deleted file mode 100644 index 84c9af7..0000000 Binary files a/.assets/striptracks-synology.png and /dev/null differ diff --git a/.assets/striptracks-v2-custom-script.png b/.assets/striptracks-v2-custom-script.png deleted file mode 100644 index 7a2b2fe..0000000 Binary files a/.assets/striptracks-v2-custom-script.png and /dev/null differ diff --git a/.assets/striptracks-v3-custom-script.png b/.assets/striptracks-v3-custom-script.png deleted file mode 100644 index d9e8564..0000000 Binary files a/.assets/striptracks-v3-custom-script.png and /dev/null differ diff --git a/.github/workflows/BuildImage.yml b/.github/workflows/BuildImage.yml index 7758aa8..0f07c57 100644 --- a/.github/workflows/BuildImage.yml +++ b/.github/workflows/BuildImage.yml @@ -6,8 +6,13 @@ jobs: build: env: DOCKERHUB: "linuxserver/mods" #don't modify +<<<<<<< HEAD BASEIMAGE: "baseimagename" #replace MODNAME: "modname" #replace +======= + BASEIMAGE: "lidarr" #replace + MODNAME: "flac2mp3" #replace +>>>>>>> 38e21e1... Initial release runs-on: ubuntu-latest steps: @@ -17,7 +22,10 @@ jobs: id: build run: | docker build --no-cache -t ${DOCKERHUB}:${BASEIMAGE}-${MODNAME}-${{ github.sha }} . +<<<<<<< HEAD +======= +>>>>>>> 38e21e1... Initial release - name: Push image if: ${{ github.ref == format('refs/heads/{0}-{1}', env.BASEIMAGE, env.MODNAME) }} run: | @@ -27,4 +35,8 @@ jobs: echo ${{ secrets.DOCKERPASS }} | docker login -u ${{ secrets.DOCKERUSER }} --password-stdin # Push all of the tags docker push ${DOCKERHUB}:${BASEIMAGE}-${MODNAME}-${{ github.sha }} +<<<<<<< HEAD docker push ${DOCKERHUB}:${BASEIMAGE}-${MODNAME} +======= + docker push ${DOCKERHUB}:${BASEIMAGE}-${MODNAME} +>>>>>>> 38e21e1... Initial release diff --git a/README.md b/README.md index 85e0b11..fdb191d 100644 --- a/README.md +++ b/README.md @@ -1,144 +1,57 @@ -A [Docker Mod](https://github.com/linuxserver/docker-mods) for the LinuxServer.io Radarr/Sonarr Docker container that adds a script to automatically strip out unwanted audio and subtitle streams, keeping only the desired languages. -Chapters, if they exist, are preserved. The Title attribute in the MKV is set to the movie title plus year (ex: `The Sting (1973)`) or the series title plus episode information (ex: `Happy! 01x01 - What Smiles Are For`). +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. -**One unified script works in both Radarr and Sonarr. Use this mod in either container!** >**NOTE:** This mod support Linux OSes only. Container info: -![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/linuxserver/mods/radarr-striptracks) +![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/linuxserver/mods/lidarr-flac2mp3)) # Installation ->**NOTE:** See the [Sonarr/Radarr v3 Builds](./README.md#sonarrradarr-v3-builds) section below for important differences to these instructions for v3 builds. - -1. Pull your selected container ([linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr "LinuxServer.io's Radarr container") or [linuxserver/sonarr](https://hub.docker.com/r/linuxserver/sonarr "LinuxServer.io's Sonarr container")) from Docker Hub: - `docker pull linuxserver/radarr:latest` OR - `docker pull linuxserver/sonarr:latest` +1. Pull the [linuxserver/lidarr](https://hub.docker.com/r/linuxserver/lidarr "LinuxServer.io's Lidarr container") docker image from Docker Hub: + `docker pull linuxserver/lidarr:latest` 2. Configure the Docker container with all the port, volume, and environment settings from the *original container documentation* here: - **[linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr "Radarr Docker container")** - **[linuxserver/sonarr](https://hub.docker.com/r/linuxserver/sonarr "Sonarr Docker container")** + **[linuxserver/lidarr](https://hub.docker.com/r/linuxserver/lidarr "Docker container")** 1. Add the **DOCKER_MODS** environment variable to the `docker create` command, as follows: - `-e DOCKER_MODS=linuxserver/mods:radarr-striptracks` + `-e DOCKER_MODS=linuxserver/mods:lidarr-flac2mp3` *Example Synology Configuration* - ![striptracks](.assets/striptracks-synology.png "Synology container settings") + ![flac2mp3](.assets/lidarr-synology.png "Synology container settings") 2. Start the container. -3. After all of the above configuration is complete, to use mkvmerge: - 1. Configure a custom script from the Radarr/Sonnar Settings->Connect screen and type the following in the **Path** field: - `/usr/local/bin/striptracks.sh` - - 2. Add the codes for the audio and subtitle languages you want to keep as **Arguments** (details in the [Syntax](./README.md#syntax) section below): - Suggested Example - **`:eng:und :eng`** +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: + `/usr/local/bin/flac2mp3.sh` ## Usage ->**NOTE:** See the [Sonarr/Radarr v3 Builds](./README.md#sonarrradarr-v3-builds) section below for important differences to these instructions for v3 builds. +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. -The source video can be any mkvtoolnix supported video format. The output is an MKV file with the same name. - -If you've configured the Radarr/Sonarr Recycle Bin path correctly, the original video will be moved there. -![warning24] **NOTE:** If you have *not* configured the Recycle Bin, the original video file will be deleted/overwritten and permanently lost. +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. ### Syntax -The script accepts two arguments and one option in the **Arguments** field: +>**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. -`[-d] ` +The script accepts two options which may be placed in the **Arguments** field: -The arguments are language codes in [ISO639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes "List of ISO 639-2 codes") format. -These are three letter abbreviations prefixed with a colon ':', such as: +`[-d] [-b ]` -* :eng -* :fre -* :spa - -...etc. - -Multiple codes may be concatenated, such as `:eng:spa` for both English and Spanish. - -It is suggested to use `:eng:und :eng` if you are unsure of what to choose. This will keep English and Undetermined audio and English subtitles, if they exist. ->**NOTE:** The script is smart enough to not remove the last audio track. This way you don't have to specify every possible language if you are importing a -foreign film, for example. +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 `-d` option enables debug logging. ### Examples ``` -:eng:und :eng # keep English and Undetermined audio and English subtitles --d :eng "" # Enable debugging, keeping English audio and no subtitles -:eng:kor:jpn :eng:spa # Keep English, Korean, and Japanese audio, and English and - Spanish subtitles +-b 320k # Output 320 kilobits per second MP3 (same as default behavior) +-d -b 160k # Enable debugging, and output 160 kilobits per second MP3 ``` -## Triggers -The only events/notification triggers that have been tested are **On Download** and **On Upgrade** - -![striptracks](.assets/striptracks-v2-custom-script.png "Radarr/Sonarr custom script settings") - -## Logs -A log file is created for the script activity called: - -`/config/logs/striptracks.txt` - -This log can be inspected or downloaded from the Radarr/Sonarr GUI under System->Logs->Files - -Script errors will show up in both the script log and the native Radarr/Sonarr log. - -Log rotation is performed with 5 log files of 512KB each being kept. ->![warning24] **NOTE:** If debug logging is enabled, the log file can grow very large very quickly. *Do not leave debug logging enabled permanently.* - -___ - -## Sonarr/Radarr v3 Builds ->![warning] **Warning: Unstable Releases** ![warning] ->The Sonarr/Radarr v3 Builds are the unstable releases (Aphrodite and Phantom) of Radarr and Sonarr. Though the mod works with all versions of the container, I cannot guarantee these releases are stable. - -Important differences for Sonarr/Radarr v3 Builds -### Mod installation -Substitute the following steps for those noted in the [Installation](./README.md#installation) section above. -1. Pull your selected container ([linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr "LinuxServer.io's Radarr container") or [linuxserver/sonarr](https://hub.docker.com/r/linuxserver/sonarr "LinuxServer.io's Sonarr container")) from Docker Hub: - `docker pull linuxserver/radarr:preview` OR - `docker pull linuxserver/sonarr:preview` - -2. Configure the Docker container with all the port, volume, and environment settings from the *original container documentation* here: - **[linuxserver/radarr](https://hub.docker.com/r/linuxserver/radarr "Radarr Docker container")** - **[linuxserver/sonarr](https://hub.docker.com/r/linuxserver/sonarr "Sonarr Docker container")** - 1. Add the **DOCKER_MODS** environment variable to the `docker create` command, as follows: - `-e DOCKER_MODS=linuxserver/mods:radarr-striptracks` - - *Example Synology Configuration* - ![striptracks](.assets/striptracks-synology.png "Synology container settings") - - 2. Start the container. - -3. After the above configuration is complete, to use mkvmerge, configure a custom script from the Settings->Connect screen and type the following in the **Path** field: - - `/usr/local/bin/striptracks-eng.sh` - - This is a wrapper script that calls striptracks.sh with the following arguments, which keep English audio and subtitles only! - `:eng:und :eng` - - *For any other combinations of audio and subtitles you **must** either use one of the [included wrapper scripts](./README.md#included-wrapper-scripts) or - create a custom script with the codes for the languages you want to keep. See the [Syntax](./README.md#syntax) section above. - Do not put `striptracks.sh` in the **Path** field!* - -### Included Wrapper Scripts ->**NOTE:** The **Arguments** field for Custom Scripts was removed in Radarr and Sonarr v3 due to security concerns. To support options with this version and later, -a wrapper script can be manually created that will call *striptracks.sh* with the required arguments. - -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 `striptracks-eng.sh` mentioned in the [Mod installation](./README.md#mod-installation) section above. +### 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. ``` -striptracks-dut.sh # Keep Dutch audio and subtitles -striptracks-eng.sh # Keep English and Undetermined audio and English subtitles -striptracks-eng-debug.sh # Keep English and Undetermined audio and English subtitles, and enable debug logging -striptracks-eng-jpn.sh # Keep English, Japanese, and Undetermined audio and English subtitles -striptracks-fre.sh # Keep French audio and subtitles -striptracks-fre-debug.sh # Keep French audio and subtitles, and enable debug logging -striptracks-ger.sh # Keep German audio and subtitles -striptracks-spa.sh # Keep Spanish audio and subtitles +flac2mp3-debug.sh # Enable debugging ``` ### Example Wrapper Script @@ -146,31 +59,33 @@ To configure the last entry from the [Examples](./README.md#examples) section ab ``` #!/bin/bash -. /usr/local/bin/striptracks.sh :eng:kor:jpn :eng:spa +. /usr/local/bin/flac2mp3.sh -d -b 160k ``` -Then put `/usr/local/bin/wrapper.sh` in the **Path** field in place of `/usr/local/bin/striptracks-eng.sh` mentioned in the [Mod installation](./README.md#mod-installation) section above. +Then put `/usr/local/bin/wrapper.sh` in the **Path** field in place of `/usr/local/bin/flac2mp3.sh` mentioned in the [Installation](./README.md#installation) section above. -### Preview Triggers -The only events/notification triggers that have been tested are **On Import** and **On Upgrade** +### Triggers +The only events/notification triggers that have been tested are **On Release Import** and **On Upgrade** -![striptracks](.assets/striptracks-v3-custom-script.png "Radarr/Sonarr custom script settings") +![lidarr-flac2mp3](.assets/lidarr-custom-script.png "Lidarr Custom Script dialog") -### Preview Logs -The log can be inspected or downloaded from the Radarr/Sonarr GUI under System->Log Files +### 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 + +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.* ___ - # Credits - This would not be possible without the following: -[Radarr](http://radarr.video/ "Radarr homepage") -[Sonarr](http://sonarr.tv/ "Sonarr homepage") -[LinuxServer.io Radarr](https://hub.docker.com/r/linuxserver/radarr "Radarr Docker container") container -[LinuxServer.io Sonarr](https://hub.docker.com/r/linuxserver/sonarr "Sonarr Docker container") container +[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 -[MKVToolNix](https://mkvtoolnix.download/ "MKVToolNix homepage") by Moritz Bunkus -The AWK script parsing mkvmerge output is adapted from Endoro's post on [VideoHelp](https://forum.videohelp.com/threads/343271-BULK-remove-non-English-tracks-from-MKV-container#post2292889). +[ffmpeg](https://ffmpeg.org/ "FFMpeg homepage") [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" diff --git a/root/etc/cont-init.d/98-flac2mp3 b/root/etc/cont-init.d/98-flac2mp3 new file mode 100644 index 0000000..7943d61 --- /dev/null +++ b/root/etc/cont-init.d/98-flac2mp3 @@ -0,0 +1,46 @@ +#!/usr/bin/with-contenv bash + +cat <>> Flac2MP3 Mod by TheCaptain989 <<< +Repo: https://github.com/linuxserver/docker-mods/tree/lidarr-flac2mp3 + +Version: $(cat /etc/version.tc989) +---------------- +EOF + +# Determine if setup is needed +if [ ! -f /usr/bin/ffmpeg ]; then + echo "Running first time setup." + + if [ -f /usr/bin/apt ]; then + # Ubuntu + echo "Installing ffmpeg using apt-get" + apt-get update && \ + apt-get -y install ffmpeg && \ + rm -rf /var/lib/apt/lists/* + elif [ -f /sbin/apk ]; then + # Alpine + echo "Installing ffmpeg using apk" + apk add --no-cache ffmpeg && \ + rm -rf /var/lib/apt/lists/* + else + # Unknown + echo "Unknown package manager. Attempting to install ffmpeg using apt-get" + apt-get update && \ + apt-get -y install ffmpeg && \ + rm -rf /var/lib/apt/lists/* + fi +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 +fi + +# Make executable +if [ ! -x /usr/local/bin/flac2mp3.sh ]; then + echo "Making scripts executable." + chmod +x /usr/local/bin/flac2mp3*.sh +fi diff --git a/root/etc/cont-init.d/98-striptracks b/root/etc/cont-init.d/98-striptracks deleted file mode 100644 index 8aa9ba1..0000000 --- a/root/etc/cont-init.d/98-striptracks +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/with-contenv bash - -cat <>> Striptracks Mod by TheCaptain989 <<< -Repo: https://github.com/linuxserver/docker-mods/tree/radarr-striptracks - -Version: $(cat /etc/version.tc989) ----------------- -EOF - -# Determine if setup is needed -if [ ! -f /usr/bin/mkvmerge ]; then - echo "Running first time setup." - - if [ -f /usr/bin/apt ]; then - # Ubuntu - echo "Installing MKVToolNix using apt-get" - apt-get update && \ - apt-get -y install mkvtoolnix && \ - rm -rf /var/lib/apt/lists/* - elif [ -f /sbin/apk ]; then - # Alpine - echo "Installing MKVToolNix using apk" - apk add --no-cache mkvtoolnix && \ - rm -rf /var/lib/apt/lists/* - else - # Unknown - echo "Unknown package manager. Attempting to install MKVToolNix using apt-get" - apt-get update && \ - apt-get -y install mkvtoolnix && \ - rm -rf /var/lib/apt/lists/* - fi -fi - -# Change ownership -if [ $(stat -c '%G' /usr/local/bin/striptracks.sh) != "abc" ]; then - echo "Changing ownership on scripts." - chown abc:abc /usr/local/bin/striptracks*.sh -fi - -# Make executable -if [ ! -x /usr/local/bin/striptracks.sh ]; then - echo "Making scripts executable." - chmod +x /usr/local/bin/striptracks*.sh -fi - diff --git a/root/usr/local/bin/flac2mp3-debug.sh b/root/usr/local/bin/flac2mp3-debug.sh new file mode 100644 index 0000000..bb698ee --- /dev/null +++ b/root/usr/local/bin/flac2mp3-debug.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +. /usr/local/bin/flac2mp3.sh -d diff --git a/root/usr/local/bin/flac2mp3.sh b/root/usr/local/bin/flac2mp3.sh new file mode 100644 index 0000000..02b5891 --- /dev/null +++ b/root/usr/local/bin/flac2mp3.sh @@ -0,0 +1,256 @@ +#!/bin/bash + +# Script to convert FLAC files to MP3 using FFMpeg +# https://github.com/linuxserver/docker-mods/tree/lidarr-flac2mp3 +# Can also process MP3s and tag them appropriately +# Resultant MP3s are fully tagged + +# Dependencies: +# ffmpeg +# awk +# stat +# nice + +# Exit codes: +# 0 - success; or test +# 1 - no tracks files specified on command line +# 2 - mkvmerge not found +# 10 - awk script generated an error + +### Variables +export flac2mp3_script=$(basename "$0") +export flac2mp3_pid=$$ +export flac2mp3_config=/config/config.xml +export flac2mp3_log=/config/logs/flac2mp3.txt +export flac2mp3_maxlogsize=1024000 +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 { + usage=" +$flac2mp3_script +Audio conversion script designed for use with Bazarr + +Source: https://github.com/TheCaptain989/lidarr-flac2mp3 + +Usage: + $0 [-d] [-b ] + +Arguments: + bitrate # output quality in bits per second (SI units) + +Options: + -d # enable debug logging + -b # set bitrate; default 320K + +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 +" + >&2 echo "$usage" +} +# Can still go over flac2mp3_maxlog if read line is too long +# Must include whole function in subshell for read to work! +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 ] + then + 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" + touch "$flac2mp3_log" + fi + done +)} +# Inspired by https://stackoverflow.com/questions/893585/how-to-parse-xml-in-bash +function read_xml { + local IFS=\> + read -d \< ENTITY 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 + else + local RET=1 + fi + return $RET +} +# 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 + break + else + if [ "$(echo $RESULT | jq -crM .status)" = "failed" ]; then + local RET=2 + break + else + local RET=1 + sleep 1 + fi + fi + done + return $RET +} +# Process options +while getopts ":db:" opt; do + case ${opt} in + d ) # For debug purposes only + MSG="Debug|Enabling debug logging." + echo "$MSG" | log + >&2 echo "$MSG" + flac2mp3_debug=1 + printenv | sort | sed 's/^/Debug|/' | log + ;; + b ) # Set bitrate + flac2mp3_bitrate="$OPTARG" + ;; + : ) + MSG="Error|Invalid option: -$OPTARG requires an argument" + echo "$MSG" | log + >&2 echo "$MSG" + ;; + esac +done +shift $((OPTIND -1)) + +# Set default bitrate +[ -z "$flac2mp3_bitrate" ] && flac2mp3_bitrate="320k" + +if [[ "$lidarr_eventtype" = "Test" ]]; then + echo "Info|Lidarr event: $lidarr_eventtype" | log + echo "Info|Script was test executed successfully." | log + exit 0 +fi + +if [ -z "$flac2mp3_tracks" ]; then + MSG="Error|No track file(s) specified! Not called from Lidarr?" + echo "$MSG" | log + >&2 echo "$MSG" + usage + exit 1 +fi + +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 +#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 ' +BEGIN { + FFMpeg="/usr/bin/ffmpeg" + FS="|" + RS="|" + IGNORECASE=1 +} +/\.flac/ { + 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") + if (Result) { + print "Error|"Result" converting \""Track"\"" + } else { + if (Recycle=="") { + if (Debug) print "Debug|Deleting: \""Track"\"" + system("[ -s \""NewTrack"\" ] && [ -f \""Track"\" ] && rm \""Track"\"") + } else { + 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"\"") + } + } +} +' | log + +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" + 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 + + # 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" + fi + else + # Error from API + MSG="Error|The 'RefreshArtist' API with artist $lidarr_artist_id failed." + echo "$MSG" | log + >&2 echo "$MSG" + fi + else + MSG="Warn|Unable to locate Lidarr config file: '$flac2mp3_config'" + echo "$MSG" | log + >&2 echo "$MSG" + fi +else + MSG="Warn|Missing environment variable lidarr_artist_id" + echo "$MSG" | log + >&2 echo "$MSG" +fi + +# Cool bash feature +MSG="Info|Completed in $(($SECONDS/60))m $(($SECONDS%60))s" +echo "$MSG" | log diff --git a/root/usr/local/bin/striptracks-dut.sh b/root/usr/local/bin/striptracks-dut.sh deleted file mode 100644 index e2c19af..0000000 --- a/root/usr/local/bin/striptracks-dut.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/striptracks.sh :dut :dut diff --git a/root/usr/local/bin/striptracks-eng-debug.sh b/root/usr/local/bin/striptracks-eng-debug.sh deleted file mode 100644 index 87ed2bb..0000000 --- a/root/usr/local/bin/striptracks-eng-debug.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/striptracks.sh -d :eng:und :eng diff --git a/root/usr/local/bin/striptracks-eng-jpn.sh b/root/usr/local/bin/striptracks-eng-jpn.sh deleted file mode 100644 index ea37f5d..0000000 --- a/root/usr/local/bin/striptracks-eng-jpn.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/striptracks.sh :eng:jpn:und :eng diff --git a/root/usr/local/bin/striptracks-eng.sh b/root/usr/local/bin/striptracks-eng.sh deleted file mode 100644 index a0eb344..0000000 --- a/root/usr/local/bin/striptracks-eng.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/striptracks.sh :eng:und :eng diff --git a/root/usr/local/bin/striptracks-fre-debug.sh b/root/usr/local/bin/striptracks-fre-debug.sh deleted file mode 100644 index 918a198..0000000 --- a/root/usr/local/bin/striptracks-fre-debug.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/striptracks.sh -d :fre:fra :fre:fra diff --git a/root/usr/local/bin/striptracks-fre.sh b/root/usr/local/bin/striptracks-fre.sh deleted file mode 100644 index 998ce43..0000000 --- a/root/usr/local/bin/striptracks-fre.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/striptracks.sh :fre:fra :fre:fra diff --git a/root/usr/local/bin/striptracks-ger.sh b/root/usr/local/bin/striptracks-ger.sh deleted file mode 100644 index 62047ab..0000000 --- a/root/usr/local/bin/striptracks-ger.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/striptracks.sh :ger:deu :ger:deu diff --git a/root/usr/local/bin/striptracks-spa.sh b/root/usr/local/bin/striptracks-spa.sh deleted file mode 100644 index 92f6c4e..0000000 --- a/root/usr/local/bin/striptracks-spa.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -. /usr/local/bin/striptracks.sh :spa :spa diff --git a/root/usr/local/bin/striptracks.sh b/root/usr/local/bin/striptracks.sh deleted file mode 100644 index 9d9034b..0000000 --- a/root/usr/local/bin/striptracks.sh +++ /dev/null @@ -1,489 +0,0 @@ -#!/bin/bash - -# Video remuxing script designed for use with Radarr and Sonarr -# Automatically strips out unwanted audio and subtitle streams, keeping only the desired languages. -# https://github.com/linuxserver/docker-mods/tree/radarr-striptracks - -# Adapted and corrected from Endoro's post 1/5/2014: -# https://forum.videohelp.com/threads/343271-BULK-remove-non-English-tracks-from-MKV-container#post2292889 -# -# Put a colon `:` in front of every language code. Expects ISO639-2 codes - -# Dependencies: -# mkvmerge -# awk -# curl -# jq -# numfmt -# stat -# nice - -# Exit codes: -# 0 - success; or test -# 1 - no video file specified on command line -# 2 - no audio language specified on command line -# 3 - no subtitle language specified on command line -# 4 - mkvmerge not found -# 5 - specified video file not found -# 6 - unable to rename video to temp video -# 10 - remuxing completed, but no output file found -# 20 - general error - -### Variables -export striptracks_script=$(basename "$0") -export striptracks_pid=$$ -export striptracks_arr_config=/config/config.xml -export striptracks_log=/config/logs/striptracks.txt -export striptracks_maxlogsize=512000 -export striptracks_maxlog=4 -export striptracks_debug=0 -export striptracks_type=$(printenv | sed -n 's/_eventtype *=.*$//p') -if [[ "${striptracks_type,,}" = "radarr" ]]; then - export striptracks_video="$radarr_moviefile_path" - export striptracks_api_endpoint="movie" - export striptracks_json_quality_root=".movieFile" - export striptracks_video_type="movie" - export striptracks_title="$radarr_movie_title ($radarr_movie_year)" -else - if [[ "${striptracks_type,,}" = "sonarr" ]]; then - export striptracks_video="$sonarr_episodefile_path" - export striptracks_api_endpoint="episodefile" - export striptracks_json_quality_root="" - export striptracks_video_type="series" - export striptracks_title="$sonarr_series_title $(numfmt --format "%02f" $sonarr_episodefile_seasonnumber)x$(numfmt --format "%02f" $sonarr_episodefile_episodenumbers) - $sonarr_episodefile_episodetitles" - fi -fi -export striptracks_api="Rescan${striptracks_video_type^}" -export striptracks_json_key="${striptracks_video_type}Id" -export striptracks_api_endpoint_idname="${striptracks_type,,}_${striptracks_api_endpoint}_id" -export striptracks_api_endpoint_id="${!striptracks_api_endpoint_idname}" -export striptracks_video_idname="${striptracks_type,,}_${striptracks_video_type}_id" -export striptracks_video_id="${!striptracks_video_idname}" -export striptracks_eventtype="${striptracks_type,,}_eventtype" -export striptracks_tempvideo="${striptracks_video}.tmp" -export striptracks_newvideo="${striptracks_video%.*}.mkv" -export striptracks_db="/config/${striptracks_type,,}.db" -if [ ! -f "$striptracks_db" ]; then - striptracks_db=/config/nzbdrone.db -fi -export striptracks_recyclebin=$(sqlite3 $striptracks_db 'SELECT Value FROM Config WHERE Key="recyclebin"') -RET=$?; [ "$RET" != 0 ] && >&2 echo "WARNING[$RET]: Unable to read recyclebin information from database \"$striptracks_db\"" - -### Functions -function usage { - usage=" -$striptracks_script -Video remuxing script designed for use with Radarr and Sonarr - -Source: https://github.com/TheCaptain989/radarr-striptracks - -Usage: - $0 [-d] - -Arguments: - audio_languages # ISO639-2 code(s) prefixed with a colon \`:\` - Multiple codes may be concatenated. - subtitle_languages # ISO639-2 code(s) prefixed with a colon \`:\` - Multiple codes may be concatenated. - -Options: - -d # enable debug logging - -Examples: - $striptracks_script :eng:und :eng # keep English and Undetermined audio and - English subtitles - $striptracks_script :eng \"\" # keep English audio and no subtitles - $striptracks_script -d :eng:kor:jpn :eng:spa # Enable debugging, keeping English, Korean, - and Japanese audio, and English and - Spanish subtitles -" - >&2 echo "$usage" -} -# Can still go over striptracks_maxlog if read line is too long -# Must include whole function in subshell for read to work! -function log {( - while read - do - echo $(date +"%Y-%-m-%-d %H:%M:%S.%1N")\|"[$striptracks_pid]$REPLY" >>"$striptracks_log" - local FILESIZE=$(stat -c %s "$striptracks_log") - if [ $FILESIZE -gt $striptracks_maxlogsize ] - then - for i in $(seq $((striptracks_maxlog-1)) -1 0); do - [ -f "${striptracks_log::-4}.$i.txt" ] && mv "${striptracks_log::-4}."{$i,$((i+1))}".txt" - done - [ -f "${striptracks_log::-4}.txt" ] && mv "${striptracks_log::-4}.txt" "${striptracks_log::-4}.0.txt" - touch "$striptracks_log" - fi - done -)} -# Inspired by https://stackoverflow.com/questions/893585/how-to-parse-xml-in-bash -function read_xml { - local IFS=\> - read -d \< ENTITY CONTENT -} -# Get video information -function get_video_info { - [ $striptracks_debug -eq 1 ] && echo "Debug|Getting video information for $striptracks_api_endpoint '$striptracks_api_endpoint_id'. Calling ${striptracks_type^} API using GET and URL 'http://$striptracks_bindaddress:$striptracks_port$striptracks_urlbase/api/$striptracks_api_endpoint/$striptracks_api_endpoint_id?apikey=(removed)'" | log - RESULT=$(curl -s -H "Content-Type: application/json" \ - -X GET http://$striptracks_bindaddress:$striptracks_port$striptracks_urlbase/api/$striptracks_api_endpoint/$striptracks_api_endpoint_id?apikey=$striptracks_apikey) - [ $striptracks_debug -eq 1 ] && echo "API returned: $RESULT" | awk '{print "Debug|"$0}' | log - if [ "$(echo $RESULT | jq -crM .path)" != "null" ]; then - local RET=0 - else - local RET=1 - fi - return $RET -} -# Initiate API Rescan request -function rescan { - MSG="Info|Calling ${striptracks_type^} API to rescan ${striptracks_video_type}, try #$i" - echo "$MSG" | log - [ $striptracks_debug -eq 1 ] && echo "Debug|Forcing rescan of $striptracks_json_key '$striptracks_video_id', try #$i. Calling ${striptracks_type^} API '$striptracks_api' using POST and URL 'http://$striptracks_bindaddress:$striptracks_port$striptracks_urlbase/api/command?apikey=(removed)'" | log - RESULT=$(curl -s -d "{name: '$striptracks_api', $striptracks_json_key: $striptracks_video_id}" -H "Content-Type: application/json" \ - -X POST http://$striptracks_bindaddress:$striptracks_port$striptracks_urlbase/api/command?apikey=$striptracks_apikey) - [ $striptracks_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 - else - local RET=1 - fi - return $RET -} -# Check result of rescan job -function check_rescan { - local i=0 - for ((i=1; i <= 15; i++)); do - [ $striptracks_debug -eq 1 ] && echo "Debug|Checking job $JOBID completion, try #$i. Calling ${striptracks_type^} API using GET and URL 'http://$striptracks_bindaddress:$striptracks_port$striptracks_urlbase/api/command/$JOBID?apikey=(removed)'" | log - RESULT=$(curl -s -H "Content-Type: application/json" \ - -X GET http://$striptracks_bindaddress:$striptracks_port$striptracks_urlbase/api/command/$JOBID?apikey=$striptracks_apikey) - [ $striptracks_debug -eq 1 ] && echo "API returned: $RESULT" | awk '{print "Debug|"$0}' | log - if [ "$(echo $RESULT | jq -crM .status)" = "completed" ]; then - local RET=0 - break - else - if [ "$(echo $RESULT | jq -crM .status)" = "failed" ]; then - local RET=2 - break - else - local RET=1 - sleep 1 - fi - fi - done - return $RET -} - -# Process options -while getopts ":d" opt; do - case ${opt} in - d ) # For debug purposes only - MSG="Debug|Enabling debug logging." - echo "$MSG" | log - >&2 echo "$MSG" - striptracks_debug=1 - printenv | sort | sed 's/^/Debug|/' | log - ;; - esac -done -shift $((OPTIND -1)) - -if [ -z "$1" ]; then - MSG="Error|No audio languages specified!" - echo "$MSG" | log - >&2 echo "$MSG" - usage - exit 2 -fi - -if [ -z "$2" ]; then - MSG="Error|No subtitles languages specified!" - echo "$MSG" | log - >&2 echo "$MSG" - usage - exit 3 -fi - -if [ ! -f "/usr/bin/mkvmerge" ]; then - MSG="Error|/usr/bin/mkvmerge is required by this script" - echo "$MSG" | log - >&2 echo "$MSG" - exit 4 -fi - -if [[ "${!striptracks_eventtype}" = "Test" ]]; then - echo "Info|${striptracks_type^} event: ${!striptracks_eventtype}" | log - echo "Info|Script was test executed successfully." | log - exit 0 -fi - -if [ -z "$striptracks_video" ]; then - MSG="Error|No video file specified! Not called from Radarr/Sonarr?" - echo "$MSG" | log - >&2 echo "$MSG" - usage - exit 1 -fi - -if [ ! -f "$striptracks_video" ]; then - MSG="Error|Input file not found: \"$striptracks_video\"" - echo "$MSG" | log - >&2 echo "$MSG" - exit 5 -fi - -#### BEGIN MAIN -FILESIZE=$(numfmt --to iec --format "%.3f" $(stat -c %s "$striptracks_video")) -MSG="Info|${striptracks_type^} event: ${!striptracks_eventtype}, Video: $striptracks_video, Size: $FILESIZE, AudioKeep: $1, SubsKeep: $2" -echo "$MSG" | log - -# Rename the original video file to a temporary name -[ $striptracks_debug -eq 1 ] && echo "Debug|Renaming: \"$striptracks_video\" to \"$striptracks_tempvideo\"" | log -mv -f "$striptracks_video" "$striptracks_tempvideo" | log -RET=$?; [ "$RET" != 0 ] && { - MSG="ERROR[$RET]: Unable to rename video: \"$striptracks_video\" to temp video: \"$striptracks_tempvideo\". Halting." - echo "$MSG" | log - >&2 echo "$MSG" - exit 6 -} - -# Read in the output of mkvmerge info extraction -[ $striptracks_debug -eq 1 ] && echo "Debug|Executing: /usr/bin/mkvmerge -J \"$striptracks_tempvideo\"" | log -JSON=$(/usr/bin/mkvmerge -J "$striptracks_tempvideo") -RET=$?; [ "$RET" != 0 ] && { - MSG="ERROR[$RET]: Error executing mkvmerge." - echo "$MSG" | log - >&2 echo "$MSG" -} - -# This and the modified AWK script are a hack, and I know it. JQ is crazy hard to learn, BTW. -# Mimic the mkvmerge --identify-verbose option that has been deprecated -JSON_PROCESSED=$(echo $JSON | jq -jcrM ' -( if (.chapters | .[] | .num_entries) then - "Chapters: \(.chapters | .[] | .num_entries) entries\n" - else - "" - end -), -( .tracks | - .[] | - ( "Track ID \(.id): \(.type) (\(.codec)) [", - ( [.properties | to_entries |.[] | "\(.key):\(.value | tostring | gsub(" "; "\\s"))"] | join(" ")), - "]\n" ) -) -') -[ $striptracks_debug -eq 1 ] && echo "$JSON_PROCESSED" | awk '{print "Debug|"$0}' | log - -echo "$JSON_PROCESSED" | awk -v Debug=$striptracks_debug \ --v OrgVideo="$striptracks_video" \ --v TempVideo="$striptracks_tempvideo" \ --v MKVVideo="$striptracks_newvideo" \ --v Title="$striptracks_title" \ --v AudioKeep="$1" \ --v SubsKeep="$2" ' -BEGIN { - MKVMerge="/usr/bin/mkvmerge" - FS="[\t\n: ]" - IGNORECASE=1 -} -/^Track ID/ { - FieldCount=split($0, Fields) - if (Fields[1]=="Track") { - NoTr++ - Track[NoTr, "id"]=Fields[3] - Track[NoTr, "typ"]=Fields[5] - if (Fields[6]~/^\(/) { - Track[NoTr, "code"]=substr(Line,1,match(Line,/\)/)) - sub(/^[^\(]+/,"",Track[NoTr, "code"]) - } - if (Track[NoTr, "typ"]=="video") VidCnt++ - if (Track[NoTr, "typ"]=="audio") AudCnt++ - if (Track[NoTr, "typ"]=="subtitles") SubsCnt++ - for (i=6; i<=FieldCount; i++) { - if (Fields[i]=="language") Track[NoTr, "lang"]=Fields[++i] - } - } -} -/^Chapters/ { - Chapters=$3 -} -END { - if (!NoTr) { print "Error|No tracks found in \""TempVideo"\"" > "/dev/stderr"; exit } - if (!AudCnt) AudCnt=0; if (!SubsCnt) SubsCnt=0 - print "Info|Original tracks: "NoTr" (audio: "AudCnt", subtitles: "SubsCnt")" - if (Chapters) print "Info|Chapters: "Chapters - for (i=1; i<=NoTr; i++) { - if (Debug) print "Debug|i:"i,"Track ID:"Track[i,"id"],"Type:"Track[i,"typ"],"Lang:"Track[i, "lang"],"Code:"Track[i, "code"] - if (Track[i, "typ"]=="audio") { - if (AudioKeep~Track[i, "lang"]) { - AudKpCnt++ - print "Info|Keeping audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "code"] - if (AudioCommand=="") { - AudioCommand=Track[i, "id"] - } else { - AudioCommand=AudioCommand","Track[i, "id"] - } - # Special case if there is only one audio track, even if it was not specified - } else if (AudCnt==1) { - AudKpCnt++ - print "Info|Keeping only audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "code"] - AudioCommand=Track[i, "id"] - # Special case if there were multiple tracks, none were selected, and this is the last one. - } else if (AudioCommand=="" && Track[i, "id"]==AudCnt) { - AudKpCnt++ - print "Info|Keeping last audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "code"] - AudioCommand=Track[i, "id"] - } else { - if (Debug) print "Debug|\tRemove:", Track[i, "typ"], "track", Track[i, "id"], Track[i, "lang"] - } - } else { - if (Track[i, "typ"]=="subtitles") { - if (SubsKeep~Track[i, "lang"]) { - SubsKpCnt++ - print "Info|Keeping subtitle track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "code"] - if (SubsCommand=="") { - SubsCommand=Track[i, "id"] - } else { - SubsCommand=SubsCommand","Track[i, "id"] - } - } else { - if (Debug) print "Debug|\tRemove:", Track[i, "typ"], "track", Track[i, "id"], Track[i, "lang"] - } - } - } - } - if (!AudKpCnt) AudKpCnt=0; if (!SubsKpCnt) SubsKpCnt=0 - print "Info|Kept tracks: "AudKpCnt+SubsKpCnt+VidCnt" (audio: "AudKpCnt", subtitles: "SubsKpCnt")" - if (AudioCommand=="") { - # This should never happen, but belt and suspenders - CommandLine="-A" - } else { - CommandLine="-a "AudioCommand - } - if (SubsCommand=="") { - CommandLine=CommandLine" -S" - } else { - CommandLine=CommandLine" -s "SubsCommand - } - if (Debug) print "Debug|Executing: nice "MKVMerge" --title \""Title"\" -q -o \""MKVVideo"\" "CommandLine" \""TempVideo"\"" - Result=system("nice "MKVMerge" --title \""Title"\" -q -o \""MKVVideo"\" "CommandLine" \""TempVideo"\"") - if (Result>1) print "Error|"Result" remuxing \""TempVideo"\"" > "/dev/stderr" -}' | log - -#### END MAIN - -# Check for script completion and non-empty file -if [ -s "$striptracks_newvideo" ]; then - # Use Recycle Bin if configured - if [ "$striptracks_recyclebin" ]; then - [ $striptracks_debug -eq 1 ] && echo "Debug|Moving: \"$striptracks_tempvideo\" to \"${striptracks_recyclebin%/}/$(basename "$striptracks_video")"\" | log - mv "$striptracks_tempvideo" "${striptracks_recyclebin%/}/$(basename "$striptracks_video")" | log - else - [ $striptracks_debug -eq 1 ] && echo "Debug|Deleting: \"$striptracks_tempvideo\"" | log - rm "$striptracks_tempvideo" | log - fi -else - MSG="Error|Unable to locate or invalid remuxed file: \"$striptracks_newvideo\". Undoing rename." - echo "$MSG" | log - >&2 echo "$MSG" - [ $striptracks_debug -eq 1 ] && echo "Debug|Renaming: \"$striptracks_tempvideo\" to \"$striptracks_video\"" | log - mv -f "$striptracks_tempvideo" "$striptracks_video" | log - exit 10 -fi - -FILESIZE=$(numfmt --to iec --format "%.3f" $(stat -c %s "$striptracks_newvideo")) -MSG="Info|New size: $FILESIZE" -echo "$MSG" | log - -# Call *arr API to RescanMovie/RescanSeries -if [ -f "$striptracks_arr_config" ]; then - # Read *arr config.xml - while read_xml; do - [[ $ENTITY = "Port" ]] && striptracks_port=$CONTENT - [[ $ENTITY = "UrlBase" ]] && striptracks_urlbase=$CONTENT - [[ $ENTITY = "BindAddress" ]] && striptracks_bindaddress=$CONTENT - [[ $ENTITY = "ApiKey" ]] && striptracks_apikey=$CONTENT - done < $striptracks_arr_config - - [[ $striptracks_bindaddress = "*" ]] && striptracks_bindaddress=localhost - - # Check for video ID - if [ "$striptracks_video_id" ]; then - # Call API - if [ "${striptracks_type,,}" = "radarr" ] && get_video_info; then - # Save original quality - ORGQUALITY=$(echo $RESULT | jq -crM ${striptracks_json_quality_root}.quality) - fi - # Loop a maximum of twice - for ((i=1; $i <= 2; i++)); do - # Scan the disk for the new movie file - if rescan; then - # Check that the Rescan completed - if check_rescan; then - # This whole section doesn't work under Sonarr because the episodefile_id changes after the RescanSeries if the filename changes - # Should look into just using a PUT to change everything at once instead of a Rescan. - if [ "${striptracks_type,,}" = "radarr" ]; then - if get_video_info; then - # Check that the file didn't get lost in the Rescan. - # Radarr sometimes needs to Rescan twice when the file extension changes - # (.avi -> .mkv for example) - if [ "$(echo $RESULT | jq -crM .hasFile)" = "true" ]; then - # If we lost the quality information, put it back - # NOTE: This "works" with Radarr in that the change shows up in the GUI, but only until the page changes. - # It doesn't seem to write the info permanently. Maybe an API bug? - if [ "$(echo $RESULT | jq -crM ${striptracks_json_quality_root}.quality.quality.name)" = "Unknown" ]; then - [ $striptracks_debug -eq 1 ] && echo "Debug|Updating quality to '$(echo $ORGQUALITY | jq -crM .quality.name)'. Calling ${striptracks_type^} API using PUT and URL 'http://$striptracks_bindaddress:$striptracks_port$striptracks_urlbase/api/$striptracks_api_endpoint/$striptracks_video_id?apikey=(removed)'" | log - RESULT=$(curl -s -d "$(echo $RESULT | jq -crM "${striptracks_json_quality_root}.quality=$ORGQUALITY")" -H "Content-Type: application/json" \ - -X PUT http://$striptracks_bindaddress:$striptracks_port$striptracks_urlbase/api/$striptracks_api_endpoint/$striptracks_video_id?apikey=$striptracks_apikey) - [ $striptracks_debug -eq 1 ] && echo "API returned: $RESULT" | awk '{print "Debug|"$0}' | log - if [ "$(echo $RESULT | jq -crM ${striptracks_json_quality_root}.quality.quality.name)" = "Unknown" ]; then - MSG="Warn|Unable to update ${striptracks_type^} $striptracks_api_endpoint '$striptracks_title' to quality '$(echo $ORGQUALITY | jq -crM .quality.name)'" - echo "$MSG" | log - >&2 echo "$MSG" - fi - fi - # The video record is [now] good - break - else - # Loop again because there was no file - continue - fi - else - # No 'path' in returned JSON. - MSG="Warn|The '$striptracks_api' API with $striptracks_api_endpoint $striptracks_api_endpoint_id returned no path." - echo "$MSG" | log - >&2 echo "$MSG" - fi - else - # Didn't do anything because we're in Sonarr - break - fi - else - # Timeout or failure - MSG="Warn|${striptracks_type^} job ID $JOBID timed out or failed." - echo "$MSG" | log - >&2 echo "$MSG" - fi - else - # Error from API - MSG="Error|The '$striptracks_api' API with $striptracks_json_key $striptracks_video_id failed." - echo "$MSG" | log - >&2 echo "$MSG" - fi - done - else - # No video ID means we can't call the API - MSG="Warn|Missing environment variable: $striptracks_video_idname" - echo "$MSG" | log - >&2 echo "$MSG" - fi -else - # No config file means we can't call the API - MSG="Warn|Unable to locate ${striptracks_type^} config file: '$striptracks_arr_config'" - echo "$MSG" | log - >&2 echo "$MSG" -fi - -# Cool bash feature -MSG="Info|Completed in $(($SECONDS/60))m $(($SECONDS%60))s" -echo "$MSG" | log