Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/BuildImage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
echo "MULTI_ARCH=${{ env.MULTI_ARCH }}" >> $GITHUB_OUTPUT
if [[ -z "${{ env.MOD_VERSION }}" ]]; then
# **** If the mod needs to be versioned, set the versioning logic below. Otherwise leave as is. ****
MOD_VERSION="2.18.0"
MOD_VERSION="2.19.0"
else
MOD_VERSION=${{ env.MOD_VERSION }}
echo "MOD_VERSION_OVERRIDE=true" >> $GITHUB_OUTPUT
Expand Down
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ All language conditions with positive scores *and* Negated conditions with negat
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:
`striptracks.sh [{-a|--audio} <audio_languages[+modifier]> [{-s|--subs} <subtitle_languages[+modifier]>] [{-f|--file} <video_file>]] [--reorder] [--disable-recycle] [--skip-profile <profile_name>]... [--set-default-audio <language_code[=name]>] [--set-default-subs <language_code[=name]>]
`striptracks.sh [{-a|--audio} <audio_languages[+modifier]> [{-s|--subs} <subtitle_languages[+modifier]>] [{-f|--file} <video_file>]] [--reorder] [--disable-recycle] [--skip-profile <profile_name>]... [--set-default-audio <language_code[=name][-f]>] [--set-default-subs <language_code[=name][-f]>]
[{-l|--log} <log_file>] [{-c|--config} <config_file>] [{-p|--priority} {idle|low|medium|high}] [{-d|--debug} [<level>]]`

<details>
Expand All @@ -224,17 +224,17 @@ Option|Argument|Description
`-a`, `--audio`|`<audio_languages[+modifier]>`|Audio languages to keep<br/>ISO 639-2 code(s) prefixed with a colon (`:`)<br/>Each code may optionally be followed by a plus (`+`) and one or more [modifiers](#language-code-modifiers).
`-s`, `--subs`|`<subtitle_languages[+modifier]>`|Subtitle languages to keep<br/>ISO 639-2 code(s) prefixed with a colon (`:`)<br/>Each code may optionally be followed by a plus (`+`) and one or more modifiers.
`-f`, `--file`|`<video_file>`|If included, the script enters **[Batch Mode](#batch-mode)** and converts the specified video file.<br/>Requires the `--audio` option.<br/>![notes] **Do not** use this argument when called from Radarr or Sonarr!
`--reorder`| |Reorder audio and subtitles tracks to match the language code order specified in the `<audio_languages>` and `<subtitle_languages>` arguments.
`--disable-recycle`| |Disable recycle bin use, even if configured in Radarr/Sonarr
`--reorder`||Reorder audio and subtitles tracks to match the language code order specified in the `<audio_languages>` and `<subtitle_languages>` arguments.
`--disable-recycle`||Disable recycle bin use, even if configured in Radarr/Sonarr
`--skip-profile`|`<profile_name>`|Skip processing if the video was downloaded using the specified Quality Profile name. May be specified multiple times to skip multiple profiles.
`--set-default-audio`|`<language_code[=name]>`|Set the default audio track to the first track of the specified language. Only one language code is allowed. If specified, all other tracks are marked as not default.<br/>The code may optionally be followed by an equals (`=`) and a [track name](#setting-default-track) matching string.
`--set-default-subs`|`<language_code[=name]>`|Set the default subtitles track to the first track of the specified language. Only one language code is allowed. If specified, all other tracks are marked as not default.<br/>The code may optionally be followed by an equals (`=`) and a track name string.
`--set-default-audio`|`<language_code[=name][-f]>`|Set the default audio track to the first track of the specified language. Only one language code is allowed. If specified, all other tracks are marked as not default.<br/>The code may optionally be followed by an equals (`=`) and a [track name](#setting-default-track) matching string.<br/>The code may optionally be followed by a minus f (`-f`) to indicate skipping Forced tracks.
`--set-default-subs`|`<language_code[=name][-f]>`|Set the default subtitles track to the first track of the specified language. Only one language code is allowed. If specified, all other tracks are marked as not default.<br/>The code may optionally be followed by an equals (`=`) and a track name string.<br/>The code may optionally be followed by a minus f (`-f`) to indicate skipping Forced tracks.
`-l`, `--log`|`<log_file>`|The log filename<br/>Default is `/config/log/striptracks.txt`
`-c`, `--config`|`<config_file>`|Radarr/Sonarr XML configuration file<br/>Default is `/config/config.xml`
`-p`, `--priority`|`idle`, `low`, `medium`, `high`|CPU and I/O process priority for mkvmerge<br/>Default is `medium`<br/>![notes] High priority can consume all system resources. When processing a large video file your system may become unresponsive!
`-d`, `--debug`|`[<level>]`|Enables debug logging. Level is optional.<br/>Default is `1` (low)<br/>`2` includes JSON output<br/>`3` contains even more JSON output
`--help`| |Display help and exit.
`--version`| |Display version and exit.
`--help`||Display help and exit.
`--version`||Display version and exit.

</details>

Expand Down Expand Up @@ -281,8 +281,12 @@ Modifiers may be combined, such as `:any+fd` to keep all forced and all default
Use the `--set-default` options to choose tracks that appear first when the video is played. Only one audio and one subtitles track may be set as default. The language code is the same colon (`:`) prepended ISO 639-2 language code used with the `--audio` and `--subs` options.
The first track of the specified language will have its default flag set and all other tracks (of any language) will have their default flag disabled.

The language code can optionally be follow by an equals (`=`) and a string which is used to match against the track name. The first track that matches the specified language and with a name that matches the string will be set to default.
The string matching uses a substring and is case insensitive. You can use this to set the default subtitles track to hearing impared (SDH), or the audio track to your preferred language.
The language code can optionally be followed by an equals (`=`) and a string which is matched against the track name. The first track that matches the specified language and with a name that matches the string will be set to default.
The string matching uses a substring and is case insensitive. You could use this to set the default subtitles track to hearing impared (SDH), for example.

The language code can optionally be followed by a minus f (`-f`) which indicates skipping tracks that have the forced flag set when choosing the default track.

The order of the `=name` and `-f` modifiers is not important.

The setting of default track flags occurs after the track selection logic.

Expand All @@ -291,14 +295,17 @@ The setting of default track flags occurs after the track selection logic.
> You may therefore not obtain consistent results.

<details>
<summary>Track Name Examples</summary>
<summary>Default Track Examples</summary>

If you want to set the default subtitles track to the first hearing impared English track, you would use:
`--set-default-subs :eng=SDH`

To set the default audio track to Dutch:
`--set-default-audio :dut`

To set the default subtitles track to the first non-forced English track:
`--set-default-subs :eng-f`

</details>

### Any language code
Expand Down Expand Up @@ -379,6 +386,12 @@ There is no way to force the script to remove audio tracks with these codes.
# (first audio track flagged as Default as it appears in the source file),
# one English subtitles track and two forced subtitles regardless of
# language (as they appear in the source file)
--audio :org:eng:fre:fra --subs :org:eng:fre:fra --reorder --disable-recycle --set-default-audio :org --set-default-subs :eng-f
# Keep the Original, English, and French audio and subtitles
# Reorder the tracks to match the above order (audio first, then substitles)
# Set the first Original language audio track as default
# Set the first non-forced English subtitles tracks as default
# Force delete the original video after remuxing
```

