aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
...
* chore: update revision datev1.0.0Dennis Fink2026-02-25
|
* fix(skip): join codec keys before passing to verbose()Dennis Fink2026-02-25
| | | | Joining into a single string ensures the entire list renders uniformly.
* feat(core): add warn() and downgrade --saving-file diagnostic to warningDennis Fink2026-02-25
| | | | | | The --saving-file without --saving condition is non-fatal, so using error() was misleading. Introduce warn() (yellow output, respects --quiet) and use it for this diagnostic instead.
* feat(core): add batch progress counter to processing outputDennis Fink2026-02-25
| | | | | | | | | | | encode_one now receives the current index and total file count and includes them in the "Processing" message (e.g. "Processing [2/7]: file.mkv"). Both the CLI and encode-file paths pre-collect their file lists into arrays so the total is known before encoding begins. Also fix a typo in the encode_one step comment ("preserverse" -> "preserves") and add a note on the filename variable explaining the single-extension stripping behaviour for multi-dot filenames.
* refactor(core): combine ffprobe calls and simplify pixel format selectionDennis Fink2026-02-25
| | | | | | | | | | | | | | | Merge the two separate ffprobe invocations for codec and pixel format into one, halving the per-file probe overhead on large batches. Both error messages now include the filename for easier diagnosis in batch runs. Replace the three-way nested if/elif/else for pixel format selection with two independent case statements — one for chroma subsampling, one for bit depth — that compose the output format string from two parts. This eliminates the repetition across the three subsampling branches and makes adding a new bit depth or subsampling variant a single-line change. Also add a verbose fallback warning for exotic formats that don't match any known subsampling pattern.
* refactor(preset): return ffargs via nameref instead of global variableDennis Fink2026-02-25
| | | | | | | | | | | | | | load_preset now accepts the name of the caller's array as a second argument and populates it via a nameref (local -n), replacing the previous implicit global ffargs. The preset is sourced into a local ffargs contained within load_preset's scope and copied to the caller on return. encode_one declares its own local ffargs=() and passes its name to load_preset, making the data flow explicit and eliminating the implicit coupling through the global. The nameref variable is prefixed with an underscore to avoid accidental aliasing of any same-named local in the calling scope.
* fix(cli): improve output consistency and verbose diagnosticsDennis Fink2026-02-25
| | | | | | | | | | | | | | Replace the full help page on no-args with a short usage hint to stderr, reserving the full help for explicit -h/--help invocations. Print the active codec skip list at startup under --verbose so unexpected skips can be diagnosed without resorting to DEBUG mode. Include the resolved ffmpeg command in dry-run --verbose output, which is useful for preset authors verifying their ffargs expansion. Fix the only-if-smaller message to follow the "label: value" convention used throughout the script.
* fix(cli): validate empty option values and improve --saving-file handlingDennis Fink2026-02-25
| | | | | | | | | | | | | | | Reject empty values for --encodefile, --saving-file, and --preset in both the space-separated and equals forms (e.g. --preset= now exits with a clear error instead of failing later with a confusing message from the allowlist check). Track whether --saving-file was set explicitly via SAVING_FILE_EXPLICIT. Warn when --saving-file is used without --saving, but do not exit, to allow the combination in aliases and wrapper scripts. Change the savings log format from space-separated to TSV and write a header line on first creation, making the file easier to parse both by eye and programmatically.
* refactor: simplify several small code patternsDennis Fink2026-02-24
| | | | | | | | | | | | - Drop the UMASK variable; umask is called directly with the literal value - Simplify filesize() to a one-liner using || instead of if/local/printf - Fold token lowercasing into the local declaration in add_skip_codec_token and drop the now-redundant empty-string guard - Replace manual whitespace trimming in the skip.conf reader with read's built-in IFS trimming - Replace the yuvj* case statement with a single parameter substitution - Collapse nested only-if-smaller conditions into one && expression - Move the "Sourcing preset file" debug call to just before source
* chore: update revision date and fix gitmessage leading newlineDennis Fink2026-02-24
|
* fix(core): use mktemp for temporary output file creationDennis Fink2026-02-24
| | | | | Replaces $$.$RANDOM with mktemp, which provides cryptographically random names and atomic file creation.
* fix: improve input validation and error reportingDennis Fink2026-02-24
| | | | | | | | | | | | | Validate the nice value is an integer in [-20, 19] at startup rather than letting nice(1) fail with a cryptic error at encode time. In encode_one, move the "Processing" message after the empty-string guard so it is not printed for blank lines, include the filename in the "Not found" error, and add a readability check so unreadable files are rejected with a clear message before ffprobe is invoked. Validate that the encode file (-f) exists before entering the read loop, exiting with a usage error rather than a silent empty run.
* fix(preset): refuse to source world-writable preset filesDennis Fink2026-02-24
| | | | | | | | | | Preset files are executed as shell code. A world-writable preset file could be modified by any local user to inject arbitrary commands. Symlinks are resolved before the permission check because stat on a symlink returns the permissions of the link itself (always 777 on Linux) rather than those of the target. readlink -f is used with a fallback to realpath for macOS/BSD compatibility.
* refactor: remove expand_aliases shoptDennis Fink2026-02-24
| | | | | | | Aliases are never defined or used in the script, making this option redundant. Removing it reduces the attack surface slightly and avoids unexpected behaviour if the script is ever sourced into a shell with user-defined aliases.
* fix: enable TRACE only when set to 1 instead of any non-zero valueDennis Fink2026-02-24
| | | | | Consistent with the DEBUG variable which is also compared against 1 throughout the script.
* fix(core): pass filename as separate argument to msg/error callsDennis Fink2026-02-24
| | | | | | | Aligns with the two-argument calling convention used elsewhere in the script, where the bold label and the highlighted value are passed as separate arguments. Also moves the preset name out of the error string in load_preset for the same reason.
* docs: document all variables available to presetsDennis Fink2026-02-24
| | | | | | | Previously only output_pixel_format was mentioned. All three variables (input_codec, input_pixel_format, output_pixel_format) are now listed with descriptions in the script header comment, the README, and the man page.
* chore: add BSD-3-Clause license textDennis Fink2026-02-22
|
* docs: document base ffmpeg arguments passed before preset ffargsDennis Fink2026-02-22
| | | | | | | | | | | Both the README and the man page now explain that the script always passes -map 0, -map_metadata 0, -map_chapters 0, and -c copy to ffmpeg before appending the preset's ffargs array. This context is important for preset authors, who only need to override the streams they intend to re-encode. Also fix a minor blockquote rendering issue in the README (missing blank line before the fenced code block in the PATH note).
* feat: initial release of transcode.sh v1.0.0Dennis Fink2026-02-22
Batch transcode helper for media files using ffmpeg. Encoding parameters are supplied by user-defined preset files (shell snippets that set an `ffargs` array) stored under ${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/presets/. Key capabilities: - Probes input codec and pixel format via ffprobe; derives an output pixel format that preserves chroma subsampling and bit depth. - Per-user and per-invocation codec skip lists to leave already-encoded files untouched. - Atomic in-place replacement: encodes to a temp file in the same directory, then renames on success. - --only-if-smaller: discard the result if it is larger than the original. - --saving: append filename, original/new sizes and percentage saved to a log file after each successful encode. - --dry-run, --verbose, --quiet, --nice and --continue flags. - Respects the NO_COLOR standard. - Script hardening: strict PATH, safe IFS, errtrace, nounset, pipefail. Also included: - Man page (transcode.sh.1) - Bash completion script (transcode.sh.bash-completion) - README.md - .gitmessage commit message template License: BSD-3-Clause