diff --git a/.github/workflows/BuildImage.yml b/.github/workflows/BuildImage.yml index 6bc4ca2c..cd9ca4fc 100644 --- a/.github/workflows/BuildImage.yml +++ b/.github/workflows/BuildImage.yml @@ -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 diff --git a/README.md b/README.md index dfbd2e94..e7dc29b1 100644 --- a/README.md +++ b/README.md @@ -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} [{-s|--subs} ] [{-f|--file} ]] [--reorder] [--disable-recycle] [--skip-profile ]... [--set-default-audio ] [--set-default-subs ] +`striptracks.sh [{-a|--audio} [{-s|--subs} ] [{-f|--file} ]] [--reorder] [--disable-recycle] [--skip-profile ]... [--set-default-audio ] [--set-default-subs ] [{-l|--log} ] [{-c|--config} ] [{-p|--priority} {idle|low|medium|high}] [{-d|--debug} []]`
@@ -224,17 +224,17 @@ Option|Argument|Description `-a`, `--audio`|``|Audio languages to keep
ISO 639-2 code(s) prefixed with a colon (`:`)
Each code may optionally be followed by a plus (`+`) and one or more [modifiers](#language-code-modifiers). `-s`, `--subs`|``|Subtitle languages to keep
ISO 639-2 code(s) prefixed with a colon (`:`)
Each code may optionally be followed by a plus (`+`) and one or more modifiers. `-f`, `--file`|``|If included, the script enters **[Batch Mode](#batch-mode)** and converts the specified video file.
Requires the `--audio` option.
![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 `` and `` 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 `` and `` arguments. +`--disable-recycle`||Disable recycle bin use, even if configured in Radarr/Sonarr `--skip-profile`|``|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`|``|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.
The code may optionally be followed by an equals (`=`) and a [track name](#setting-default-track) matching string. -`--set-default-subs`|``|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.
The code may optionally be followed by an equals (`=`) and a track name string. +`--set-default-audio`|``|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.
The code may optionally be followed by an equals (`=`) and a [track name](#setting-default-track) matching string.
The code may optionally be followed by a minus f (`-f`) to indicate skipping Forced tracks. +`--set-default-subs`|``|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.
The code may optionally be followed by an equals (`=`) and a track name string.
The code may optionally be followed by a minus f (`-f`) to indicate skipping Forced tracks. `-l`, `--log`|``|The log filename
Default is `/config/log/striptracks.txt` `-c`, `--config`|``|Radarr/Sonarr XML configuration file
Default is `/config/config.xml` `-p`, `--priority`|`idle`, `low`, `medium`, `high`|CPU and I/O process priority for mkvmerge
Default is `medium`
![notes] High priority can consume all system resources. When processing a large video file your system may become unresponsive! `-d`, `--debug`|`[]`|Enables debug logging. Level is optional.
Default is `1` (low)
`2` includes JSON output
`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.
@@ -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. @@ -291,7 +295,7 @@ The setting of default track flags occurs after the track selection logic. > You may therefore not obtain consistent results.
-Track Name Examples +Default Track Examples If you want to set the default subtitles track to the first hearing impared English track, you would use: `--set-default-subs :eng=SDH` @@ -299,6 +303,9 @@ If you want to set the default subtitles track to the first hearing impared Engl 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` +
### Any language code @@ -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 ``` diff --git a/SECURITY.md b/SECURITY.md index 69d4e47c..c6a71dc6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -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 diff --git a/root/usr/local/bin/striptracks.sh b/root/usr/local/bin/striptracks.sh index 35bdc0e7..d496d962 100755 --- a/root/usr/local/bin/striptracks.sh +++ b/root/usr/local/bin/striptracks.sh @@ -122,7 +122,7 @@ mode. Source: https://github.com/TheCaptain989/radarr-striptracks Usage: - $0 [{-a|--audio} [{-s|--subs} ] [{-f|--file} ]] [--reorder] [--disable-recycle] [--skip-profile ]... [--set-default-audio ] [--set-default-subs ] [{-l|--log} ] [{-c|--config} ] [{-p|--priority} {idle|low|medium|high}] [{-d|--debug} []] + $0 [{-a|--audio} [{-s|--subs} ] [{-f|--file} ]] [--reorder] [--disable-recycle] [--skip-profile ]... [--set-default-audio ] [--set-default-subs ] [{-l|--log} ] [{-c|--config} ] [{-p|--priority} {idle|low|medium|high}] [{-d|--debug} []] Options can also be set via the STRIPTRACKS_ARGS environment variable. Command-line arguments override the environment variable. @@ -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 + --set-default-audio 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 + The code may optionally be followed by a + minus \`-f\` to indicate skipping Forced + tracks. + --set-default-subs 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 filename [default: /config/log/striptracks.txt] -c, --config Radarr/Sonarr XML configuration file @@ -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 @@ -1047,6 +1054,16 @@ 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 @@ -1054,7 +1071,7 @@ function execute_mkv_command { 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) @@ -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 @@ -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 // "" @@ -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 } @@ -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 @@ -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