</details>
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Only the latest major and minor version are supported.

| Version | Supported |
| ------- | ------------------ |
| 2.18.x | :heavy_check_mark: |
| < 2.18 | :x: |
| 2.19.x | :heavy_check_mark: |
| < 2.19 | :x: |

## Reporting a Vulnerability

Expand Down
70 changes: 52 additions & 18 deletions root/usr/local/bin/striptracks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ mode.
Source: https://github.com/TheCaptain989/radarr-striptracks

Usage:
$0 [{-a|--audio} <audio_languages> [{-s|--subs} <subtitle_languages>] [{-f|--file} <video_file>]] [--reorder] [--disable-recycle] [--skip-profile <profile_name>]... [--set-default-audio <language_code[=name]>] [--set-default-subs <language_code[=name]>] [{-l|--log} <log_file>] [{-c|--config} <config_file>] [{-p|--priority} {idle|low|medium|high}] [{-d|--debug} [<level>]]
$0 [{-a|--audio} <audio_languages> [{-s|--subs} <subtitle_languages>] [{-f|--file} <video_file>]] [--reorder] [--disable-recycle] [--skip-profile <profile_name>]... [--set-default-audio <language_code[=name][-f]>] [--set-default-subs <language_code[=name][-f]>] [{-l|--log} <log_file>] [{-c|--config} <config_file>] [{-p|--priority} {idle|low|medium|high}] [{-d|--debug} [<level>]]

