Merge pull request #72 from TheCaptain989/radarr-striptracks

Radarr: striptracks initial release
This commit is contained in:
aptalca 2020-10-13 21:15:47 -04:00 committed by GitHub
commit a3f538e613
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 761 additions and 71 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -4,7 +4,7 @@ language: shell
branches:
only:
- <baseimagename>-<modname> #replace variables, omit brackets
- radarr-striptracks #replace variables, omit brackets
services:
- docker
@ -12,21 +12,29 @@ services:
env:
global:
- DOCKERHUB="linuxserver/mods" #don't modify
- BASEIMAGE="baseimagename" #replace
- MODNAME="modname" #replace
- BASEIMAGE="radarr" #replace
- MODNAME="striptracks" #replace
jobs:
include:
- stage: PR-BuildImage
if: (type IN (pull_request))
script:
# Build variables
- VERSION=$(git describe --tags --always)
# Build image
- docker build --no-cache -t ${DOCKERHUB}:${BASEIMAGE}-${MODNAME}-${TRAVIS_COMMIT} .
- docker build --no-cache
--build-arg VERSION=${VERSION}
-t ${DOCKERHUB}:${BASEIMAGE}-${MODNAME}-${TRAVIS_COMMIT} .
- stage: BuildImage
if: (NOT (type IN (pull_request)))
script:
# Build variables
- VERSION=$(git describe --tags --always)
# Build image
- docker build --no-cache -t ${DOCKERHUB}:${BASEIMAGE}-${MODNAME}-${TRAVIS_COMMIT} .
- docker build --no-cache
--build-arg VERSION=${VERSION}
-t ${DOCKERHUB}:${BASEIMAGE}-${MODNAME}-${TRAVIS_COMMIT} .
- docker tag ${DOCKERHUB}:${BASEIMAGE}-${MODNAME}-${TRAVIS_COMMIT} ${DOCKERHUB}:${BASEIMAGE}-${MODNAME}
# Login to DockerHub
- echo $DOCKERPASS | docker login -u $DOCKERUSER --password-stdin

View File

@ -1,6 +1,20 @@
## Buildstage ##
FROM lsiobase/ubuntu:xenial as buildstage
# Build arguments
ARG VERSION
# Add version number for use in container init script
RUN mkdir -p /root-layer/etc && \
echo "$VERSION" > /root-layer/etc/version.tc989
# Stage local files
COPY root/ /root-layer/
## Single layer deployed image ##
FROM scratch
LABEL maintainer="username"
LABEL maintainer="TheCaptain989"
# copy local files
COPY root/ /
# Copy files from buildstage
COPY --from=buildstage /root-layer/ /

View File

@ -1,21 +0,0 @@
## Buildstage ##
FROM lsiobase/alpine:3.9 as buildstage
RUN \
echo "**** install packages ****" && \
apk add --no-cache \
curl && \
echo "**** grab rclone ****" && \
mkdir -p /root-layer && \
curl -o \
/root-layer/rclone.deb -L \
"https://downloads.rclone.org/v1.47.0/rclone-v1.47.0-linux-amd64.deb"
# copy local files
COPY root/ /root-layer/
## Single layer deployed image ##
FROM scratch
# Add files from buildstage
COPY --from=buildstage /root-layer/ /

183
README.md
View File

@ -1,17 +1,176 @@
# Rsync - Docker mod for openssh-server
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`).
This mod adds rsync to openssh-server, to be installed/updated during container start.
**One unified script works in both Radarr and Sonarr. Use this mod in either container!**
>**NOTE:** This mod support Linux OSes only.
In openssh-server docker arguments, set an environment variable `DOCKER_MODS=linuxserver/mods:openssh-server-rsync`
Container info:
![Docker Image Size (latest by date)](https://img.shields.io/docker/image-size/linuxserver/mods/radarr-striptracks)
If adding multiple mods, enter them in an array separated by `|`, such as `DOCKER_MODS=linuxserver/mods:openssh-server-rsync|linuxserver/mods:openssh-server-mod2`
# Installation
>**NOTE:** See the [Sonarr/Radarr v3 Builds](./README.md#sonarrradarr-v3-builds) section below for important differences to these instructions for v3 builds.
# Mod creation instructions
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`
* Fork the repo, create a new branch based on the branch `template`.
* Edit the `Dockerfile` for the mod. `Dockerfile.complex` is only an example and included for reference; it should be deleted when done.
* Inspect the `root` folder contents. Edit, add and remove as necessary.
* Edit this readme with pertinent info, delete these instructions.
* Finally edit the `travis.yml`. Customize the build branch, and the vars for `BASEIMAGE` and `MODNAME`.
* Ask the team to create a new branch named `<baseimagename>-<modname>`. Baseimage should be the name of the image the mod will be applied to. The new branch will be based on the `template` branch.
* Submit PR against the branch created by the team.
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 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):
<ins>Suggested Example</ins>
**`:eng:und :eng`**
## Usage
>**NOTE:** See the [Sonarr/Radarr v3 Builds](./README.md#sonarrradarr-v3-builds) section below for important differences to these instructions for v3 builds.
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.
### Syntax
The script accepts two arguments and one option in the **Arguments** field:
`[-d] <audio_languages> <subtitle_languages>`
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:
* :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 `-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
```
## 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.
<ins>Important differences for Sonarr/Radarr v3 Builds</ins>
### 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`
<ins>This is a wrapper script that calls striptracks.sh with the following arguments, which keep English audio and subtitles only!</ins>
`: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.
```
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
```
### Example Wrapper Script
To configure the last entry from the [Examples](./README.md#examples) section above, create and save a file called `wrapper.sh` to `/usr/local/bin` containing the following text:
```
#!/bin/bash
. /usr/local/bin/striptracks.sh :eng:kor:jpn :eng:spa
```
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.
### Preview Triggers
The only events/notification triggers that have been tested are **On Import** and **On Upgrade**
![striptracks](.assets/striptracks-v3-custom-script.png "Radarr/Sonarr custom script settings")
### Preview Logs
The log can be inspected or downloaded from the Radarr/Sonarr GUI under System->Log Files
___
# 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
[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).
[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"

View File

@ -0,0 +1,47 @@
#!/usr/bin/with-contenv bash
cat <<EOF
----------------
>>> 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

View File

@ -1,27 +0,0 @@
#!/usr/bin/with-contenv bash
# Determine if setup is needed
if [ ! -f /usr/local/lib/python***/dist-packages/sshuttle ] && \
[ -f /usr/bin/apt ]; then
## Ubuntu
apt-get update
apt-get install --no-install-recommends -y \
iptables \
openssh-client \
python3 \
python3-pip
pip3 install sshuttle
fi
if [ ! -f /usr/lib/python***/site-packages/sshuttle ] && \
[ -f /sbin/apk ]; then
# Alpine
apk add --no-cache \
iptables \
openssh \
py3-pip \
python3
pip3 install sshuttle
fi
chown -R root:root /root
chmod -R 600 /root/.ssh

View File

@ -1,3 +0,0 @@
#!/usr/bin/with-contenv bash
sshuttle --dns --remote root@${HOST}:${PORT} 0/0 -x 172.17.0.0/16

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh :dut :dut

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh -d :eng:und :eng

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh :eng:jpn:und :eng

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh :eng:und :eng

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh -d :fre:fra :fre:fra

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh :fre:fra :fre:fra

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh :ger:deu :ger:deu

View File

@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh :spa :spa

View File

@ -0,0 +1,489 @@
#!/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] <audio_languages> <subtitle_languages>
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