aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--README.md84
-rwxr-xr-xtranscode.sh345
-rw-r--r--transcode.sh.1160
-rw-r--r--transcode.sh.bash-completion.sh119
4 files changed, 378 insertions, 330 deletions
diff --git a/README.md b/README.md
index 5a3119c..53678cf 100644
--- a/README.md
+++ b/README.md
@@ -153,11 +153,12 @@ An optional TOML configuration file can be placed at:
${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/config.toml
```
-Use `--config-file FILE` to load an alternative path. CLI flags generally take
-precedence over values in the config file. Skip codecs are additive by default:
-configured codecs and CLI codecs are merged unless `--skip-codec-override` is
-used. The file must be valid TOML — an unparseable file is a hard error.
-Requires `tomlq` when the file is present.
+Use `--config-file FILE` to load an alternative path, or `--no-config` to skip
+configuration loading entirely. CLI flags generally take precedence over values
+in the config file. Skip codecs are additive by default: configured codecs and
+CLI codecs are merged unless `--skip-codec-override` is used. The file must be
+valid TOML — an unparseable file is a hard error. Requires `tomlq` when the
+file is present.
**Example `config.toml`:**
@@ -182,18 +183,18 @@ quiet = false
| Section | Key | Type | CLI equivalent |
|---------|-----|------|----------------|
-| `[encoding]` | `backup_dir` | string | `--backup-dir` |
-| `[encoding]` | `hwaccel` | string or boolean | `--hwaccel` / `--no-hwaccel` |
-| `[encoding]` | `nice` | integer | `-N` |
| `[encoding]` | `preset` | string | `-p` |
-| `[encoding]` | `verify_output` | boolean | `--verify-output` |
+| `[encoding]` | `nice` | integer | `-N` |
+| `[encoding]` | `hwaccel` | string or boolean | `--hwaccel` / `--no-hwaccel` |
| `[encoding]` | `video_stream` | string | `--video-stream` |
-| `[output]` | `quiet` | boolean | `-q` |
-| `[output]` | `verbose` | boolean | `-v` |
-| `[output]` | `ffmpeg_loglevel` | string | `--ffmpeg-loglevel` |
+| `[encoding]` | `backup_dir` | string | `--backup-dir` |
+| `[encoding]` | `verify_output` | boolean | `--verify-output` |
+| `[skip]` | `codecs` | array of strings | `-S` / `--skip-codec-override` |
| `[size_report]` | `enabled` | boolean | `-s` / `--no-size-report` |
| `[size_report]` | `file` | string | `--size-report-file` |
-| `[skip]` | `codecs` | array of strings | `-S` / `--skip-codec-override` |
+| `[output]` | `ffmpeg_loglevel` | string | `--ffmpeg-loglevel` |
+| `[output]` | `quiet` | boolean | `-q` |
+| `[output]` | `verbose` | boolean | `-v` |
> **Note:** `[skip] codecs` from the config file and `--skip-codec` from the
> CLI are **merged** by default — both sources contribute to the skip list. Use
@@ -225,35 +226,68 @@ deprecation warning is printed at startup. Migrate its contents to
transcode.sh [OPTION] [--] FILE...
```
+### Input options
+
| Option | Description |
|--------|-------------|
-| `-c`, `--continue` | Continue to next file if ffmpeg fails |
-| `--no-continue` | Do not continue with the next file if ffmpeg fails |
-| `--verify-output` | Probe output with ffprobe before replacing original (default) |
-| `--no-verify-output` | Skip the post-encode integrity check |
| `--config-file FILE`, `--config-file=FILE` | Load configuration from FILE instead of the default path |
+| `--no-config` | Do not load any configuration file |
| `-f PATH`, `--encode-file PATH`, `--encode-file=PATH` | Read file list from PATH (one per line) |
-| `-n`, `--dry-run` | Show what would be done; don't run ffmpeg |
-| `--backup-dir DIR`, `--backup-dir=DIR` | Copy originals to an existing backup directory before replacing them |
+
+### Encoding options
+
+| Option | Description |
+|--------|-------------|
+| `-p NAME`, `--preset NAME`, `--preset=NAME` | Preset to use (default: `default`) |
| `-N VALUE`, `--nice VALUE`, `--nice=VALUE` | Nice adjustment for ffmpeg (default: 19) |
| `--hwaccel [METHOD]`, `--hwaccel=METHOD` | Enable hardware acceleration; METHOD defaults to `auto` if omitted (e.g. `cuda`, `vaapi`, `videotoolbox`); enabled by default |
| `--no-hwaccel` | Disable hardware acceleration (omit `-hwaccel` from ffmpeg invocation) |
-| `-s`, `--size-report` | Print per-file size feedback and write a status TSV log |
-| `--no-size-report` | Disable a size report enabled in `config.toml` |
-| `--size-report-file PATH`, `--size-report-file=PATH` | Size report TSV path (default: `transcode_size_report`) |
+| `--video-stream STREAM_SELECTOR`, `--video-stream=STREAM_SELECTOR` | Select the input video stream to probe for preset helper variables, e.g. `v:0` or `v:1` (default: `v:0`) |
+
+### Skip options
+
+| Option | Description |
+|--------|-------------|
| `-S LIST`, `--skip-codec LIST`, `--skip-codec=LIST` | Add codecs to the effective skip list (comma/space/colon separated) |
| `--skip-codec-override` | Use only codecs from `--skip-codec`, ignoring `[skip].codecs` from config |
+
+### Processing options
+
+| Option | Description |
+|--------|-------------|
+| `-n`, `--dry-run` | Show what would be done; don't run ffmpeg |
+| `--backup-dir DIR`, `--backup-dir=DIR` | Copy originals to an existing backup directory before replacing them |
| `-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`) |
-| `--video-stream STREAM_SELECTOR`, `--video-stream=STREAM_SELECTOR` | Select the input video stream to probe for preset helper variables, e.g. `v:0` or `v:1` (default: `v:0`) |
+| `--verify-output` | Probe output with ffprobe before replacing original (default) |
+| `--no-verify-output` | Skip the post-encode integrity check |
+| `-c`, `--continue` | Continue to next file if ffmpeg fails |
+| `--no-continue` | Do not continue with the next file if ffmpeg fails |
+
+### Size report options
+
+| Option | Description |
+|--------|-------------|
+| `-s`, `--size-report` | Print per-file size feedback and write a status TSV log |
+| `--no-size-report` | Disable a size report enabled in config |
+| `--size-report-file PATH`, `--size-report-file=PATH` | Size report TSV path (default: `transcode_size_report`) |
+
+### Display options
+
+| Option | Description |
+|--------|-------------|
| `--ffmpeg-loglevel LEVEL`, `--ffmpeg-loglevel=LEVEL` | Specify the loglevel to pass to ffmpeg (default: `fatal`) |
| `-q`, `--quiet` | Suppress all output (overrides `-v`) |
| `-v`, `--verbose` | More detailed output |
| `--color` / `--no-color` | Force or disable colored output |
+
+### General options
+
+| Option | Description |
+|--------|-------------|
+| `-h`, `-?`, `--help` | Show help and exit |
| `--version` | Print version information |
| `--list-presets` | List available presets (name + description) and exit |
-| `-h`, `-?`, `--help` | Show help and exit |
### Examples
diff --git a/transcode.sh b/transcode.sh
index b9aee8b..fe18b0d 100755
--- a/transcode.sh
+++ b/transcode.sh
@@ -285,37 +285,39 @@ ${BOLD}${BLUE}Usage:${ALL_OFF} ${BOLD}${MAGENTA}%s${ALL_OFF} ${BOLD}${YELLOW}[OP
Long options that take a value also accept ${BOLD}${YELLOW}--option${ALL_OFF}${BOLD}${CYAN}=${ALL_OFF}${BOLD}${GREEN}VALUE${ALL_OFF} syntax.
+${BOLD}${BLUE}Input options:${ALL_OFF}
+ ${BOLD}${YELLOW}--config-file${ALL_OFF} ${BOLD}${GREEN}FILE${ALL_OFF} load configuration from FILE instead of the default path
+ ${BOLD}${YELLOW}--no-config${ALL_OFF} do not load any configuration file
+ ${BOLD}${YELLOW}-f, --encode-file${ALL_OFF} ${BOLD}${GREEN}FILE${ALL_OFF} file containing a list of files to encode
+
${BOLD}${BLUE}Encoding options:${ALL_OFF}
${BOLD}${YELLOW}-p, --preset${ALL_OFF} ${BOLD}${GREEN}NAME${ALL_OFF} load ffmpeg arguments from a preset (default: ${BOLD}${RED}%s${ALL_OFF})
${BOLD}${YELLOW}-N, --nice${ALL_OFF} ${BOLD}${GREEN}VALUE${ALL_OFF} nice adjustment 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} --backup-dir${ALL_OFF} ${BOLD}${GREEN}DIR${ALL_OFF} backup original files to DIR instead of overwriting them
- ${BOLD}${YELLOW}--hwaccel${ALL_OFF} ${BOLD}${GREEN}[METHOD]${ALL_OFF} enable hardware acceleration; METHOD defaults to ${BOLD}${RED}%s${ALL_OFF}
- if omitted
+ ${BOLD}${YELLOW}--hwaccel${ALL_OFF} ${BOLD}${GREEN}[METHOD]${ALL_OFF} enable hardware acceleration; METHOD defaults to ${BOLD}${RED}%s${ALL_OFF} if omitted
+ ${BOLD}${YELLOW}--no-hwaccel${ALL_OFF} disable hardware acceleration (do not pass ${BOLD}${YELLOW}-hwaccel${ALL_OFF} to ffmpeg)
${BOLD}${YELLOW}--video-stream${ALL_OFF} ${BOLD}${GREEN}STREAM_SELECTOR${ALL_OFF} video stream to probe for preset helper variables (default: ${BOLD}${RED}%s${ALL_OFF})
- ${BOLD}${YELLOW} --no-hwaccel${ALL_OFF} disable hardware acceleration (do not pass ${BOLD}${YELLOW}-hwaccel${ALL_OFF} to ffmpeg)
+
+${BOLD}${BLUE}Skip options:${ALL_OFF}
+ ${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
+ ${BOLD}${YELLOW}--skip-codec-override${ALL_OFF} use only codecs from ${BOLD}${YELLOW}--skip-codec${ALL_OFF}, ignoring ${BOLD}${CYAN}[skip].codecs${ALL_OFF} from config
+
+${BOLD}${BLUE}Processing options:${ALL_OFF}
+ ${BOLD}${YELLOW}-n, --dry-run${ALL_OFF} show what would be done, do not run ffmpeg
+ ${BOLD}${YELLOW}--backup-dir${ALL_OFF} ${BOLD}${GREEN}DIR${ALL_OFF} backup original files to DIR instead of overwriting them
${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}${YELLOW}--verify-output${ALL_OFF} probe output with ffprobe before replacing original (default)
${BOLD}${YELLOW}--no-verify-output${ALL_OFF} skip the post-encode integrity check
-
-${BOLD}${BLUE}Input options:${ALL_OFF}
- ${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
- ${BOLD}${YELLOW}--skip-codec-override${ALL_OFF} use only codecs from --skip-codec,
- ignoring [skip].codecs from config
+ ${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}Size report options:${ALL_OFF}
${BOLD}${YELLOW}-s, --size-report${ALL_OFF} print size feedback and write a status TSV log
- ${BOLD}${YELLOW}--no-size-report${ALL_OFF} disable size reporting from config.toml
+ ${BOLD}${YELLOW}--no-size-report${ALL_OFF} disable size reporting from config
${BOLD}${YELLOW}--size-report-file${ALL_OFF} ${BOLD}${GREEN}FILE${ALL_OFF} path for the size report log (default: ${BOLD}${RED}%s${ALL_OFF})
-${BOLD}${BLUE}Output options:${ALL_OFF}
- ${BOLD}${YELLOW}--ffmpeg-loglevel${ALL_OFF} specify the loglevel to pass to ffmpeg (default: ${BOLD}${RED}%s${ALL_OFF})
+${BOLD}${BLUE}Display options:${ALL_OFF}
+ ${BOLD}${YELLOW}--ffmpeg-loglevel${ALL_OFF} ${BOLD}${GREEN}LEVEL${ALL_OFF} specify the loglevel to pass to ffmpeg (default: ${BOLD}${RED}%s${ALL_OFF})
${BOLD}${YELLOW}-q, --quiet${ALL_OFF} suppress all output; takes precedence over ${BOLD}${YELLOW}-v${ALL_OFF}
${BOLD}${YELLOW}-v, --verbose${ALL_OFF} explain what is being done
${BOLD}${YELLOW}--color${ALL_OFF} force colored output
@@ -336,7 +338,7 @@ ${BOLD}${BLUE}Configuration files:${ALL_OFF}
${BOLD}${GREEN}input_frame_rate${ALL_OFF} raw fraction from ffprobe (e.g. 30000/1001)
${BOLD}${GREEN}input_fps${ALL_OFF} input_frame_rate rounded to nearest integer
${BOLD}${GREEN}output_gop_size${ALL_OFF} ~5 s GOP derived from input_fps, capped at 300
-
+
${BOLD}${RED}presets are sourced as shell code; only use trusted presets from trusted
directories.${ALL_OFF}
@@ -354,8 +356,8 @@ ${BOLD}${BLUE}Examples:${ALL_OFF}
"$NICE_VALUE" \
"$HWACCEL_VALUE" \
"$VIDEO_STREAM" \
- "$SIZE_REPORT_FILE" \
"$FFMPEG_LOGLEVEL" \
+ "$SIZE_REPORT_FILE" \
"$PRESET_DIR" \
"$CONFIG_FILE" \
"$SCRIPTNAME" \
@@ -1460,84 +1462,6 @@ fi
# variables so load_config() can respect CLI-over-config precedence.
while [[ $# -gt 0 ]]; do
case "$1" in
- -h | --help | -\?)
- print_help
- exit $EXIT_OK
- ;;
- --version)
- print_version
- exit $EXIT_OK
- ;;
- --list-presets)
- list_presets
- exit $EXIT_OK
- ;;
- -q | --quiet)
- QUIET=1
- _CLI_QUIET=1
- shift
- ;;
- -v | --verbose)
- VERBOSE=1
- _CLI_VERBOSE=1
- shift
- ;;
- --color)
- ENABLE_COLOR=1
- # Propagate the explicit color choice to ffmpeg/libav subprocesses.
- export AV_LOG_FORCE_COLOR=1
- setup_colors
- shift
- ;;
- --no-color)
- ENABLE_COLOR=0
- # Propagate the explicit color choice to ffmpeg/libav subprocesses.
- export AV_LOG_FORCE_NOCOLOR=1
- setup_colors
- shift
- ;;
- -c | --continue)
- CONTINUE_ON_FAIL=1
- _CLI_CONTINUE=1
- shift
- ;;
- --no-continue)
- CONTINUE_ON_FAIL=0
- _CLI_CONTINUE=1
- shift
- ;;
- --verify-output)
- VERIFY_OUTPUT=1
- _CLI_VERIFY_OUTPUT=1
- shift
- ;;
- --no-verify-output)
- VERIFY_OUTPUT=0
- _CLI_VERIFY_OUTPUT=1
- shift
- ;;
- --backup-dir)
- if [[ $# -lt 2 ]]; then
- error "Missing value for $1"
- exit $EXIT_USAGE_ERROR
- fi
- if [[ -z "$2" ]]; then
- error "Value for $1 must not be empty"
- exit $EXIT_USAGE_ERROR
- fi
- BACKUP_DIR="$2"
- _CLI_BACKUP_DIR=1
- shift 2
- ;;
- --backup-dir=*)
- if [[ -z "${1#*=}" ]]; then
- error "Value for --backup-dir must not be empty"
- exit $EXIT_USAGE_ERROR
- fi
- BACKUP_DIR="${1#*=}"
- _CLI_BACKUP_DIR=1
- shift
- ;;
--config-file)
if [[ $# -lt 2 ]]; then
error "Missing value for $1"
@@ -1585,8 +1509,26 @@ while [[ $# -gt 0 ]]; do
ENCODE_FILE="${1#*=}"
shift
;;
- -n | --dry-run)
- DRY_RUN=1
+ -p | --preset)
+ if [[ $# -lt 2 ]]; then
+ error "Missing value for $1"
+ exit $EXIT_USAGE_ERROR
+ fi
+ if [[ -z "$2" ]]; then
+ error "Value for $1 must not be empty"
+ exit $EXIT_USAGE_ERROR
+ fi
+ PRESET_NAME="$2"
+ _CLI_PRESET=1
+ shift 2
+ ;;
+ --preset=*)
+ if [[ -z "${1#*=}" ]]; then
+ error "Value for --preset must not be empty"
+ exit $EXIT_USAGE_ERROR
+ fi
+ PRESET_NAME="${1#*=}"
+ _CLI_PRESET=1
shift
;;
-N | --nice)
@@ -1603,36 +1545,62 @@ while [[ $# -gt 0 ]]; do
_CLI_NICE=1
shift
;;
- -s | --size-report)
- SIZE_REPORT=1
- _CLI_SIZE_REPORT=1
+ --hwaccel)
+ HWACCEL=1
+ # Peek at the next argument: use it as the METHOD only if it is
+ # non-empty and does not look like an option flag.
+ if [[ $# -ge 2 && -n "$2" && "$2" != -* ]]; then
+ HWACCEL_VALUE="$2"
+ shift 2
+ else
+ HWACCEL_VALUE="auto"
+ shift
+ fi
+ _CLI_HWACCEL=1
+ ;;
+ --hwaccel=*)
+ HWACCEL=1
+ HWACCEL_VALUE="${1#*=}"
+ if [[ -z "$HWACCEL_VALUE" ]]; then
+ error "Value for --hwaccel must not be empty"
+ exit $EXIT_USAGE_ERROR
+ fi
+ _CLI_HWACCEL=1
shift
;;
- --no-size-report)
- SIZE_REPORT=0
- _CLI_SIZE_REPORT=1
+ --no-hwaccel)
+ HWACCEL=0
+ _CLI_HWACCEL=1
shift
;;
- --size-report-file)
+ --video-stream)
if [[ $# -lt 2 ]]; then
- error "Missing value for $1"
+ error "Missing value for:" "$1"
exit $EXIT_USAGE_ERROR
fi
if [[ -z "$2" ]]; then
error "Value for $1 must not be empty"
exit $EXIT_USAGE_ERROR
fi
- SIZE_REPORT_FILE="$2"
- _CLI_SIZE_REPORT_FILE=1
+ if ! validate_stream_selector "$2"; then
+ error "Invalid stream selector:" "$2"
+ exit $EXIT_USAGE_ERROR
+ fi
+ VIDEO_STREAM="$2"
+ _CLI_VIDEO_STREAM=1
shift 2
;;
- --size-report-file=*)
+ --video-stream=*)
if [[ -z "${1#*=}" ]]; then
- error "Value for --size-report-file must not be empty"
+ error "Value for --video-stream must not be empty"
exit $EXIT_USAGE_ERROR
fi
- SIZE_REPORT_FILE="${1#*=}"
- _CLI_SIZE_REPORT_FILE=1
+ if ! validate_stream_selector "${1#*=}"; then
+ error "Invalid stream selector:" "${1#*=}"
+ exit $EXIT_USAGE_ERROR
+ fi
+ VIDEO_STREAM="${1#*=}"
+ _CLI_VIDEO_STREAM=1
shift
;;
-S | --skip-codec)
@@ -1651,6 +1619,32 @@ while [[ $# -gt 0 ]]; do
_CLI_SKIP_CODECS_OVERRIDE=1
shift
;;
+ -n | --dry-run)
+ DRY_RUN=1
+ shift
+ ;;
+ --backup-dir)
+ if [[ $# -lt 2 ]]; then
+ error "Missing value for $1"
+ exit $EXIT_USAGE_ERROR
+ fi
+ if [[ -z "$2" ]]; then
+ error "Value for $1 must not be empty"
+ exit $EXIT_USAGE_ERROR
+ fi
+ BACKUP_DIR="$2"
+ _CLI_BACKUP_DIR=1
+ shift 2
+ ;;
+ --backup-dir=*)
+ if [[ -z "${1#*=}" ]]; then
+ error "Value for --backup-dir must not be empty"
+ exit $EXIT_USAGE_ERROR
+ fi
+ BACKUP_DIR="${1#*=}"
+ _CLI_BACKUP_DIR=1
+ shift
+ ;;
-l | --only-if-smaller)
ONLY_IF_SMALLER=1
_CLI_ONLY_IF_SMALLER=1
@@ -1661,35 +1655,37 @@ while [[ $# -gt 0 ]]; do
_CLI_ONLY_IF_SMALLER=1
shift
;;
- --hwaccel)
- HWACCEL=1
- # Peek at the next argument: use it as the METHOD only if it is
- # non-empty and does not look like an option flag.
- if [[ $# -ge 2 && -n "$2" && "$2" != -* ]]; then
- HWACCEL_VALUE="$2"
- shift 2
- else
- HWACCEL_VALUE="auto"
- shift
- fi
- _CLI_HWACCEL=1
+ --verify-output)
+ VERIFY_OUTPUT=1
+ _CLI_VERIFY_OUTPUT=1
+ shift
;;
- --hwaccel=*)
- HWACCEL=1
- HWACCEL_VALUE="${1#*=}"
- if [[ -z "$HWACCEL_VALUE" ]]; then
- error "Value for --hwaccel must not be empty"
- exit $EXIT_USAGE_ERROR
- fi
- _CLI_HWACCEL=1
+ --no-verify-output)
+ VERIFY_OUTPUT=0
+ _CLI_VERIFY_OUTPUT=1
shift
;;
- --no-hwaccel)
- HWACCEL=0
- _CLI_HWACCEL=1
+ -c | --continue)
+ CONTINUE_ON_FAIL=1
+ _CLI_CONTINUE=1
shift
;;
- -p | --preset)
+ --no-continue)
+ CONTINUE_ON_FAIL=0
+ _CLI_CONTINUE=1
+ shift
+ ;;
+ -s | --size-report)
+ SIZE_REPORT=1
+ _CLI_SIZE_REPORT=1
+ shift
+ ;;
+ --no-size-report)
+ SIZE_REPORT=0
+ _CLI_SIZE_REPORT=1
+ shift
+ ;;
+ --size-report-file)
if [[ $# -lt 2 ]]; then
error "Missing value for $1"
exit $EXIT_USAGE_ERROR
@@ -1698,17 +1694,17 @@ while [[ $# -gt 0 ]]; do
error "Value for $1 must not be empty"
exit $EXIT_USAGE_ERROR
fi
- PRESET_NAME="$2"
- _CLI_PRESET=1
+ SIZE_REPORT_FILE="$2"
+ _CLI_SIZE_REPORT_FILE=1
shift 2
;;
- --preset=*)
+ --size-report-file=*)
if [[ -z "${1#*=}" ]]; then
- error "Value for --preset must not be empty"
+ error "Value for --size-report-file must not be empty"
exit $EXIT_USAGE_ERROR
fi
- PRESET_NAME="${1#*=}"
- _CLI_PRESET=1
+ SIZE_REPORT_FILE="${1#*=}"
+ _CLI_SIZE_REPORT_FILE=1
shift
;;
--ffmpeg-loglevel)
@@ -1733,36 +1729,43 @@ while [[ $# -gt 0 ]]; do
_CLI_FFMPEG_LOGLEVEL=1
shift
;;
- --video-stream)
- if [[ $# -lt 2 ]]; then
- error "Missing value for:" "$1"
- exit $EXIT_USAGE_ERROR
- fi
- if [[ -z "$2" ]]; then
- error "Value for $1 must not be empty"
- exit $EXIT_USAGE_ERROR
- fi
- if ! validate_stream_selector "$2"; then
- error "Invalid stream selector:" "$2"
- exit $EXIT_USAGE_ERROR
- fi
- VIDEO_STREAM="$2"
- _CLI_VIDEO_STREAM=1
- shift 2
+
+ -q | --quiet)
+ QUIET=1
+ _CLI_QUIET=1
+ shift
;;
- --video-stream=*)
- if [[ -z "${1#*=}" ]]; then
- error "Value for --video-stream must not be empty"
- exit $EXIT_USAGE_ERROR
- fi
- if ! validate_stream_selector "${1#*=}"; then
- error "Invalid stream selector:" "${1#*=}"
- exit $EXIT_USAGE_ERROR
- fi
- VIDEO_STREAM="${1#*=}"
- _CLI_VIDEO_STREAM=1
+ -v | --verbose)
+ VERBOSE=1
+ _CLI_VERBOSE=1
+ shift
+ ;;
+ --color)
+ ENABLE_COLOR=1
+ # Propagate the explicit color choice to ffmpeg/libav subprocesses.
+ export AV_LOG_FORCE_COLOR=1
+ setup_colors
+ shift
+ ;;
+ --no-color)
+ ENABLE_COLOR=0
+ # Propagate the explicit color choice to ffmpeg/libav subprocesses.
+ export AV_LOG_FORCE_NOCOLOR=1
+ setup_colors
shift
;;
+ -h | --help | -\?)
+ print_help
+ exit $EXIT_OK
+ ;;
+ --version)
+ print_version
+ exit $EXIT_OK
+ ;;
+ --list-presets)
+ list_presets
+ exit $EXIT_OK
+ ;;
--)
shift
REMAINING_ARGS+=("$@")
diff --git a/transcode.sh.1 b/transcode.sh.1
index 524ba68..caa4c1a 100644
--- a/transcode.sh.1
+++ b/transcode.sh.1
@@ -45,30 +45,7 @@ playable media file before the original is replaced. If the integrity
check fails the temporary file is removed and the encode is treated as a
runtime failure, leaving the original untouched.
.SH OPTIONS
-.TP
-.BR \-c ", " \-\-continue
-Continue processing the next file even if
-.BR ffmpeg (1)
-fails on the current one. Without this flag the script exits immediately
-on the first failure.
-.TP
-.BR \-\-no\-continue
-Do not continue processing next file even if
-.BR ffmpeg (1)
-fails on the current one.
-.TP
-.BR \-\-verify\-output
-After encoding, probe the temporary output file with
-.BR ffprobe (1)
-to confirm it is a valid, playable media file before replacing the
-original. Enabled by default.
-.TP
-.BR \-\-no\-verify\-output
-Skip the post-encode integrity check. The original is replaced as long
-as
-.BR ffmpeg (1)
-exits successfully. Useful for large batch jobs on trusted encoders
-where the additional probe round-trip is undesirable.
+.SS "Input options"
.TP
.BR \-\-config\-file " \fIPATH\fR, " \-\-config\-file= \fIPATH\fR
Load configuration from \fIPATH\fR instead of the default location
@@ -79,23 +56,26 @@ Requires
.BR tomlq (1)
when the file is present.
.TP
+.BR \-\-no\-config
+Do not load any configuration file.
+.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.
+.SS "Encoding options"
.TP
-.BR \-n ", " \-\-dry\-run
-Print what would be done without actually invoking
-.BR ffmpeg (1).
-Combine with
-.B \-v
-to see the selected video stream and detected codec, pixel format and frame
-rate information.
+.BR \-p " \fINAME\fR, " \-\-preset " \fINAME\fR, " \-\-preset= \fINAME\fR
+Load the preset named \fINAME\fR from the preset directory. Defaults to
+.BR default .
.TP
-.BR \-\-backup\-dir " \fIDIR\fR, " \-\-backup\-dir= \fIDIR\fR
-Copy originals to \fIDIR\fR before replacing them after successful encoding.
-\fIDIR\fR must already exist; the script exits with a usage error if it does
-not. Backups preserve the source file's absolute path below \fIDIR\fR, and
-existing backup files are not overwritten.
+.BR \-N " \fIVALUE\fR, " \-\-nice " \fIVALUE\fR, " \-\-nice= \fIVALUE\fR
+Run
+.BR ffmpeg (1)
+under
+.BR nice (1)
+with the given niceness value. Defaults to
+.BR 19
+(lowest priority).
.TP
.BR \-\-hwaccel " [\fIMETHOD\fR], " \-\-hwaccel= \fIMETHOD\fR
Pass
@@ -138,31 +118,7 @@ or
.BR v:1 .
This option does not change ffmpeg stream mapping; presets remain responsible
for selecting which stream to encode.
-.TP
-.BR \-N " \fIVALUE\fR, " \-\-nice " \fIVALUE\fR, " \-\-nice= \fIVALUE\fR
-Run
-.BR ffmpeg (1)
-under
-.BR nice (1)
-with the given niceness value. Defaults to
-.BR 19
-(lowest priority).
-.TP
-.BR \-s ", " \-\-size\-report
-Print per-file size feedback after successful encodes and size-based skips,
-then write a TSV status log for encoded, skipped and failed files. For runs
-with more than one input file, print a final summary with encoded, skipped
-and failed counts, total bytes saved and the overall saved percentage.
-.TP
-.BR \-\-no\-size\-report
-Disable size reporting from the configuration file.
-.TP
-.BR \-\-size\-report\-file " \fIPATH\fR, " \-\-size\-report\-file= \fIPATH\fR
-Path to the TSV status log written by
-.BR \-\-size\-report .
-Defaults to
-.B transcode_size_report
-in the current working directory.
+.SS "Skip options"
.TP
.BR \-S " \fILIST\fR, " \-\-skip\-codec " \fILIST\fR, " \-\-skip\-codec= \fILIST\fR
Comma-, space- or colon-separated list of video codec names to skip.
@@ -182,6 +138,21 @@ and use only codecs provided through
.BR \-S / \-\-skip\-codec
for this run. The position of this flag on the command line does not matter;
it changes how the final skip list is resolved after all options are parsed.
+.SS "Processing options"
+.TP
+.BR \-n ", " \-\-dry\-run
+Print what would be done without actually invoking
+.BR ffmpeg (1).
+Combine with
+.B \-v
+to see the selected video stream and detected codec, pixel format and frame
+rate information.
+.TP
+.BR \-\-backup\-dir " \fIDIR\fR, " \-\-backup\-dir= \fIDIR\fR
+Copy originals to \fIDIR\fR before replacing them after successful encoding.
+\fIDIR\fR must already exist; the script exits with a usage error if it does
+not. Backups preserve the source file's absolute path below \fIDIR\fR, and
+existing backup files are not overwritten.
.TP
.BR \-l ", " \-\-only\-if\-smaller
After encoding, replace the original only when the new file is strictly
@@ -191,9 +162,47 @@ and the original is kept unchanged.
.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 .
+.BR \-\-verify\-output
+After encoding, probe the temporary output file with
+.BR ffprobe (1)
+to confirm it is a valid, playable media file before replacing the
+original. Enabled by default.
+.TP
+.BR \-\-no\-verify\-output
+Skip the post-encode integrity check. The original is replaced as long
+as
+.BR ffmpeg (1)
+exits successfully. Useful for large batch jobs on trusted encoders
+where the additional probe round-trip is undesirable.
+.TP
+.BR \-c ", " \-\-continue
+Continue processing the next file even if
+.BR ffmpeg (1)
+fails on the current one. Without this flag the script exits immediately
+on the first failure.
+.TP
+.BR \-\-no\-continue
+Do not continue processing next file even if
+.BR ffmpeg (1)
+fails on the current one.
+.SS "Size report options"
+.TP
+.BR \-s ", " \-\-size\-report
+Print per-file size feedback after successful encodes and size-based skips,
+then write a TSV status log for encoded, skipped and failed files. For runs
+with more than one input file, print a final summary with encoded, skipped
+and failed counts, total bytes saved and the overall saved percentage.
+.TP
+.BR \-\-no\-size\-report
+Disable size reporting from the configuration file.
+.TP
+.BR \-\-size\-report\-file " \fIPATH\fR, " \-\-size\-report\-file= \fIPATH\fR
+Path to the TSV status log written by
+.BR \-\-size\-report .
+Defaults to
+.B transcode_size_report
+in the current working directory.
+.SS "Display options"
.TP
.BR \-\-ffmpeg\-loglevel " \fILEVEL\fR, " \-\-ffmpeg\-loglevel= \fILEVEL\fR
Pass
@@ -203,9 +212,6 @@ to
Defaults to
.BR fatal .
.TP
-.BR \-h ", " \-\-help ", " \-?
-Print a short help message and exit.
-.TP
.BR \-q ", " \-\-quiet
Suppress all normal output. Takes precedence over
.BR \-v / \-\-verbose .
@@ -214,6 +220,18 @@ Suppress all normal output. Takes precedence over
Emit additional informational messages, including the selected video stream and
detected codec, pixel format and frame rate.
.TP
+.B \-\-color
+Force colored output even when stdout is not a terminal or
+.B NO_COLOR
+is set.
+.TP
+.B \-\-no\-color
+Disable colored output unconditionally.
+.SS "General options"
+.TP
+.BR \-h ", " \-\-help ", " \-?
+Print a short help message and exit.
+.TP
.B \-\-version
Print version, author and license information and exit.
.TP
@@ -226,14 +244,6 @@ If the preset directory does not exist or contains no
.B .sh
files, a notice is printed instead.
.TP
-.B \-\-color
-Force colored output even when stdout is not a terminal or
-.B NO_COLOR
-is set.
-.TP
-.B \-\-no\-color
-Disable colored output unconditionally.
-.TP
.B \-\-
End of options. All subsequent arguments are treated as file names even
if they begin with
diff --git a/transcode.sh.bash-completion.sh b/transcode.sh.bash-completion.sh
index 2ae59d0..6e55970 100644
--- a/transcode.sh.bash-completion.sh
+++ b/transcode.sh.bash-completion.sh
@@ -52,19 +52,14 @@ function _transcode_sh() {
_filedir
return
;;
- --backup-dir=*)
- cur="${cur#*=}"
- _filedir -d
- return
- ;;
--encode-file=*)
cur="${cur#*=}"
_filedir
return
;;
- --size-report-file=*)
+ --preset=*)
cur="${cur#*=}"
- _filedir
+ COMPREPLY=($(compgen -W "$(_transcode_presets)" -- "$cur"))
return
;;
--nice=*)
@@ -72,19 +67,29 @@ function _transcode_sh() {
COMPREPLY=($(compgen -W "$nice_vals" -- "$cur"))
return
;;
+ --hwaccel=*)
+ cur="${cur#*=}"
+ COMPREPLY=($(compgen -W "$hwaccel_methods" -- "$cur"))
+ return
+ ;;
+ --video-stream=*)
+ cur="${cur#*=}"
+ COMPREPLY=($(compgen -W "$video_streams" -- "$cur"))
+ return
+ ;;
--skip-codec=*)
cur="${cur#*=}"
COMPREPLY=($(compgen -W "$codecs" -- "$cur"))
return
;;
- --preset=*)
+ --backup-dir=*)
cur="${cur#*=}"
- COMPREPLY=($(compgen -W "$(_transcode_presets)" -- "$cur"))
+ _filedir -d
return
;;
- --hwaccel=*)
+ --size-report-file=*)
cur="${cur#*=}"
- COMPREPLY=($(compgen -W "$hwaccel_methods" -- "$cur"))
+ _filedir
return
;;
--ffmpeg-loglevel=*)
@@ -92,16 +97,11 @@ function _transcode_sh() {
COMPREPLY=($(compgen -W "$ffmpeg_loglevels" -- "$cur"))
return
;;
- --video-stream=*)
- cur="${cur#*=}"
- COMPREPLY=($(compgen -W "$video_streams" -- "$cur"))
- return
- ;;
esac
# ---------------------------------------------------------------------------
- # Handle VALUE after short form (-f, -N, -S, -p) and
- # long space form (--encode-file, --nice, --size-report-file, --skip-codec, --preset).
+ # Handle VALUE after short and long space forms.
+ # The dispatch order mirrors the help output where practical.
# $prev is the option word, $cur is the value being typed.
# ---------------------------------------------------------------------------
case "$prev" in
@@ -109,40 +109,40 @@ function _transcode_sh() {
_filedir
return
;;
- --backup-dir)
- _filedir -d
- return
- ;;
-f | --encode-file)
_filedir
return
;;
+ -p | --preset)
+ COMPREPLY=($(compgen -W "$(_transcode_presets)" -- "$cur"))
+ return
+ ;;
-N | --nice)
COMPREPLY=($(compgen -W "$nice_vals" -- "$cur"))
return
;;
- --size-report-file)
- _filedir
+ --hwaccel)
+ COMPREPLY=($(compgen -W "$hwaccel_methods" -- "$cur"))
return
;;
- -S | --skip-codec)
- COMPREPLY=($(compgen -W "$codecs" -- "$cur"))
+ --video-stream)
+ COMPREPLY=($(compgen -W "$video_streams" -- "$cur"))
return
;;
- -p | --preset)
- COMPREPLY=($(compgen -W "$(_transcode_presets)" -- "$cur"))
+ --ffmpeg-loglevel)
+ COMPREPLY=($(compgen -W "$ffmpeg_loglevels" -- "$cur"))
return
;;
- --hwaccel)
- COMPREPLY=($(compgen -W "$hwaccel_methods" -- "$cur"))
+ -S | --skip-codec)
+ COMPREPLY=($(compgen -W "$codecs" -- "$cur"))
return
;;
- --ffmpeg-loglevel)
- COMPREPLY=($(compgen -W "$ffmpeg_loglevels" -- "$cur"))
+ --backup-dir)
+ _filedir -d
return
;;
- --video-stream)
- COMPREPLY=($(compgen -W "$video_streams" -- "$cur"))
+ --size-report-file)
+ _filedir
return
;;
esac
@@ -157,44 +157,45 @@ function _transcode_sh() {
case "$cur" in
--*)
local longopts='
- --backup-dir
- --backup-dir=
- --color
--config-file
--config-file=
- --continue
- --dry-run
+ --no-config
--encode-file
--encode-file=
- --ffmpeg-loglevel
- --ffmpeg-loglevel=
- --help
- --hwaccel
- --hwaccel=
- --list-presets
+ --preset
+ --preset=
--nice
--nice=
- --no-color
- --no-continue
+ --hwaccel
+ --hwaccel=
--no-hwaccel
+ --video-stream
+ --video-stream=
+ --skip-codec
+ --skip-codec=
+ --skip-codec-override
+ --dry-run
+ --backup-dir
+ --backup-dir=
+ --only-if-smaller
--no-only-if-smaller
- --no-size-report
+ --verify-output
--no-verify-output
- --only-if-smaller
- --preset
- --preset=
- --quiet
+ --continue
+ --no-continue
--size-report
+ --no-size-report
--size-report-file
--size-report-file=
- --skip-codec
- --skip-codec-override
- --skip-codec=
+ --ffmpeg-loglevel
+ --ffmpeg-loglevel=
+ --quiet
--verbose
- --verify-output
+ --color
+ --no-color
+ --help
--version
- --video-stream
- --video-stream=
+ --list-presets
'
COMPREPLY=($(compgen -W "$longopts" -- "$cur"))
# Suppress the trailing space when the only completion ends with '='
@@ -203,7 +204,7 @@ function _transcode_sh() {
return
;;
-*)
- local shortopts='-c -f -n -N -s -S -l -p -h -? -q -v --'
+ local shortopts='-f -p -N -S -n -l -c -s -q -v -h -? --'
COMPREPLY=($(compgen -W "$shortopts" -- "$cur"))
return
;;