Options can also be set via the STRIPTRACKS_ARGS environment variable.
Command-line arguments override the environment variable.
Expand Down Expand Up @@ -155,16 +155,22 @@ Options and Arguments:
using the specified quality profile name.
May be specified multiple times to skip
multiple profiles.
--set-default-audio <language_code[=name]>
--set-default-audio <language_code[=name][-f]>
Set the default audio track to the first
track of the specified language.
The code may optionally be followed by an
equals \`=\` and a track name.
--set-default-subs <language_code[=name]>
The code may optionally be followed by a
minus \`-f\` to indicate skipping Forced
tracks.
--set-default-subs <language_code[=name][-f]>
Set the default subtitles track to the first
track of the specified language.
The code may optionally be followed by an
equals \`+\` and a track name.
equals \`=\` and a track name.
The code may optionally be followed by a
minus \`-f\` to indicate skipping Forced
tracks.
-l, --log <log_file> Log filename
[default: /config/log/striptracks.txt]
-c, --config <config_file> Radarr/Sonarr XML configuration file
Expand Down Expand Up @@ -646,14 +652,15 @@ function get_mediainfo {

local videofile="$1" # Video file to inspect

local mkvcommand="/usr/bin/mkvmerge -J \"$videofile\""
local mkvcommand="/usr/bin/mkvmerge -J \"$(escape_string "$videofile")\""
execute_mkv_command "$mkvcommand" "inspecting video"
local return=$?

unset striptracks_json
# This must be a declare statement to avoid the 'Argument list too long' error with some large returned JSON (see issue #104)
declare -g striptracks_json
striptracks_json="$striptracks_mkvresult"
return
return $return
}
# function import_video {
# # Import new video into Radarr/Sonarr
Expand Down Expand Up @@ -1047,14 +1054,24 @@ function wait_if_locked {
fi
return $return
}
function escape_string {
# Escape special characters in string for use in mkvmerge/mkvpropedit commands

local input="$1" # Input string to escape

# Escape backslashes, double quotes, and dollar signs
# shellcheck disable=SC2001
local output="$(echo "$input" | sed -e 's/[`"\\$]/\\&/g')"
echo "$output"
}
function execute_mkv_command {
# Execute mkvmerge or mkvpropedit command

local command="$1" # Full mkvmerge or mkvpropedit command to execute
local action="$2" # Action being performed (for logging purposes)

[ $striptracks_debug -ge 1 ] && echo "Debug|Executing: $command" | log
local shortcommand="$(echo $command | sed -E 's/(nice )?([^ ]+).*$/\2/')"
local shortcommand="$(echo $command | sed -E 's/(.+ )?(\/[^ ]+) .*$/\2/')"
shortcommand=$(basename "$shortcommand")
unset striptracks_mkvresult
# This must be a declare statement to avoid the 'Argument list too long' error with some large returned JSON (see issue #104)
Expand Down Expand Up @@ -1571,7 +1588,7 @@ function determine_track_order {
fi
}
function set_default_tracks {
# Build mkvpropedit paramaters to set default flags on audio and subtitle tracks.
# Build mkvpropedit parameters to set default flags on audio and subtitle tracks.

# Process audio and subtitle --set-default track settings
for tracktype in audio subtitles; do
Expand All @@ -1586,15 +1603,32 @@ function set_default_tracks {
# Use jq to find the track ID using case-insensitive substring match on track name
local track_id=$(echo "$striptracks_json_processed" | jq -crM --arg type "$tracktype" --arg currentcfg "$currentcfg" '
def parse_cfg(cfg):
cfg | ltrimstr(":") | split("=") | {lang: .[0], name: .[1]};

(parse_cfg($currentcfg)).lang as $lang |
(parse_cfg($currentcfg)).name as $name |
# Remove leading ":" then split on "=" (if present)
# Supports f as a modifier (see issue #113)
(cfg | ltrimstr(":") | split("=")) as $eq |
($eq[0]) as $left |
(if ($eq | length > 1) then $eq[1] else "" end) as $right |

# Detect trailing "-f" on left or right and strip it; only "f" is a valid modifier
(if ($left | test("-f$")) then {lang: ($left | sub("-f$"; "")), skip: true} else {lang: $left, skip: false} end) as $leftinfo |

(if $right == "" then
$leftinfo + {name: ""}
else
(if ($right | test("-f$")) then
$leftinfo + {name: ($right | sub("-f$"; "")), skip: true}
else
$leftinfo + {name: $right}
end)
end);

parse_cfg($currentcfg) as $rule |
.tracks |
map(. as $track |
(($lang == "any" or $lang == $track.language) as $lang_match |
($name == "" or (($track.name // "") | ascii_downcase | contains(($name // "") | ascii_downcase))) as $name_match |
select($track.type == $type and $lang_match and $name_match and .striptracks_keep)
(($rule.lang == "any" or $rule.lang == $track.language) as $lang_match |
($rule.name == "" or (($track.name // "") | ascii_downcase | contains(($rule.name // "") | ascii_downcase))) as $name_match |
($rule.skip and $track.forced) as $skipped |
select($track.type == $type and $lang_match and $name_match and ($skipped | not) and .striptracks_keep)
)
) |
.[0].id // ""
Expand All @@ -1620,7 +1654,7 @@ function set_default_tracks {

if [ -n "$striptracks_default_flags" ]; then
# Execute mkvpropedit to set default flags on tracks
local mkvcommand="/usr/bin/mkvpropedit -q $striptracks_default_flags \"$striptracks_video\""
local mkvcommand="/usr/bin/mkvpropedit -q $striptracks_default_flags \"$(escape_string "$striptracks_video")\""
execute_mkv_command "$mkvcommand" "setting default track flags"
fi
}
Expand All @@ -1637,7 +1671,7 @@ function set_title_and_exit_if_nothing_removed {
# Remuxing not performed
local message="Info|No tracks would be removed from video$( [ "$striptracks_reorder" = "true" ] && echo " or reordered"). Setting Title only and exiting."
echo "$message" | log
local mkvcommand="/usr/bin/mkvpropedit -q --edit info --set \"title=$striptracks_title\" \"$striptracks_video\""
local mkvcommand="/usr/bin/mkvpropedit -q --edit info --set \"title=$(escape_string "$striptracks_title")\" \"$(escape_string "$striptracks_video")\""
execute_mkv_command "$mkvcommand" "setting video title"
end_script
else
Expand Down Expand Up @@ -1672,7 +1706,7 @@ function remux_video {
fi

# Execute MKVmerge (remux then rename, see issue #46)
local mkvcommand="$striptracks_nice /usr/bin/mkvmerge --title \"$striptracks_title\" -q -o \"$striptracks_tempvideo\" $audioarg $subsarg $striptracks_neworder \"$striptracks_video\""
local mkvcommand="$striptracks_nice /usr/bin/mkvmerge --title \"$(escape_string "$striptracks_title")\" -q -o \"$(escape_string "$striptracks_tempvideo")\" $audioarg $subsarg $striptracks_neworder \"$(escape_string "$striptracks_video")\""
execute_mkv_command "$mkvcommand" "remuxing video"

# Check for non-empty file
Expand Down