aboutsummaryrefslogtreecommitdiff
path: root/transcode.sh.1
diff options
context:
space:
mode:
authorDennis Fink2026-02-22 08:41:04 +0100
committerDennis Fink2026-02-22 08:41:24 +0100
commitd6b6cb1bfd71e95aeda2e784c214ddffcc777fd1 (patch)
tree4ca07090f28242764425f6416c10b0203334da29 /transcode.sh.1
downloadtranscode.sh-d6b6cb1bfd71e95aeda2e784c214ddffcc777fd1.tar.gz
transcode.sh-d6b6cb1bfd71e95aeda2e784c214ddffcc777fd1.zip
feat: initial release of transcode.sh v1.0.0
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
Diffstat (limited to 'transcode.sh.1')
-rw-r--r--transcode.sh.1274
1 files changed, 274 insertions, 0 deletions
diff --git a/transcode.sh.1 b/transcode.sh.1
new file mode 100644
index 0000000..9001e8a
--- /dev/null
+++ b/transcode.sh.1
@@ -0,0 +1,274 @@
+.TH TRANSCODE.SH 1 "2026-02-02" "1.0.0" "User Commands"
+.SH NAME
+transcode.sh \- batch transcode helper for media files using ffmpeg
+.SH SYNOPSIS
+.B transcode.sh
+[\fIOPTION\fR]... [\fB\-\-\fR] \fIFILE\fR...
+.SH DESCRIPTION
+.B transcode.sh
+is a batch transcoding wrapper around
+.BR ffmpeg (1)
+that processes one or more media files in place, replacing each with a
+re-encoded version.
+.PP
+Encoding parameters are not hard-coded; instead they are supplied by
+.IR presets ,
+which are small shell snippets stored under the preset directory (see
+.B FILES
+below). Each preset must define a Bash array named
+.B ffargs
+containing the extra arguments passed to
+.BR ffmpeg (1).
+.PP
+The script probes every input file with
+.BR ffprobe (1)
+to detect the input video codec and pixel format. Files whose codec
+appears in the skip list are silently skipped. The output pixel format
+is derived automatically so that chroma subsampling (4:2:0, 4:2:2,
+4:4:4) and bit depth (8, 10, 12, 16\-bit) are preserved.
+.PP
+All streams, metadata and chapter markers from the input are retained by
+default (\fB\-map 0 \-map_metadata 0 \-map_chapters 0 \-c copy\fR); the
+preset only needs to override the streams it cares about (typically
+video).
+.PP
+Encoding is performed into a temporary file in the same directory as the
+input, which ensures an atomic rename on completion.
+.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 \-f " \fIPATH\fR, " \-\-encodefile " \fIPATH\fR, " \-\-encodefile= \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
+.BR \-n ", " \-\-dry\-run
+Print what would be done without actually invoking
+.BR ffmpeg (1).
+Combine with
+.B \-v
+to see the detected codec and pixel format information.
+.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 ", " \-\-saving
+After each successful encode, append a line to the savings log file
+recording the filename, original size in bytes, new size in bytes and the
+percentage saved. Requires
+.BR bc (1).
+.TP
+.BR \-\-saving\-file " \fIPATH\fR, " \-\-saving\-file= \fIPATH\fR
+Path to the savings log file written by
+.BR \-\-saving .
+Defaults to
+.B transcode_savings
+in the current working directory.
+.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.
+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.
+.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 \-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 \-h ", " \-\-help ", " \-?
+Print a short help message and exit.
+.TP
+.BR \-q ", " \-\-quiet
+Suppress all normal output. Takes precedence over
+.BR \-v / \-\-verbose .
+.TP
+.BR \-v ", " \-\-verbose
+Emit additional informational messages (detected codec, pixel format,
+etc.).
+.TP
+.B \-\-version
+Print version, author and license information and exit.
+.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
+.BR \- .
+.SH ENVIRONMENT
+.TP
+.B NO_COLOR
+When set (to any value), colored output is disabled. See
+.IR https://no-color.org/ .
+.TP
+.B FORCE_COLOR
+When set, colored output is enabled regardless of
+.B NO_COLOR
+or terminal detection.
+.TP
+.B DEBUG
+Set to
+.B 1
+to enable structured debug messages (high-level state reporting).
+.TP
+.B TRACE
+Set to
+.B 1
+to enable Bash execution tracing
+.RB ( set\ \-x ),
+which prints every command as it is executed.
+.TP
+.B XDG_CONFIG_HOME
+Base directory for user configuration. Defaults to
+.BR $HOME/.config .
+.SH FILES
+.TP
+.IR "${XDG_CONFIG_HOME:-$HOME/.config}/transcode.sh/presets/<name>.sh"
+Preset files. Each preset is sourced as Bash code and must define an
+array variable named
+.B ffargs
+containing additional arguments for
+.BR ffmpeg (1).
+The variable
+.B output_pixel_format
+is available to presets and contains the automatically selected output
+pixel format string.
+.IP
+Example preset:
+.RS
+.nf
+ffargs=( \-c:v:0 libsvtav1 \-crf 30 \-preset 6 \-pix_fmt "$output_pixel_format" )
+.fi
+.RE
+.IP
+.B Warning:
+presets are executed as shell code. Only use presets from trusted
+sources.
+.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.
+.SH EXIT STATUS
+.TP
+.B 0
+Success (or all skipped files were intentionally skipped).
+.TP
+.B 1
+Runtime failure (e.g.
+.BR ffmpeg (1)
+error on one or more files).
+.TP
+.B 2
+Usage error (invalid option or missing argument).
+.TP
+.B 3
+Configuration error (missing or invalid preset).
+.TP
+.B 127
+A required dependency
+.RB ( ffmpeg ,
+.BR ffprobe ,
+.BR nice ,
+or
+.B bc
+when
+.B \-\-saving
+is active) was not found.
+.SH EXAMPLES
+Transcode a single file using the default preset:
+.PP
+.RS
+.nf
+transcode.sh video.mp4
+.fi
+.RE
+.PP
+Transcode a batch of files listed in a file and log size savings:
+.PP
+.RS
+.nf
+transcode.sh \-s \-f list.txt
+.fi
+.RE
+.PP
+Dry-run with verbosity to inspect detected formats:
+.PP
+.RS
+.nf
+transcode.sh \-n \-v my_movie.mkv
+.fi
+.RE
+.PP
+Use a custom preset and only keep the result if it is smaller:
+.PP
+.RS
+.nf
+transcode.sh \-p av1_fast \-l /media/films/*.mkv
+.fi
+.RE
+.PP
+Run at a less aggressive niceness and skip already-AV1 files:
+.PP
+.RS
+.nf
+transcode.sh \-N 10 \-S av1 input.mkv
+.fi
+.RE
+.PP
+Use
+.BR ffmpeg (1)
+installed via Homebrew (macOS):
+.PP
+.RS
+.nf
+PATH="/opt/homebrew/bin:$PATH" transcode.sh input.mp4
+.fi
+.RE
+.SH NOTES
+The script resets
+.B PATH
+to
+.I /bin:/usr/bin:/usr/local/bin
+for security. If
+.BR ffmpeg (1)
+is installed outside these directories (e.g. via Homebrew or Nix),
+prepend the correct directory to
+.B PATH
+before invoking
+.BR transcode.sh .
+.SH SEE ALSO
+.BR ffmpeg (1),
+.BR ffprobe (1),
+.BR nice (1),
+.BR bc (1)
+.SH AUTHOR
+Dennis Fink <dennis.fink@c3l.lu>
+.SH LICENSE
+BSD\-3\-Clause