diff options
| -rw-r--r-- | README.md | 59 | ||||
| -rwxr-xr-x | transcode.sh | 282 | ||||
| -rw-r--r-- | transcode.sh.1 | 98 | ||||
| -rw-r--r-- | transcode.sh.bash-completion | 28 |
4 files changed, 409 insertions, 58 deletions
@@ -33,6 +33,7 @@ replaces the original atomically on success. | `ffprobe` | always | codec/format detection | | `nice` | always | process priority control | | `bc` | only with `--saving` | percentage calculation | +| `tomlq` | only when `config.toml` is present | TOML config parsing | ## Installation @@ -114,22 +115,56 @@ ffargs=( > **Security:** presets are executed as shell code. Only use presets from > trusted sources. -### Codec skip list +### Configuration file -To permanently skip files that are already in a particular codec, add codec -names (one per line) to: +An optional TOML configuration file can be placed at: ``` -${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/skip.conf +${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/config.toml ``` -**Example — skip files already encoded as AV1 or HEVC:** +Use `--config-file FILE` to load an alternative path. CLI flags always take +precedence over values in the config file. The file must be valid TOML — an +unparseable file is a hard error. Requires `tomlq` when the file is present. -``` -av1 -hevc +**Example `config.toml`:** + +```toml +[encoding] +preset = "av1" +nice = 10 + +[skip] +codecs = ["av1", "hevc"] + +[saving] +enabled = true +file = "transcode_savings" + +[output] +verbose = false +quiet = false ``` +| Section | Key | Type | CLI equivalent | +|---------|-----|------|----------------| +| `[encoding]` | `preset` | string | `-p` | +| `[encoding]` | `nice` | integer | `-N` | +| `[skip]` | `codecs` | array of strings | `-S` (merged with CLI) | +| `[saving]` | `enabled` | boolean | `-s` | +| `[saving]` | `file` | string | `--saving-file` | +| `[output]` | `verbose` | boolean | `-v` | +| `[output]` | `quiet` | boolean | `-q` | + +> **Note:** `[skip] codecs` from the config file and `--skip-codec` from the +> CLI are **merged** — both sources contribute to the skip list. + +### Codec skip list (deprecated) + +The legacy `skip.conf` file is no longer read. If it still exists, a +deprecation warning is printed at startup. Migrate its contents to +`[skip] codecs` in `config.toml` and delete the old file. + ## Usage ``` @@ -139,13 +174,16 @@ transcode.sh [OPTION] [--] FILE... | Option | Description | |--------|-------------| | `-c`, `--continue` | Continue to next file if ffmpeg fails | -| `-f PATH`, `--encodefile PATH`, `--encodefile=PATH` | Read file list from PATH (one per line) | +| `--no-continue` | Do not continue with the next file if ffmpeg fails | +| `--config-file FILE`, `--config-file=FILE` | Load configuration from FILE instead of the default path | +| `-f PATH`, `--encode-file PATH`, `--encodefile=PATH` | Read file list from PATH (one per line) | | `-n`, `--dry-run` | Show what would be done; don't run ffmpeg | | `-N VALUE`, `--nice VALUE`, `--nice=VALUE` | Niceness value for ffmpeg (default: 19) | | `-s`, `--saving` | Log filesize savings after each encode | | `--saving-file PATH`, `--saving-file=PATH` | Savings log path (default: `transcode_savings`) | | `-S LIST`, `--skip-codec LIST`, `--skip-codec=LIST` | Codecs to skip (comma/space/colon separated) | | `-l`, `--only-if-smaller` | Only replace original if new file is smaller | +| `--no-only-if-smaller` | Do replace original even if new file is bigger | | `-p NAME`, `--preset NAME`, `--preset=NAME` | Preset to use (default: `default`) | | `-q`, `--quiet` | Suppress all output (overrides `-v`) | | `-v`, `--verbose` | More detailed output | @@ -170,6 +208,9 @@ transcode.sh --preset av1_fast --only-if-smaller --skip-codec av1 /media/films/* # Run at a moderate priority and continue past failures transcode.sh --nice 10 --continue *.mp4 + +# Load an alternative config file +transcode.sh --config-file ~/profiles/fast.toml input.mp4 ``` ## Debugging diff --git a/transcode.sh b/transcode.sh index 61ecc5e..092fbb9 100755 --- a/transcode.sh +++ b/transcode.sh @@ -23,8 +23,28 @@ # # Note: Presets are sourced as shell code. Only use trusted presets. # -# A per-user list of video-codecs to skip can be provided in: -# ${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/skip.conf +# An optional TOML configuration file may be placed at: +# ${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/config.toml +# +# It may set defaults for any option, for example: +# [encoding] +# preset = "av1" +# nice = 10 +# +# [skip] +# codecs = ["av1", "hevc"] +# +# [saving] +# enabled = false +# file = "transcode_savings" +# +# CLI flags always take precedence over config file values. +# Requires tomlq (https://github.com/nicowillis/tomlq) when config.toml +# is present. +# +# NOTE: skip.conf is deprecated. If it exists alongside config.toml the +# script will warn and ignore it. Migrate codecs to [skip] codecs in +# config.toml. # # NOTES # This script respects the NO_COLOR standard (https://no-color.org/). @@ -130,8 +150,22 @@ REMAINING_ARGS=() TMP_FILES=() readonly PRESET_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/presets" +CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/config.toml" +# Kept for deprecation warning only — no longer read for codec data. readonly SKIP_CODECS_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/skip.conf" +# Sentinel flags: set to 1 by the CLI option parser so that load_config() +# knows which values have already been provided and must not be overridden. +_CLI_CONFIG_FILE=0 +_CLI_PRESET=0 +_CLI_NICE=0 +_CLI_ONLY_IF_SMALLER=0 +_CLI_CONTINUE=0 +_CLI_SAVING=0 +_CLI_SAVING_FILE=0 +_CLI_QUIET=0 +_CLI_VERBOSE=0 + ############################################################################### # EXIT CODES ############################################################################### @@ -201,10 +235,13 @@ ${BOLD}${BLUE}Encoding options:${ALL_OFF} ${BOLD}${YELLOW}-N, --nice${ALL_OFF} ${BOLD}${GREEN}VALUE${ALL_OFF} nice value for ffmpeg (default: ${BOLD}${RED}%d${ALL_OFF}) ${BOLD}${YELLOW}-n, --dry-run${ALL_OFF} show what would be done, do not run ffmpeg ${BOLD}${YELLOW}-l, --only-if-smaller${ALL_OFF} only replace original if new file is smaller + ${BOLD}${YELLOW}--no-only-if-smaller${ALL_OFF} do replace original even if new file is bigger ${BOLD}${YELLOW}-c, --continue${ALL_OFF} continue with the next file even if ffmpeg fails + ${BOLD}${YELLOW}--no-continue${ALL_OFF} do not continue with the next file if ffmpeg fails ${BOLD}${BLUE}Input options:${ALL_OFF} - ${BOLD}${YELLOW}-f, --encodefile${ALL_OFF} ${BOLD}${GREEN}FILE${ALL_OFF} file containing a list of files to encode + ${BOLD}${YELLOW}--config-file${ALL_OFF} ${BOLD}${GREEN}FILE${ALL_OFF} load configuration from FILE instead of the default path + ${BOLD}${YELLOW}-f, --encode-file${ALL_OFF} ${BOLD}${GREEN}FILE${ALL_OFF} file containing a list of files to encode ${BOLD}${YELLOW}-S, --skip-codec${ALL_OFF} ${BOLD}${GREEN}LIST${ALL_OFF} skip files with these codecs; ${BOLD}${GREEN}LIST${ALL_OFF} is comma, space, or colon separated @@ -224,20 +261,18 @@ ${BOLD}${BLUE}General options:${ALL_OFF} ${BOLD}${BLUE}Configuration files:${ALL_OFF} ${BOLD}${CYAN}%s/<NAME>.sh${ALL_OFF} - preset file; must define a bash array ${BOLD}${GREEN}ffargs${ALL_OFF} with - the ffmpeg encoding arguments. the following - variables are available to presets: - ${BOLD}${GREEN}input_codec${ALL_OFF} e.g. h264, hevc - ${BOLD}${GREEN}input_pixel_format${ALL_OFF} e.g. yuv420p - ${BOLD}${GREEN}output_pixel_format${ALL_OFF} derived from input - presets are sourced as shell code; only use - trusted presets from trusted directories. + preset file; must define a bash array ${BOLD}${GREEN}ffargs${ALL_OFF} with the ffmpeg encoding arguments. + the following variables are available to presets: + ${BOLD}${GREEN}input_codec${ALL_OFF} e.g. h264, hevc + ${BOLD}${GREEN}input_pixel_format${ALL_OFF} e.g. yuv420p + ${BOLD}${GREEN}output_pixel_format${ALL_OFF} derived from input + + ${BOLD}${RED}presets are sourced as shell code; only use trusted presets from trusted + directories.${ALL_OFF} ${BOLD}${CYAN}%s${ALL_OFF} - skip file; one codec name per line, lines - starting with ${BOLD}${YELLOW}#${ALL_OFF} are treated as comments. - codecs listed here are skipped in addition to - any codecs passed via ${BOLD}${YELLOW}--skip-codec${ALL_OFF}. + Use ${BOLD}${YELLOW}--config-file${ALL_OFF} ${BOLD}${GREEN}FILE${ALL_OFF} to load an alternative path. + CLI flags always take precedence. Requires ${BOLD}tomlq${ALL_OFF} when the file is present. ${BOLD}${BLUE}Examples:${ALL_OFF} %s video.mp4 @@ -246,7 +281,7 @@ ${BOLD}${BLUE}Examples:${ALL_OFF} "$SCRIPTNAME" "$VERSION" "$DESCRIPTION" \ "$SCRIPTNAME" \ "$PRESET_NAME" "$NICE_VALUE" "$SAVING_FILE" \ - "$PRESET_DIR" "$SKIP_CODECS_FILE" \ + "$PRESET_DIR" "$CONFIG_FILE" \ "$SCRIPTNAME" "$SCRIPTNAME" "$SCRIPTNAME" } @@ -365,6 +400,129 @@ setup_colors # MAIN EXECUTION ############################################################################### +############################################################################### +# CONFIGURATION FILE +# +# Load defaults from config.toml if it exists. Values are only applied when +# the corresponding CLI flag has NOT already been set (CLI takes precedence). +# Requires tomlq when config.toml is present. +############################################################################### + +# Query a single scalar value from config.toml via tomlq. +# Usage: _tomlq_get <key> (e.g. ".encoding.preset") +# Outputs the raw string on stdout; returns non-zero if the key is absent +# or tomlq fails for any reason. +_tomlq_get() { + tomlq -r "$1" "$CONFIG_FILE" 2>/dev/null +} + +# Load configuration from config.toml, respecting CLI precedence. +# Called once, after option parsing, so all _CLI_* sentinels are already set. +load_config() { + # Warn about the legacy skip.conf here (not at startup) so --quiet is + # respected; by this point the CLI has been fully parsed. + if [[ -f "$SKIP_CODECS_FILE" ]]; then + warn "skip.conf is deprecated." "Migrate codecs to [skip] codecs in config.toml and remove $SKIP_CODECS_FILE" + fi + + # We use -r and not -f to allow things like /dev/null + [[ -r "$CONFIG_FILE" ]] || { + if [[ $_CLI_CONFIG_FILE -eq 1 ]]; then + error "Config file not found:" "$CONFIG_FILE" + exit $EXIT_CONFIG_ERROR + fi + return 0 + } + + command -v tomlq >/dev/null 2>&1 || { + error "tomlq not found but $CONFIG_FILE exists. Install tomlq or remove the config file." + exit $EXIT_MISSING_DEPENDENCY + } + + # Validate that the config file is well-formed TOML before reading any keys. + # tomlq exits non-zero and prints to stderr if the file cannot be parsed. + if ! tomlq '.' "$CONFIG_FILE" >/dev/null 2>&1; then + error "Config file is not valid TOML:" "$CONFIG_FILE" + exit $EXIT_CONFIG_ERROR + fi + + debug "Loading config file:" "$CONFIG_FILE" + + local val + + # [encoding] preset + if [[ $_CLI_PRESET -eq 0 ]]; then + val=$(_tomlq_get '.encoding.preset // empty') && [[ -n "$val" ]] && { + debug "Config: preset =" "$val" + PRESET_NAME="$val" + } + fi + + # [encoding] nice + if [[ $_CLI_NICE -eq 0 ]]; then + val=$(_tomlq_get '.encoding.nice // empty') && [[ -n "$val" ]] && { + debug "Config: nice =" "$val" + NICE_VALUE="$val" + } + fi + + # [encoding] only_if_smaller + if [[ $_CLI_ONLY_IF_SMALLER -eq 0 ]]; then + val=$(_tomlq_get '.encoding.only_if_smaller // empty') && [[ -n "$val" ]] && { + debug "Config: encoding.only_if_smaller =" "$val" + [[ "$val" == "true" ]] && ONLY_IF_SMALLER=1 || ONLY_IF_SMALLER=0 + } + fi + + # [encoding] continue + if [[ $_CLI_CONTINUE -eq 0 ]]; then + val=$(_tomlq_get '.encoding.continue // empty') && [[ -n "$val" ]] && { + debug "Config: encoding.continue =" "$val" + [[ "$val" == "true" ]] && CONTINUE_ON_FAIL=1 || CONTINUE_ON_FAIL=0 + } + fi + + # [skip] codecs (TOML array → one element per line via tomlq -r '.skip.codecs[]') + # CLI --skip-codec entries are additive, so we always load config codecs + # regardless of _CLI_SKIP_CODEC. Both sources merge into SKIP_CODECS. + local codec + while IFS= read -r codec; do + [[ -n "$codec" ]] && add_skip_codec_token "$codec" + done < <(tomlq -r '.skip.codecs[]?' "$CONFIG_FILE" 2>/dev/null) + + # [saving] enabled + if [[ $_CLI_SAVING -eq 0 ]]; then + val=$(_tomlq_get '.saving.enabled // empty') && [[ -n "$val" ]] && { + debug "Config: saving.enabled =" "$val" + [[ "$val" == "true" ]] && SAVING=1 || SAVING=0 + } + fi + + # [saving] file + if [[ $_CLI_SAVING_FILE -eq 0 ]]; then + val=$(_tomlq_get '.saving.file // empty') && [[ -n "$val" ]] && { + debug "Config: saving.file =" "$val" + SAVING_FILE="$val" + } + fi + + # [output] verbose + if [[ $_CLI_VERBOSE -eq 0 ]]; then + val=$(_tomlq_get '.output.verbose // empty') && [[ -n "$val" ]] && { + debug "Config: output.verbose =" "$val" + [[ "$val" == "true" ]] && VERBOSE=1 || VERBOSE=0 + } + fi + + # [output] quiet + if [[ $_CLI_QUIET -eq 0 ]]; then + val=$(_tomlq_get '.output.quiet // empty') && [[ -n "$val" ]] && { + debug "Config: output.quiet =" "$val" + [[ "$val" == "true" ]] && QUIET=1 || QUIET=0 + } + fi +} + # Add a codec name to the SKIP_CODECS associative array. # - Normalizes to lowercase # - Ignores empty tokens @@ -390,13 +548,6 @@ parse_skip_codec_parameter() { done } -if [[ -f "$SKIP_CODECS_FILE" ]]; then - while read -r line || [[ -n "$line" ]]; do - [[ -z "$line" || "${line:0:1}" == "#" ]] && continue - parse_skip_codec_parameter "$line" - done <"$SKIP_CODECS_FILE" -fi - # Load ffmpeg argument preset by name. # # Security: @@ -434,8 +585,10 @@ load_preset() { # readlink -f (GNU) with a fallback to realpath for macOS/BSD. local resolved_file resolved_file=$(readlink -f -- "$file" 2>/dev/null || realpath -- "$file") + local preset_perms preset_perms=$(stat -c '%a' -- "$resolved_file" 2>/dev/null || stat -f '%OLp' -- "$resolved_file") + if [[ "${preset_perms: -1}" =~ [2367] ]]; then error "Preset file is world-writable, refusing to source:" "$resolved_file" exit $EXIT_CONFIG_ERROR @@ -476,10 +629,12 @@ while [[ $# -gt 0 ]]; do ;; -q | --quiet) QUIET=1 + _CLI_QUIET=1 shift ;; -v | --verbose) VERBOSE=1 + _CLI_VERBOSE=1 shift ;; --color) @@ -494,9 +649,42 @@ while [[ $# -gt 0 ]]; do ;; -c | --continue) CONTINUE_ON_FAIL=1 + _CLI_CONTINUE=1 + shift + ;; + --no-continue) + CONTINUE_ON_FAIL=0 + _CLI_CONTINUE=1 + shift + ;; + --config-file) + [[ $# -ge 2 ]] || { + error "Missing value for $1" + exit $EXIT_USAGE_ERROR + } + [[ -n "$2" ]] || { + error "Value for $1 must not be empty" + exit $EXIT_USAGE_ERROR + } + CONFIG_FILE="$2" + _CLI_CONFIG_FILE=1 + shift 2 + ;; + --config-file=*) + [[ -n "${1#*=}" ]] || { + error "Value for --config-file must not be empty" + exit $EXIT_USAGE_ERROR + } + CONFIG_FILE="${1#*=}" + _CLI_CONFIG_FILE=1 + shift + ;; + --no-config) + CONFIG_FILE="/dev/null" + _CLI_CONFIG_FILE=1 shift ;; - -f | --encodefile) + -f | --encode-file) [[ $# -ge 2 ]] || { error "Missing value for $1" exit $EXIT_USAGE_ERROR @@ -508,9 +696,9 @@ while [[ $# -gt 0 ]]; do ENCODE_FILE="$2" shift 2 ;; - --encodefile=*) + --encode-file=*) [[ -n "${1#*=}" ]] || { - error "Value for --encodefile must not be empty" + error "Value for --encode-file must not be empty" exit $EXIT_USAGE_ERROR } ENCODE_FILE="${1#*=}" @@ -526,14 +714,22 @@ while [[ $# -gt 0 ]]; do exit $EXIT_USAGE_ERROR } NICE_VALUE="$2" + _CLI_NICE=1 shift 2 ;; --nice=*) NICE_VALUE="${1#*=}" + _CLI_NICE=1 shift ;; -s | --saving) SAVING=1 + _CLI_SAVING=1 + shift + ;; + --no-saving) + SAVING=0 + _CLI_SAVING=1 shift ;; --saving-file) @@ -547,6 +743,7 @@ while [[ $# -gt 0 ]]; do } SAVING_FILE="$2" SAVING_FILE_EXPLICIT=1 + _CLI_SAVING_FILE=1 shift 2 ;; --saving-file=*) @@ -556,6 +753,7 @@ while [[ $# -gt 0 ]]; do } SAVING_FILE="${1#*=}" SAVING_FILE_EXPLICIT=1 + _CLI_SAVING_FILE=1 shift ;; -S | --skip-codec) @@ -572,6 +770,12 @@ while [[ $# -gt 0 ]]; do ;; -l | --only-if-smaller) ONLY_IF_SMALLER=1 + _CLI_ONLY_IF_SMALLER=1 + shift + ;; + --no-only-if-smaller) + ONLY_IF_SMALLER=0 + _CLI_ONLY_IF_SMALLER=1 shift ;; -p | --preset) @@ -584,6 +788,7 @@ while [[ $# -gt 0 ]]; do exit $EXIT_USAGE_ERROR } PRESET_NAME="$2" + _CLI_PRESET=1 shift 2 ;; --preset=*) @@ -592,10 +797,12 @@ while [[ $# -gt 0 ]]; do exit $EXIT_USAGE_ERROR } PRESET_NAME="${1#*=}" + _CLI_PRESET=1 shift ;; --) shift + REMAINING_ARGS+=("$@") break ;; -*) @@ -609,6 +816,25 @@ while [[ $# -gt 0 ]]; do esac done +# Apply config file defaults. Must run after CLI parsing so _CLI_* sentinels +# are set, but before validation so config-supplied values are validated too. +load_config + +printf -v joined ' %s' "${!SKIP_CODECS[@]}" + +debug "Effective configuration:" +debug " preset:" "$PRESET_NAME" +debug " nice:" "$NICE_VALUE" +debug " dry-run:" "$DRY_RUN" +debug " only-if-smaller:" "$ONLY_IF_SMALLER" +debug " saving:" "$SAVING" +debug " saving-file:" "$SAVING_FILE" +debug " skip-codecs:" "${joined# }" +debug " verbose:" "$VERBOSE" +debug " quiet:" "$QUIET" +debug " config-file:" "$CONFIG_FILE" +debug " encode-file:" "$ENCODE_FILE" + command -v ffmpeg >/dev/null 2>&1 || { error "ffmpeg not found." exit $EXIT_MISSING_DEPENDENCY @@ -640,10 +866,10 @@ if [[ ! "$NICE_VALUE" =~ ^-?[0-9]+$ ]] || ((NICE_VALUE < -20 || NICE_VALUE > 19) exit $EXIT_USAGE_ERROR fi -if [[ ${#SKIP_CODECS[@]} -gt 0 ]]; then - printf -v joined ' %s' "${!SKIP_CODECS[@]}" +if [[ ! -z "${joined# }" ]]; then verbose "Skipping files with codecs:" "${joined# }" fi +unset joined # Remove temporary output files created during encoding. # Registered via trap EXIT so it runs on normal exit and on failures diff --git a/transcode.sh.1 b/transcode.sh.1 index a22b802..bcbc0fb 100644 --- a/transcode.sh.1 +++ b/transcode.sh.1 @@ -42,7 +42,21 @@ Continue processing the next file even if fails on the current one. Without this flag the script exits immediately on the first failure. .TP -.BR \-f " \fIPATH\fR, " \-\-encodefile " \fIPATH\fR, " \-\-encodefile= \fIPATH\fR +.BR \-\-no\-continue +Do not continue processing next file even if +.BR ffmpeg (1) +fails on the current one. +.TP +.BR \-\-config\-file " \fIPATH\fR, " \-\-config\-file= \fIPATH\fR +Load configuration from \fIPATH\fR instead of the default location +.RI ( ${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/config.toml ). +If the specified file does not exist the script exits with a configuration +error. CLI flags always take precedence over values in the config file. +Requires +.BR tomlq (1) +when the file is present. +.TP +.BR \-f " \fIPATH\fR, " \-\-encode-file " \fIPATH\fR, " \-\-encode-file= \fIPATH\fR Read the list of files to encode from \fIPATH\fR (one file per line) instead of taking files from the command line. .TP @@ -78,17 +92,20 @@ in the current working directory. .BR \-S " \fILIST\fR, " \-\-skip\-codec " \fILIST\fR, " \-\-skip\-codec= \fILIST\fR Comma-, space- or colon-separated list of video codec names to skip. Files whose detected input codec appears in this list are left untouched. -The per-user skip list from -.B skip.conf -(see -.BR FILES ) -is always loaded in addition to codecs supplied here. +Codecs specified here are merged with any codecs listed under +.B [skip] codecs +in +.B config.toml +\(em both sources contribute to the skip list. .TP .BR \-l ", " \-\-only\-if\-smaller After encoding, replace the original only when the new file is strictly smaller. If the transcoded file is larger the temporary file is removed and the original is kept unchanged. .TP +.BR \-\-no\-only\-if\-smaller +After encoding, replace the original also if the new file is bigger. +.TP .BR \-p " \fINAME\fR, " \-\-preset " \fINAME\fR, " \-\-preset= \fINAME\fR Load the preset named \fINAME\fR from the preset directory. Defaults to .BR default . @@ -134,6 +151,8 @@ or terminal detection. Set to .B 1 to enable structured debug messages (high-level state reporting). +After configuration loading, a summary of all effective option values +is printed. .TP .B TRACE Set to @@ -207,12 +226,51 @@ ffargs=( \-c:v:0 libsvtav1 \-crf 30 \-preset 6 \-pix_fmt "$output_pixel_format" presets are executed as shell code. Only use presets from trusted sources. .TP +.IR "${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/config.toml" +Optional TOML configuration file. Provides defaults for all options. +CLI flags always take precedence. The file must be valid TOML; an +unparseable file is a hard error. Requires +.BR tomlq (1). +Supported sections and keys: +.RS +.TP +.B [encoding] preset +String. Default preset name. Equivalent to +.BR \-p . +.TP +.B [encoding] nice +Integer. Default niceness value. Equivalent to +.BR \-N . +.TP +.B [skip] codecs +Array of strings. Merged with any codecs from +.BR \-S . +.TP +.B [saving] enabled +Boolean. Equivalent to +.BR \-s . +.TP +.B [saving] file +String. Equivalent to +.BR \-\-saving\-file . +.TP +.B [output] verbose +Boolean. Equivalent to +.BR \-v . +.TP +.B [output] quiet +Boolean. Equivalent to +.BR \-q . +.RE +.TP .IR "${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/skip.conf" -Optional per-user codec skip list. Each line should contain one codec -name (as reported by -.BR ffprobe (1)). -Files whose input video codec matches an entry are skipped without -encoding. +.B Deprecated. +This file is no longer read. If it exists, a warning is printed. +Migrate its contents to +.B [skip] codecs +in +.B config.toml +and delete the file. .SH EXIT STATUS .TP .B 0 @@ -234,11 +292,14 @@ A required dependency .RB ( ffmpeg , .BR ffprobe , .BR nice , -or .B bc when .B \-\-saving -is active) was not found. +is active, or +.B tomlq +when +.B config.toml +is present) was not found. .SH EXAMPLES Transcode a single file using the default preset: .PP @@ -280,6 +341,14 @@ transcode.sh \-N 10 \-S av1 input.mkv .fi .RE .PP +Load an alternative configuration file: +.PP +.RS +.nf +transcode.sh \-\-config\-file ~/profiles/fast.toml input.mp4 +.fi +.RE +.PP Use .BR ffmpeg (1) installed via Homebrew (macOS): @@ -305,7 +374,8 @@ before invoking .BR ffmpeg (1), .BR ffprobe (1), .BR nice (1), -.BR bc (1) +.BR bc (1), +.BR tomlq (1) .SH AUTHOR Dennis Fink <dennis.fink@c3l.lu> .SH LICENSE diff --git a/transcode.sh.bash-completion b/transcode.sh.bash-completion index ce153dd..59a9c8d 100644 --- a/transcode.sh.bash-completion +++ b/transcode.sh.bash-completion @@ -6,8 +6,8 @@ # # Each option that takes an argument is supported in all three forms: # short -f list.txt -# long space --encodefile list.txt -# long equals --encodefile=list.txt +# long space --encode-file list.txt +# long equals --encode-file=list.txt _transcode_sh() { local cur prev words cword @@ -40,7 +40,12 @@ _transcode_sh() { # This must be checked before the $prev dispatch below. # --------------------------------------------------------------------------- case "$cur" in - --encodefile=*) + --config-file=*) + cur="${cur#*=}" + _filedir + return + ;; + --encode-file=*) cur="${cur#*=}" _filedir return @@ -69,11 +74,15 @@ _transcode_sh() { # --------------------------------------------------------------------------- # Handle VALUE after short form (-f, -N, -S, -p) and - # long space form (--encodefile, --nice, --saving-file, --skip-codec, --preset). + # long space form (--encode-file, --nice, --saving-file, --skip-codec, --preset). # $prev is the option word, $cur is the value being typed. # --------------------------------------------------------------------------- case "$prev" in - -f|--encodefile) + --config-file) + _filedir + return + ;; + -f|--encode-file) _filedir return ;; @@ -106,17 +115,22 @@ _transcode_sh() { --*) local longopts=' --continue - --encodefile - --encodefile= + --no-continue + --config-file + --config-file= + --encode-file + --encode-file= --dry-run --nice --nice= --saving + --no-saving --saving-file --saving-file= --skip-codec --skip-codec= --only-if-smaller + --no-only-if-smaller --preset --preset= --help |
