Release 2.3 candidate 1

- Added Original language feature
- Added :org special purpose language code (Resolves #392)
- Added example scripts to use :org code
- Cleaned up awk code
- Modified removed track logging to be a single line
- Removed tracks now are logged as Informational instead of Debug
- Moved position argument check earlier
- Updated README
- Changed some log messages to make them more concise
- Added version option
- Reverted to single-stage build
- Insert version into scripts during build
- Updates Radarr/Sonarr version check to use v3 API. This makes the script fully compatible with Radarr v4.
- Added debug info for system API
- Added debug info for config API
- Preparation for S6 V3
This commit is contained in:
TheCaptain989
2022-08-30 14:23:52 -05:00
parent d9abfefe2e
commit 1bcd422bc2
8 changed files with 204 additions and 154 deletions
+6 -2
View File
@@ -20,9 +20,13 @@ jobs:
cat <<EOF cat <<EOF
Building version $VERSION Building version $VERSION
EOF EOF
# Insert version into scripts
sed -i -e "s/{{VERSION}}/$VERSION/" \
$GITHUB_WORKSPACE/root/usr/local/bin/striptracks.sh \
$GITHUB_WORKSPACE/root/etc/cont-init.d/98-striptracks \
$GITHUB_WORKSPACE/root/etc/s6-overlay/s6-rc.d/init-mod-radarr-striptracks-add-package/run
# Build image # Build image
docker build --build-arg VERSION=${VERSION} \ docker build --no-cache \
--no-cache \
--tag ${{ github.sha }} . --tag ${{ github.sha }} .
- name: Tag image - name: Tag image
+2 -15
View File
@@ -1,20 +1,7 @@
## Buildstage ##
FROM ghcr.io/linuxserver/baseimage-alpine:3.15 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 ## ## Single layer deployed image ##
FROM scratch FROM scratch
LABEL maintainer="TheCaptain989" LABEL maintainer="TheCaptain989"
# Copy files from buildstage # Copy local files
COPY --from=buildstage /root-layer/ / COPY root/ /
+37 -16
View File
@@ -68,19 +68,24 @@ Beginning with version 2.0 of this mod, the script may be called with no argumen
#### Automatic Language Detection #### Automatic Language Detection
Both audio and subtitles that match the selected language(s) are kept. Both audio and subtitles that match the selected language(s) are kept.
>**Note:** The Radarr language selection 'Any' will preserve all languages in the video file.
>**Note:** The Radarr language selection 'Original' will use the language Radarr pulled from [The Movie Database](https://www.themoviedb.org/ "TMDB") during its last refresh. Selecting this profile language is functionally equivalent to calling the script with `--audio :org --subs :org` command line options. See [Original language code](./README.md#original-language-code) below for more details.
>**Note:** The Sonarr language selection 'Unknown' will match tracks with no configured language in the video file. Selecting this profile language is functionally equivalent to calling the script with `--audio :und --subs :und` command line options. See [Unknown language code](./README.md#unknown-language-code) below for more details.
*Radarr Quality Profile Example* *Radarr Quality Profile Example*
![radarr profile](.assets/radarr-quality-profile.png "Radarr Quality Profile settings") ![radarr profile](.assets/radarr-quality-profile.png "Radarr Quality Profile settings")
*Sonarr Language Profile Example* *Sonarr Language Profile Example*
![sonarr profile](.assets/sonarr-language-profile.png "Sonarr Language Profile settings") ![sonarr profile](.assets/sonarr-language-profile.png "Sonarr Language Profile settings")
>**Note:** The intent of the Radarr language selection 'Original' is not well documented. For the purposes of this script, it has the same function as 'Any' and will preserve all languages in the video file.
#### Command Line Options and Arguments #### Command Line Options and Arguments
The script also supports command line arguments that will override the automatic language detection. More granular control can therefore be exerted or extended using tagging and defining multiple Connect scripts (this is native Radarr/Sonarr functionality outside the scope of this documentation). The script also supports command line arguments that will override the automatic language detection. More granular control can therefore be exerted or extended using tagging and defining multiple Connect scripts (this is native Radarr/Sonarr functionality outside the scope of this documentation).
The syntax for the command line is: The syntax for the command line is:
`striptracks.sh [OPTIONS] [<audio_languages> [<subtitle_languages>]]` OR `striptracks.sh [OPTIONS] [<audio_languages> [<subtitle_languages>]]`
OR
`striptracks.sh [OPTIONS] {-f|--file} <video_file> {-a|--audio} <audio_languages> {-s|--subs} <subtitle_languages>` `striptracks.sh [OPTIONS] {-f|--file} <video_file> {-a|--audio} <audio_languages> {-s|--subs} <subtitle_languages>`
Where: Where:
@@ -102,23 +107,35 @@ For example:
...etc. ...etc.
Multiple codes may be concatenated, such as `:eng:spa` for both English and Spanish. Multiple codes may be concatenated, such as `:eng:spa` for both English and Spanish. Order is unimportant.
>**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 >**NOTE:** The script is smart enough to not remove the last audio track. (There is in fact no way to force the script to remove all audio.) This way you don't have to specify every possible language if you are importing a
foreign film, for example. foreign film, for example.
#### Original language code
The `:org` language code is a special code. When used, instead of retaining a specific language, the script substitutes the original movie language as specified in its [The Movie Database](https://www.themoviedb.org/ "TMDB") entry.
As an example, when importing "_Amores Perros (2000)_" with options `--audio :org:eng`, the Spanish and English audio tracks are preserved.
Several [Included Wrapper Scripts](./README.md#included-wrapper-scripts) use this special code.
>**NOTE:** This feature relies on the 'originalLanguage' field in the Radarr database. It is not known to exist in Sonarr, and the `:org` code will therefore be ignored.
#### Unknown language code
The `:und` language code is a special code. When used, the script will match on any track that has a blank language entry. If not included, tracks with a blank language value will be removed.
>![danger] **NOTE:** It is common for M2TS and AVI containers to have tracks with unknown languages! It is strongly recommended to include `:und` in most instances unless you know exactly what you're doing.
### Examples ### Examples
``` ```
-d 2 # Enable debugging level 2, audio and subtitles -d 2 # Enable debugging level 2, audio and subtitles
# languages detected from Radarr/Sonarr # languages detected from Radarr/Sonarr
-a :eng:und -s :eng # Keep English and Unknown audio and English subtitles -a :eng:und -s :eng # Keep English and Unknown audio, and English subtitles
-a :org:eng -s :eng # Keep English and Original audio, and English subtitles
:eng "" # Keep English audio and no subtitles :eng "" # Keep English audio and no subtitles
-d :eng:kor:jpn :eng:spa # Enable debugging level 1, keeping English, Korean, and Japanese audio, and English and -d :eng:kor:jpn :eng:spa # Enable debugging level 1, keeping English, Korean, and Japanese audio, and
# Spanish subtitles # English and Spanish subtitles
-f \"/path/to/movies/Finding Nemo (2003).mkv\" -a :eng:und -s :eng -f "/path/to/movies/Finding Nemo (2003).mkv" -a :eng:und -s :eng
# Batch Mode # Batch Mode
# Keep English and Unknown audio and # Keep English and Unknown audio and English subtitles, converting
# English subtitles, converting video specified # video specified
``` ```
### Wrapper Scripts ### Wrapper Scripts
@@ -133,18 +150,21 @@ striptracks-debug.sh # Use detected languages, but enable debug logging
striptracks-debug-2.sh # Use detected languages, enable debug logging level 2 striptracks-debug-2.sh # Use detected languages, enable debug logging level 2
striptracks-debug-max.sh # Use detected languages, enable highest debug logging striptracks-debug-max.sh # Use detected languages, enable highest debug logging
striptracks-dut.sh # Keep Dutch audio and subtitles striptracks-dut.sh # Keep Dutch audio and subtitles
striptracks-eng.sh # Keep English and Unknown audio and English subtitles striptracks-eng.sh # Keep English and Unknown audio, and English subtitles
striptracks-eng-debug.sh # Keep English and Unknown audio and English subtitles, and enable debug logging striptracks-eng-debug.sh # Keep English and Unknown audio, and English subtitles, and enable debug logging
striptracks-eng-fre.sh # Keep English, French, and Unknown audio and English subtitles striptracks-eng-fre.sh # Keep English, French, and Unknown audio and English subtitles
striptracks-eng-jpn.sh # Keep English, Japanese, and Unknown audio and English subtitles striptracks-eng-jpn.sh # Keep English, Japanese, and Unknown audio and English subtitles
striptracks-fre.sh # Keep French audio and subtitles striptracks-fre.sh # Keep French audio and subtitles
striptracks-fre-debug.sh # Keep French audio and subtitles, and enable debug logging striptracks-fre-debug.sh # Keep French audio and subtitles, and enable debug logging
striptracks-ger.sh # Keep German audio and subtitles striptracks-ger.sh # Keep German audio and subtitles
striptracks-spa.sh # Keep Spanish audio and subtitles striptracks-spa.sh # Keep Spanish audio and subtitles
striptracks-org-eng.sh # Keep Original, English, and Unknown audio, and English and Unknown subtitles
striptracks-org-ger.sh # Keep Original and German audio, and Original and German subtitles
striptracks-org-spa.sh # Keep Original and Spanish audio, and Original and Spanish subtitles
``` ```
#### Example Wrapper Script #### Example Wrapper Script
To configure the an entry from the [Examples](./README.md#examples) section above, create and save a file called `striptracks-custom.sh` to `/config` containing the following text: To configure an entry from the [Examples](./README.md#examples) section above, create and save a file called `striptracks-custom.sh` to `/config` containing the following text:
```shell ```shell
#!/bin/bash #!/bin/bash
@@ -169,8 +189,9 @@ Using this function, you can easily process all of your video files in any subdi
#### Script Execution Differences in Batch Mode #### Script Execution Differences in Batch Mode
Because the script is not called from within Radarr or Sonarr, expect the following behavior while in Batch Mode: Because the script is not called from within Radarr or Sonarr, expect the following behavior while in Batch Mode:
* *The file name must be specified on the command line*<br/>(The `-f` flag places the script in Batch Mode) * *The file name must be specified on the command line.*<br/>(The `-f` option places the script in Batch Mode)
* *No audio or subtitles language auto detection occurs.*<br/>Both the audio and subtitles languages must be specified on the command line * *No audio or subtitles language detection occurs.*<br/>Both the audio and subtitles languages must be specified on the command line.
* *The `:org` language code in meaningless.*<br/>The original video langauge cannot be determined without the Radarr database.
* *The resultant MKV embedded title attribute is set to the basename of the file minus the extension.*<br/>The canonical name of the movie/TV show cannot otherwise be determined. * *The resultant MKV embedded title attribute is set to the basename of the file minus the extension.*<br/>The canonical name of the movie/TV show cannot otherwise be determined.
* *Radarr or Sonarr APIs are not called and their database is not updated.*<br/>This may require a manual rescan of converted videos. * *Radarr or Sonarr APIs are not called and their database is not updated.*<br/>This may require a manual rescan of converted videos.
* *Original video files are deleted.*<br/>The Recycle Bin function is not available. * *Original video files are deleted.*<br/>The Recycle Bin function is not available.
+23 -22
View File
@@ -7,40 +7,41 @@ Repos:
Dev/test: https://github.com/TheCaptain989/radarr-striptracks Dev/test: https://github.com/TheCaptain989/radarr-striptracks
Prod: https://github.com/linuxserver/docker-mods/tree/radarr-striptracks Prod: https://github.com/linuxserver/docker-mods/tree/radarr-striptracks
Version: $(cat /etc/version.tc989) Version: {{VERSION}}
---------------- ----------------
EOF EOF
# Determine if setup is needed # Determine if setup is needed
if [ ! -f /usr/bin/mkvmerge ]; then if [ ! -f /usr/bin/mkvmerge ]; then
echo "Running first time setup." echo "Running first time setup."
if [ -f /usr/bin/apt ]; then
# Ubuntu if [ -f /usr/bin/apt ]; then
echo "Installing MKVToolNix using apt-get" # Ubuntu
apt-get -y install mkvtoolnix && \ echo "Installing MKVToolNix using apt-get"
rm -rf /var/lib/apt/lists/* apt-get -y install mkvtoolnix && \
elif [ -f /sbin/apk ]; then rm -rf /var/lib/apt/lists/*
# Alpine elif [ -f /sbin/apk ]; then
echo "Installing MKVToolNix using apk" # Alpine
apk add --no-cache mkvtoolnix && \ echo "Installing MKVToolNix using apk"
rm -rf /var/lib/apt/lists/* apk add --no-cache mkvtoolnix && \
else rm -rf /var/lib/apt/lists/*
# Unknown else
echo "Unknown package manager. Attempting to install MKVToolNix using apt-get" # Unknown
apt-get -y install mkvtoolnix && \ echo "Unknown package manager. Attempting to install MKVToolNix using apt-get"
rm -rf /var/lib/apt/lists/* apt-get -y install mkvtoolnix && \
fi rm -rf /var/lib/apt/lists/*
fi
fi fi
# Change ownership # Change ownership
if [ $(stat -c '%G' /usr/local/bin/striptracks.sh) != "abc" ]; then if [ $(stat -c '%G' /usr/local/bin/striptracks.sh) != "abc" ]; then
echo "Changing ownership on scripts." echo "Changing ownership on scripts."
chown abc:abc /usr/local/bin/striptracks*.sh chown abc:abc /usr/local/bin/striptracks*.sh
fi fi
# Make executable # Make executable
if [ ! -x /usr/local/bin/striptracks.sh ]; then if [ ! -x /usr/local/bin/striptracks.sh ]; then
echo "Making scripts executable." echo "Making scripts executable."
chmod +x /usr/local/bin/striptracks*.sh chmod +x /usr/local/bin/striptracks*.sh
fi fi
@@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh --audio :org:eng:und --subs :eng:und
@@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh --audio :org:ger:deu --subs :org:ger:deu
@@ -0,0 +1,3 @@
#!/bin/bash
. /usr/local/bin/striptracks.sh --audio :org:spa --subs :org:spa
+126 -98
View File
@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Video remuxing script designed for use with Radarr and Sonarr # Video remuxing script designed for use with Radarr and Sonarr
# Automatically strips out unwanted audio and subtitle streams, keeping only the desired languages. # Automatically strips out unwanted audio and subtitles streams, keeping only the desired languages.
# Prod: https://github.com/linuxserver/docker-mods/tree/radarr-striptracks # Prod: https://github.com/linuxserver/docker-mods/tree/radarr-striptracks
# Dev/test: https://github.com/TheCaptain989/radarr-striptracks # Dev/test: https://github.com/TheCaptain989/radarr-striptracks
@@ -30,7 +30,7 @@
# 0 - success; or test # 0 - success; or test
# 1 - no video file specified on command line # 1 - no video file specified on command line
# 2 - no audio language specified on command line # 2 - no audio language specified on command line
# 3 - no subtitle language specified on command line # 3 - no subtitles language specified on command line
# 4 - mkvmerge not found # 4 - mkvmerge not found
# 5 - specified video file not found # 5 - specified video file not found
# 6 - unable to rename video to temp video # 6 - unable to rename video to temp video
@@ -42,21 +42,21 @@
### Variables ### Variables
export striptracks_script=$(basename "$0") export striptracks_script=$(basename "$0")
export striptracks_ver="{{VERSION}}"
export striptracks_pid=$$ export striptracks_pid=$$
export striptracks_arr_config=/config/config.xml export striptracks_arr_config=/config/config.xml
export striptracks_log=/config/logs/striptracks.txt export striptracks_log=/config/logs/striptracks.txt
export striptracks_maxlogsize=512000 export striptracks_maxlogsize=512000
export striptracks_maxlog=4 export striptracks_maxlog=4
export striptracks_debug=0 export striptracks_debug=0
export striptracks_langcodes= unset striptracks_pos_params
export striptracks_pos_params=
# Presence of '*_eventtype' variable sets script mode # Presence of '*_eventtype' variable sets script mode
export striptracks_type=$(printenv | sed -n 's/_eventtype *=.*$//p') export striptracks_type=$(printenv | sed -n 's/_eventtype *=.*$//p')
# Usage function # Usage function
function usage { function usage {
usage=" usage="
$striptracks_script $striptracks_script Version: $striptracks_ver
Video remuxing script that only keeps tracks with the specified languages. Video remuxing script that only keeps tracks with the specified languages.
Designed for use with Radarr and Sonarr, but may be used standalone in batch mode. Designed for use with Radarr and Sonarr, but may be used standalone in batch mode.
@@ -80,9 +80,10 @@ Options and Arguments:
WARNING: Do not use this argument when called WARNING: Do not use this argument when called
from Radarr or Sonarr! from Radarr or Sonarr!
--help display this help and exit --help display this help and exit
--version display script version and exit
When audio_languages and subtitle_languages are omitted the script detects the audio When audio_languages and subtitle_languages are omitted the script detects the audio
or subtitle languages configured in Radarr or Sonarr profile. When used on the command or subtitle languages configured in the Radarr or Sonarr profile. When used on the command
line, they override the detected codes. They are also accepted as positional parameters line, they override the detected codes. They are also accepted as positional parameters
for backwards compatibility. for backwards compatibility.
@@ -97,6 +98,8 @@ Examples:
# languages detected from Radarr/Sonarr # languages detected from Radarr/Sonarr
$striptracks_script -a :eng:und -s :eng # keep English and Unknown audio and $striptracks_script -a :eng:und -s :eng # keep English and Unknown audio and
# English subtitles # English subtitles
$striptracks_script -a :eng:org -s :eng # keep English and Original audio and
# English subtitles
$striptracks_script :eng \"\" # keep English audio and no subtitles $striptracks_script :eng \"\" # keep English audio and no subtitles
$striptracks_script -d :eng:kor:jpn :eng:spa # Enable debugging level 1, keeping English, Korean, $striptracks_script -d :eng:kor:jpn :eng:spa # Enable debugging level 1, keeping English, Korean,
# and Japanese audio, and English and # and Japanese audio, and English and
@@ -126,6 +129,10 @@ while (( "$#" )); do
usage usage
exit 0 exit 0
;; ;;
--version ) # Display version
echo "$striptracks_script $striptracks_ver"
exit 0
;;
-f|--file ) # Batch Mode -f|--file ) # Batch Mode
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
# Overrides detected *_eventtype # Overrides detected *_eventtype
@@ -172,6 +179,14 @@ done
# Set positional arguments in their proper place # Set positional arguments in their proper place
eval set -- "$striptracks_pos_params" eval set -- "$striptracks_pos_params"
# Check for and assign positional arguments
if [ -n "$1" ]; then
striptracks_audiokeep="$1"
fi
if [ -n "$2" ]; then
striptracks_subskeep="$2"
fi
## Mode specific variables ## Mode specific variables
if [[ "${striptracks_type,,}" = "batch" ]]; then if [[ "${striptracks_type,,}" = "batch" ]]; then
# Batch mode # Batch mode
@@ -205,7 +220,7 @@ elif [[ "${striptracks_type,,}" = "sonarr" ]]; then
export striptracks_language_api="languageprofile" export striptracks_language_api="languageprofile"
else else
# Called in an unexpected way # Called in an unexpected way
echo -e "Error|Unknown or missing '*_eventtype' environment variable: ${striptracks_type}\nNot called within Radarr/Sonarr?\nTry using Batch Mode option: -f <file>" echo -e "Error|Unknown or missing '*_eventtype' environment variable: ${striptracks_type}\nNot called from Radarr/Sonarr.\nTry using Batch Mode option: -f <file>"
exit 7 exit 7
fi fi
export striptracks_rescan_api="Rescan${striptracks_video_type^}" export striptracks_rescan_api="Rescan${striptracks_video_type^}"
@@ -214,7 +229,7 @@ export striptracks_eventtype="${striptracks_type,,}_eventtype"
export striptracks_tempvideo="${striptracks_video}.tmp" export striptracks_tempvideo="${striptracks_video}.tmp"
export striptracks_newvideo="${striptracks_video%.*}.mkv" export striptracks_newvideo="${striptracks_video%.*}.mkv"
# If this were defined directly in Radarr or Sonarr this would not be needed here # If this were defined directly in Radarr or Sonarr this would not be needed here
striptracks_isocodemap='{"languages":[{"language":{"name":"Any","iso639-2":["ara","bul","zho","chi","ces","cze","dan","nld","dut","eng","fin","fra","fre","deu","ger","ell","gre","heb","hin","hun","isl","ice","ita","jpn","kor","lit","nor","pol","por","ron","rom","rus","spa","swe","tha","tur","vie","und"]}},{"language":{"name":"Original","iso639-2":["ara","bul","zho","chi","ces","cze","dan","nld","dut","eng","fin","fra","fre","deu","ger","ell","gre","heb","hin","hun","isl","ice","ita","jpn","kor","lit","nor","pol","por","ron","rom","rus","spa","swe","tha","tur","vie","und"]}},{"language":{"name":"Arabic","iso639-2":["ara"]}},{"language":{"name":"Bulgarian","iso639-2":["bul"]}},{"language":{"name":"Chinese","iso639-2":["zho","chi"]}},{"language":{"name":"Czech","iso639-2":["ces","cze"]}},{"language":{"name":"Danish","iso639-2":["dan"]}},{"language":{"name":"Dutch","iso639-2":["nld","dut"]}},{"language":{"name":"English","iso639-2":["eng"]}},{"language":{"name":"Finnish","iso639-2":["fin"]}},{"language":{"name":"Flemish","iso639-2":["nld","dut"]}},{"language":{"name":"French","iso639-2":["fra","fre"]}},{"language":{"name":"German","iso639-2":["deu","ger"]}},{"language":{"name":"Greek","iso639-2":["ell","gre"]}},{"language":{"name":"Hebrew","iso639-2":["heb"]}},{"language":{"name":"Hindi","iso639-2":["hin"]}},{"language":{"name":"Hungarian","iso639-2":["hun"]}},{"language":{"name":"Icelandic","iso639-2":["isl","ice"]}},{"language":{"name":"Italian","iso639-2":["ita"]}},{"language":{"name":"Japanese","iso639-2":["jpn"]}},{"language":{"name":"Korean","iso639-2":["kor"]}},{"language":{"name":"Lithuanian","iso639-2":["lit"]}},{"language":{"name":"Norwegian","iso639-2":["nor"]}},{"language":{"name":"Polish","iso639-2":["pol"]}},{"language":{"name":"Portuguese","iso639-2":["por"]}},{"language":{"name":"Romanian","iso639-2":["rum","ron"]}},{"language":{"name":"Russian","iso639-2":["rus"]}},{"language":{"name":"Spanish","iso639-2":["spa"]}},{"language":{"name":"Swedish","iso639-2":["swe"]}},{"language":{"name":"Thai","iso639-2":["tha"]}},{"language":{"name":"Turkish","iso639-2":["tur"]}},{"language":{"name":"Vietnamese","iso639-2":["vie"]}},{"language":{"name":"Unknown","iso639-2":["und"]}}]}' striptracks_isocodemap='{"languages":[{"language":{"name":"Any","iso639-2":["ara","bul","zho","chi","ces","cze","dan","nld","dut","eng","fin","fra","fre","deu","ger","ell","gre","heb","hin","hun","isl","ice","ita","jpn","kor","lit","nor","pol","por","ron","rom","rus","spa","swe","tha","tur","vie","und"]}},{"language":{"name":"Arabic","iso639-2":["ara"]}},{"language":{"name":"Bulgarian","iso639-2":["bul"]}},{"language":{"name":"Chinese","iso639-2":["zho","chi"]}},{"language":{"name":"Czech","iso639-2":["ces","cze"]}},{"language":{"name":"Danish","iso639-2":["dan"]}},{"language":{"name":"Dutch","iso639-2":["nld","dut"]}},{"language":{"name":"English","iso639-2":["eng"]}},{"language":{"name":"Finnish","iso639-2":["fin"]}},{"language":{"name":"Flemish","iso639-2":["nld","dut"]}},{"language":{"name":"French","iso639-2":["fra","fre"]}},{"language":{"name":"German","iso639-2":["deu","ger"]}},{"language":{"name":"Greek","iso639-2":["ell","gre"]}},{"language":{"name":"Hebrew","iso639-2":["heb"]}},{"language":{"name":"Hindi","iso639-2":["hin"]}},{"language":{"name":"Hungarian","iso639-2":["hun"]}},{"language":{"name":"Icelandic","iso639-2":["isl","ice"]}},{"language":{"name":"Italian","iso639-2":["ita"]}},{"language":{"name":"Japanese","iso639-2":["jpn"]}},{"language":{"name":"Korean","iso639-2":["kor"]}},{"language":{"name":"Lithuanian","iso639-2":["lit"]}},{"language":{"name":"Norwegian","iso639-2":["nor"]}},{"language":{"name":"Polish","iso639-2":["pol"]}},{"language":{"name":"Portuguese","iso639-2":["por"]}},{"language":{"name":"Romanian","iso639-2":["rum","ron"]}},{"language":{"name":"Russian","iso639-2":["rus"]}},{"language":{"name":"Spanish","iso639-2":["spa"]}},{"language":{"name":"Swedish","iso639-2":["swe"]}},{"language":{"name":"Thai","iso639-2":["tha"]}},{"language":{"name":"Turkish","iso639-2":["tur"]}},{"language":{"name":"Vietnamese","iso639-2":["vie"]}},{"language":{"name":"Unknown","iso639-2":["und"]}}]}'
### Functions ### Functions
@@ -280,7 +295,7 @@ function get_videofile_info {
function rescan { function rescan {
striptracks_message="Info|Calling ${striptracks_type^} API to rescan ${striptracks_video_type}, try #$loop" striptracks_message="Info|Calling ${striptracks_type^} API to rescan ${striptracks_video_type}, try #$loop"
echo "$striptracks_message" | log echo "$striptracks_message" | log
[ $striptracks_debug -ge 1 ] && echo "Debug|Forcing rescan of $striptracks_json_key '$striptracks_rescan_id', try #$loop. Calling ${striptracks_type^} API '$striptracks_rescan_api' using POST and URL '$striptracks_api_url/v3/command' with data {\"name\": \"$striptracks_rescan_api\", \"$striptracks_json_key\": $striptracks_rescan_id}" | log [ $striptracks_debug -ge 1 ] && echo "Debug|Forcing rescan of $striptracks_video_api '$striptracks_rescan_id', try #$loop. Calling ${striptracks_type^} API '$striptracks_rescan_api' using POST and URL '$striptracks_api_url/v3/command' with data {\"name\": \"$striptracks_rescan_api\", \"$striptracks_json_key\": $striptracks_rescan_id}" | log
striptracks_result=$(curl -s -H "X-Api-Key: $striptracks_apikey" -H "Content-Type: application/json" \ striptracks_result=$(curl -s -H "X-Api-Key: $striptracks_apikey" -H "Content-Type: application/json" \
-d "{\"name\": \"$striptracks_rescan_api\", \"$striptracks_json_key\": $striptracks_rescan_id}" \ -d "{\"name\": \"$striptracks_rescan_api\", \"$striptracks_json_key\": $striptracks_rescan_id}" \
-X POST "$striptracks_api_url/v3/command") -X POST "$striptracks_api_url/v3/command")
@@ -382,6 +397,7 @@ function get_mediainfo {
fi fi
return $striptracks_return return $striptracks_return
} }
### End Functions
# Check for required binaries # Check for required binaries
if [ ! -f "/usr/bin/mkvmerge" ]; then if [ ! -f "/usr/bin/mkvmerge" ]; then
@@ -474,7 +490,7 @@ if [[ "${!striptracks_eventtype}" = "Test" ]]; then
exit 0 exit 0
fi fi
# Check if video file is blank # Check if video file variable is blank
if [ -z "$striptracks_video" ]; then if [ -z "$striptracks_video" ]; then
striptracks_message="Error|No video file detected! radarr_moviefile_path or sonarr_episodefile_path environment variable missing or -f option not specified on command line." striptracks_message="Error|No video file detected! radarr_moviefile_path or sonarr_episodefile_path environment variable missing or -f option not specified on command line."
echo "$striptracks_message" | log echo "$striptracks_message" | log
@@ -492,9 +508,10 @@ if [ ! -f "$striptracks_video" ]; then
fi fi
#### Detect languages configured in Radarr/Sonarr #### Detect languages configured in Radarr/Sonarr
# Check for URL # Bypass language detection if using batch mode
if [ "$striptracks_type" = "batch" ]; then if [ "$striptracks_type" = "batch" ]; then
[ $striptracks_debug -ge 1 ] && echo "Debug|Cannot detect languages in batch mode." | log [ $striptracks_debug -ge 1 ] && echo "Debug|Cannot detect languages in batch mode." | log
# Check for URL
elif [ -n "$striptracks_api_url" ]; then elif [ -n "$striptracks_api_url" ]; then
# Get language codes # Get language codes
if get_language_codes; then if get_language_codes; then
@@ -521,15 +538,25 @@ elif [ -n "$striptracks_api_url" ]; then
exit 7 exit 7
fi fi
striptracks_profileName="$(echo $striptracks_profiles | jq -crM ".[] | select(.id == $striptracks_profileId).name")" striptracks_profileName="$(echo $striptracks_profiles | jq -crM ".[] | select(.id == $striptracks_profileId).name")"
striptracks_languageNames="$(echo $striptracks_languages | jq -crM "[.[].name]")"
[ $striptracks_debug -ge 1 ] && echo "Debug|Detected $striptracks_profile_type profile '(${striptracks_profileId}) ${striptracks_profileName}'" | log [ $striptracks_debug -ge 1 ] && echo "Debug|Detected $striptracks_profile_type profile '(${striptracks_profileId}) ${striptracks_profileName}'" | log
[ $striptracks_debug -ge 1 ] && echo "Debug|Detected profile language(s) '$(echo $striptracks_languageNames | jq -crM "join(\",\")")' id(s) of '$(echo $striptracks_languages | jq -crM "[.[].id | tostring] | join(\",\")")'" | log striptracks_proflangNames="$(echo $striptracks_languages | jq -crM "[.[].name]")"
# Map 'Language' Id(s) to ISO code(s) used by mkvmerge [ $striptracks_debug -ge 1 ] && echo "Debug|Detected $striptracks_profile_type profile language(s) '$(echo $striptracks_languages | jq -crM '[.[] | "(\(.id | tostring)) \(.name)"] | join(",")')'" | log
unset striptracks_langcodes # Get originalLanguage of video from Radarr
for i in $(echo $striptracks_languageNames | jq -crM ".[]"); do striptracks_orglangName="$(echo $striptracks_result | jq -crM .originalLanguage.name)"
striptracks_langcodes+="$(echo $striptracks_isocodemap | jq -jcrM ".languages[] | select(.language.name == \"$i\") | .language | \":\(.\"iso639-2\"[])\"")" if [ -n "$striptracks_orglangName" ]; then
striptracks_orglangCode="$(echo $striptracks_isocodemap | jq -jcrM ".languages[] | select(.language.name == \"$striptracks_orglangName\") | .language | \":\(.\"iso639-2\"[])\"")"
[ $striptracks_debug -ge 1 ] && echo "Debug|Detected original video language of '$striptracks_orglangName ($striptracks_orglangCode)' from $striptracks_video_type '$striptracks_video_id'" | log
fi
# Map language names to ISO code(s) used by mkvmerge
unset striptracks_proflangCodes
for striptracks_templang in $(echo $striptracks_proflangNames | jq -crM ".[]"); do
# Convert 'Original' profile selection to specific video language (Radarr only)
if [[ "$striptracks_templang" = "Original" ]]; then
striptracks_templang="$striptracks_orglangName"
fi
striptracks_proflangCodes+="$(echo $striptracks_isocodemap | jq -jcrM ".languages[] | select(.language.name == \"$striptracks_templang\") | .language | \":\(.\"iso639-2\"[])\"")"
done done
[ $striptracks_debug -ge 1 ] && echo "Debug|Mapped language(s) '$(echo $striptracks_languageNames | jq -crM "join(\",\")")' to ISO639-2 code string '$striptracks_langcodes'" | log [ $striptracks_debug -ge 1 ] && echo "Debug|Mapped profile language(s) '$(echo $striptracks_proflangNames | jq -crM "join(\",\")")' to ISO639-2 code string '$striptracks_proflangCodes'" | log
else else
# 'hasFile' is False in returned JSON. # 'hasFile' is False in returned JSON.
striptracks_message="Warn|The '$striptracks_video_api' API with id $striptracks_video_id returned a false hasFile." striptracks_message="Warn|The '$striptracks_video_api' API with id $striptracks_video_id returned a false hasFile."
@@ -555,14 +582,14 @@ else
echo "$striptracks_message" >&2 echo "$striptracks_message" >&2
fi fi
# Check for command line language options; will override the detected languages # Final assignment of audio and subtitles options
if [ -n "$1" ]; then if [ -n "$striptracks_audiokeep" ]; then
striptracks_audiokeep="$1" # Allows ordered argument on command line to override detected languages
elif [ -n "$striptracks_audiokeep" ]; then # plus special handling of ':org' code
# Needed to allow ordered argument on command line to override detected languages [ $striptracks_debug -ge 1 ] && [[ "$striptracks_audiokeep" ~= :org ]] && echo "Debug|:org specified for audio. Using new code string of ${striptracks_audiokeep//:org/${striptracks_orglangCode}}" | log
striptracks_audiokeep="$striptracks_audiokeep" striptracks_audiokeep="${striptracks_audiokeep//:org/${striptracks_orglangCode}}"
elif [ -n "$striptracks_langcodes" ]; then elif [ -n "$striptracks_proflangCodes" ]; then
striptracks_audiokeep="$striptracks_langcodes" striptracks_audiokeep="$striptracks_proflangCodes"
else else
striptracks_message="Error|No audio languages specified or detected!" striptracks_message="Error|No audio languages specified or detected!"
echo "$striptracks_message" | log echo "$striptracks_message" | log
@@ -570,13 +597,14 @@ else
usage usage
exit 2 exit 2
fi fi
if [ -n "$2" ]; then
striptracks_subskeep="$2" if [ -n "$striptracks_subskeep" ]; then
elif [ -n "$striptracks_subskeep" ]; then # Allows ordered argument on command line to override detected languages
# Needed to allow ordered argument on command line to override detected languages # plus special handling of ':org' code
striptracks_subskeep="$striptracks_subskeep" [ $striptracks_debug -ge 1 ] && [[ "$striptracks_subskeep" ~= :org ]] && echo "Debug|:org specified for subtitles. Using new code string of ${striptracks_subskeep//:org/${striptracks_orglangCode}}" | log
elif [ -n "$striptracks_langcodes" ]; then striptracks_subskeep="${striptracks_subskeep//:org/${striptracks_orglangCode}}"
striptracks_subskeep="$striptracks_langcodes" elif [ -n "$striptracks_proflangCodes" ]; then
striptracks_subskeep="$striptracks_proflangCodes"
else else
striptracks_message="Error|No subtitles languages specified or detected!" striptracks_message="Error|No subtitles languages specified or detected!"
echo "$striptracks_message" | log echo "$striptracks_message" | log
@@ -627,6 +655,7 @@ striptracks_return=$?; [ "$striptracks_return" != 0 ] && {
exit 6 exit 6
} }
# Process video file
echo "$striptracks_json_processed" | awk -v Debug=$striptracks_debug \ echo "$striptracks_json_processed" | awk -v Debug=$striptracks_debug \
-v OrgVideo="$striptracks_video" \ -v OrgVideo="$striptracks_video" \
-v TempVideo="$striptracks_tempvideo" \ -v TempVideo="$striptracks_tempvideo" \
@@ -634,102 +663,101 @@ echo "$striptracks_json_processed" | awk -v Debug=$striptracks_debug \
-v Title="$striptracks_title" \ -v Title="$striptracks_title" \
-v AudioKeep="$striptracks_audiokeep" \ -v AudioKeep="$striptracks_audiokeep" \
-v SubsKeep="$striptracks_subskeep" ' -v SubsKeep="$striptracks_subskeep" '
# Array join function, based on GNU docs
function join(array, sep, i, ret) {
for (i in array)
if (!ret)
ret = array[i]
else
ret = ret sep array[i]
return ret
}
BEGIN { BEGIN {
MKVMerge="/usr/bin/mkvmerge" MKVMerge = "/usr/bin/mkvmerge"
FS="[\t\n: ]" FS = "[\t\n: ]"
IGNORECASE=1 IGNORECASE = 1
} }
/^Track ID/ { /^Track ID/ {
FieldCount=split($0, Fields) FieldCount = split($0, Fields)
if (Fields[1]=="Track") { if (Fields[1] == "Track") {
NoTr++ NoTr++
Track[NoTr, "id"]=Fields[3] Track[NoTr, "id"] = Fields[3]
Track[NoTr, "typ"]=Fields[5] Track[NoTr, "typ"] = Fields[5]
# This is inelegant and I know it # This is inelegant and I know it
if (Fields[6]~/^\(/) { # Finds the codec in parenthesis
for (i=6; i<=FieldCount; i++) { if (Fields[6] ~ /^\(/) {
Track[NoTr, "codec"]=Track[NoTr, "codec"]" "Fields[i] for (i = 6; i <= FieldCount; i++) {
if (match(Fields[i],/\)$/)) { Track[NoTr, "codec"] = Track[NoTr, "codec"]" "Fields[i]
if (match(Fields[i], /\)$/))
break break
}
} }
sub(/^ /,"",Track[NoTr, "codec"]) sub(/^ /, "", Track[NoTr, "codec"])
} }
if (Track[NoTr, "typ"]=="video") VidCnt++ if (Track[NoTr, "typ"] == "video") VidCnt++
if (Track[NoTr, "typ"]=="audio") AudCnt++ if (Track[NoTr, "typ"] == "audio") AudCnt++
if (Track[NoTr, "typ"]=="subtitles") SubsCnt++ if (Track[NoTr, "typ"] == "subtitles") SubsCnt++
for (i=6; i<=FieldCount; i++) { for (i = 6; i <= FieldCount; i++) {
if (Fields[i]=="language") Track[NoTr, "lang"]=Fields[++i] if (Fields[i] == "language")
Track[NoTr, "lang"] = Fields[++i]
} }
if (Track[NoTr, "lang"]=="") Track[NoTr, "lang"]="und" if (Track[NoTr, "lang"] == "")
Track[NoTr, "lang"] = "und"
} }
} }
/^Chapters/ { /^Chapters/ {
Chapters=$3 Chapters = $3
} }
END { END {
if (!NoTr) { print "Error|No tracks found in \""TempVideo"\"" > "/dev/stderr"; exit } if (!NoTr) {
print "Error|No tracks found in \""TempVideo"\"" > "/dev/stderr"
exit
}
if (!AudCnt) AudCnt=0; if (!SubsCnt) SubsCnt=0 if (!AudCnt) AudCnt=0; if (!SubsCnt) SubsCnt=0
print "Info|Original tracks: "NoTr" (audio: "AudCnt", subtitles: "SubsCnt")" print "Info|Original tracks: "NoTr" (audio: "AudCnt", subtitles: "SubsCnt")"
if (Chapters) print "Info|Chapters: "Chapters if (Chapters) print "Info|Chapters: "Chapters
for (i=1; i<=NoTr; i++) { for (i = 1; i <= NoTr; i++) {
if (Debug >= 2) print "Debug|i:"i,"Track ID:"Track[i,"id"],"Type:"Track[i,"typ"],"Lang:"Track[i, "lang"],"Codec:"Track[i, "codec"] if (Debug >= 2) print "Debug|i:"i,"Track ID:"Track[i,"id"],"Type:"Track[i,"typ"],"Lang:"Track[i, "lang"],"Codec:"Track[i, "codec"]
if (Track[i, "typ"]=="audio") { if (Track[i, "typ"] == "audio") {
if (AudioKeep~Track[i, "lang"]) { if (AudioKeep ~ Track[i, "lang"]) {
AudKpCnt++
print "Info|Keeping audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"] print "Info|Keeping audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"]
if (AudioCommand=="") { AudioCommand[i] = Track[i, "id"]
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 # Special case if there is only one audio track, even if it was not specified
} else if (AudCnt==1) { } else if (AudCnt == 1) {
AudKpCnt++
print "Info|Keeping only audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"] print "Info|Keeping only audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"]
AudioCommand=Track[i, "id"] AudioCommand[i] = Track[i, "id"]
# Special case if there were multiple tracks, none were selected, and this is the last one. # Special case if there were multiple tracks, none were selected, and this is the last one.
} else if (AudioCommand=="" && Track[i, "id"]==AudCnt) { } else if (length(AudioCommand) == 0 && Track[i, "id"] == AudCnt) {
AudKpCnt++
print "Info|Keeping last audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"] print "Info|Keeping last audio track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"]
AudioCommand=Track[i, "id"] AudioCommand[i] = Track[i, "id"]
} else { } else
if (Debug >= 1) print "Debug|\tRemove:", Track[i, "typ"], "track", Track[i, "id"], Track[i, "lang"], Track[i, "codec"] AudRmvLog[i] = Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"]
}
} else { } else {
if (Track[i, "typ"]=="subtitles") { if (Track[i, "typ"] == "subtitles") {
if (SubsKeep~Track[i, "lang"]) { if (SubsKeep ~ Track[i, "lang"]) {
SubsKpCnt++ print "Info|Keeping subtitles track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"]
print "Info|Keeping subtitle track "Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"] SubsCommand[i] = Track[i, "id"]
if (SubsCommand=="") { } else
SubsCommand=Track[i, "id"] SubsRmvLog[i] = Track[i, "id"]": "Track[i, "lang"]" "Track[i, "codec"]
} else {
SubsCommand=SubsCommand","Track[i, "id"]
}
} else {
if (Debug >= 1) print "Debug|\tRemove:", Track[i, "typ"], "track", Track[i, "id"], Track[i, "lang"], Track[i, "codec"]
}
} }
} }
} }
if (!AudKpCnt) AudKpCnt=0; if (!SubsKpCnt) SubsKpCnt=0 if (length(AudRmvLog) != 0) print "Info|Removed audio tracks: " join(AudRmvLog, ",")
print "Info|Kept tracks: "AudKpCnt+SubsKpCnt+VidCnt" (audio: "AudKpCnt", subtitles: "SubsKpCnt")" if (length(SubsRmvLog) != 0) print "Info|Removed subtitles tracks: " join(SubsRmvLog, ",")
if (AudioCommand=="") { print "Info|Kept tracks: "length(AudioCommand)+length(SubsCommand)+VidCnt" (audio: "length(AudioCommand)", subtitles: "length(SubsCommand)")"
if (length(AudioCommand) == 0) {
# This should never happen, but belt and suspenders # This should never happen, but belt and suspenders
CommandLine="-A" # Prevents errors during mkvmerge execution
} else { CommandLine = "-A"
CommandLine="-a "AudioCommand } else
} CommandLine = "-a " join(AudioCommand, ",")
if (SubsCommand=="") { if (length(SubsCommand) == 0)
CommandLine=CommandLine" -S" CommandLine = CommandLine" -S"
} else { else
CommandLine=CommandLine" -s "SubsCommand CommandLine = CommandLine" -s " join(SubsCommand, ",")
}
if (Debug >= 1) print "Debug|Executing: nice "MKVMerge" --title \""Title"\" -q -o \""MKVVideo"\" "CommandLine" \""TempVideo"\"" if (Debug >= 1) print "Debug|Executing: nice "MKVMerge" --title \""Title"\" -q -o \""MKVVideo"\" "CommandLine" \""TempVideo"\""
Result=system("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" if (Result>1) print "Error|["Result"] remuxing \""TempVideo"\"" > "/dev/stderr"
}' | log }' | log
#### END MAIN #### END MAIN
# Check for script completion and non-empty file # Check for script completion and non-empty file