| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add --video-stream and [encoding].video_stream so users can choose which
input video stream is probed for preset helper variables.
Use the selected stream for codec, pixel format, frame rate, output
pixel format, and GOP size metadata while leaving preset stream mapping
unchanged.
Validate CLI stream selectors strictly and ignore invalid config values
with a warning so bad configuration falls back to the default v:0
stream.
Document the new option in the README and man page, add verbose dry-run
output, and provide bash completion for common video stream selectors.
Closes #6.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Export ffmpeg/libav color environment variables alongside transcode.sh
color detection so subprocess logs follow the same color mode as the
wrapper.
Set AV_LOG_FORCE_COLOR when colors are forced or stdout is interactive,
and set AV_LOG_FORCE_NOCOLOR when NO_COLOR is present or output is
non-interactive.
Also propagate explicit --color and --no-color choices so later CLI
overrides stay consistent with ffmpeg output.
|
| |
|
|
|
|
|
|
| |
Keep CLI sentinel variables and bash completion options ordered
consistently so related skip-codec settings stay grouped together.
Align the --backup-dir help text spacing with neighboring options for
cleaner terminal output.
|
| |
|
|
|
|
|
|
|
|
|
| |
Add --ffmpeg-loglevel so users can choose which ffmpeg messages are
shown during encoding instead of always using the built-in default.
Load the same setting from [output].ffmpeg_loglevel when it is
configured and no CLI value was provided.
Document the new option in the README and man page, and add shell
completion for supported ffmpeg log levels.
|
| |
|
|
|
|
|
|
|
| |
Add contrib/archlinux as a git submodule pointing to the AUR package
repository for transcode.sh.
Keep AUR-specific generated files, such as .SRCINFO, tracked separately
from the main project while still allowing packaging files to live under
contrib.
|
| | |
|
| |
|
|
|
|
|
|
| |
Add release version and revision date markers to the README so release
tooling can update visible project metadata automatically.
Expose the current packaged version near the top of the README without
changing the rest of the documentation structure.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Add initial contributed presets for AV1/SVT-AV1, H.264/x264, H.265/x265,
and VP9/libvpx-vp9.
Provide fast, balanced, and high-quality variants where applicable so
users can choose between encode speed, compression efficiency, and
visual quality.
Include preset descriptions and use derived GOP size and pixel format
settings where appropriate for consistent behavior with transcode.sh.
|
| |
|
|
|
|
|
|
|
| |
Add SPDX copyright and license markers to repository metadata and
documentation files.
Use comment styles appropriate for git attributes, gitignore, the commit
message template, README, and justfile so license metadata is visible
without changing runtime behavior.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Add a developer script that uses ffmpeg lavfi sources to create
synthetic video test files without storing binary media in the
repository.
Allow callers to choose codec, resolution, duration, frame rate, source
filter, pixel format, output path, and overwrite behavior from the
command line.
Expose the generator through just and ignore generated testfiles in git.
|
| |
|
|
|
|
|
|
| |
Split the release helper into clearer section headers that match the
main script structure.
Move terminal color detection into main execution so function
definitions stay grouped together before the executable flow.
|
| |
|
|
|
|
|
|
|
|
|
| |
Add --skip-codec-override so users can ignore configured skip codecs for
a single run and use only codecs provided through --skip-codec.
Defer CLI skip-codec parsing until after config loading so the final
skip list can be resolved independently of option order.
Document the new override behavior in the README and man page, and add
shell completion for the new flag.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Add --backup-dir support so successful encodes can copy the original
file to an existing backup directory before replacing it.
Preserve each source file's absolute path below the backup directory and
avoid overwriting existing backups by appending numeric suffixes when
needed.
Document the new CLI and config option, and add directory completion for
the backup path.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Keep nice validation focused on accepting integer values instead of
rejecting values outside the standard -20 to 19 range.
Avoid failing early for values that nice itself accepts and clamps
internally. This gives users behavior that matches the underlying tool
instead of turning a non-error into a transcode.sh usage error.
Update help text and README wording to describe the option as a nice
adjustment, matching the command behavior.
|
| |
|
|
|
|
|
|
|
| |
Add a file structure overview and split the script into clearer section
headers so related functions are easier to find.
Move main execution below all function definitions and add local
subsection comments inside encode_one without changing the script
behavior.
|
| |
|
|
|
|
|
|
|
| |
Rename generic preset path variables to make the preset loading and
listing code easier to read.
Use explicit names such as preset_file and preset_name so the code
better communicates which values refer to files and which refer to
display names.
|
| |
|
|
|
|
|
|
|
| |
Add a dedicated release helper so version and revision metadata can be
prepared consistently before publishing a new release.
Use git attributes to keep developer tooling and repository metadata out
of generated source archives. Also ignore the dist directory created
during the release process.
|
| |
|
|
|
|
|
|
| |
Move the preset security note before the preset path so readers see the
warning before creating or sourcing preset files.
Align the size report schema header with spaces for cleaner rendered
documentation.
|
| |
|
|
|
|
|
|
|
| |
Move the skip-codec check directly after codec detection, before
validating pixel format and frame rate.
This lets files with excluded codecs return early without requiring
additional probe fields that are irrelevant when the file will not be
encoded.
|
| |
|
|
|
|
|
|
|
|
|
| |
Replace three separate `printf | sed` pipelines with a single grouped
`read` block fed from the existing ffprobe output.
This keeps codec, pixel format, and frame-rate parsing together, avoids
extra subprocesses, and makes the field order easier to see at the call
site.
No runtime behavior is intended to change.
|
| |
|
|
|
|
|
|
|
|
|
| |
Track the total encoded output size alongside the original and saved
byte counts so the batch summary can show original vs. new totals.
Improve size report feedback for larger outputs by printing the byte
difference as “larger” instead of showing a negative saved value. Rework
the final summary format to include colored encoded, skipped, failed,
total-size, and average saving lines, with skipped and failed counts
broken down by reason.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Replace compact `[[ ... ]] || { ... }` guard blocks with explicit `if`
statements in config loading, preset loading, CLI argument validation,
size report helpers, and encode-file handling.
Rename the local preset variable in `load_preset` to `preset_name` for
clearer intent, and simplify the nice-value range check and size-report
summary default percentage handling.
No runtime behavior is intended to change.
|
| |
|
|
|
|
|
|
|
| |
Rewrap long comments throughout transcode.sh for more consistent line
length and readability. Clarify a few explanatory comments around
filesize formatting, preset descriptions, empty input handling, ffprobe
probing, temporary output creation, and output verification.
No runtime behavior is changed.
|
| |
|
|
|
|
|
|
| |
Correct the README entry for the long --encode-file=PATH form, which was
documented as --encodefile=PATH.
Also fix spacing in the generated help text for output_gop_size so the
preset variable descriptions remain aligned.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a shared emit() helper for styled terminal output and route error(),
msg(), warn(), verbose(), and debug() through it.
This removes duplicated printf formatting across the output helpers
while keeping the existing prefixes, colors, quiet/verbose/debug gating,
and stderr handling for errors. emit() also joins additional message
arguments into a single trailing string, matching the output pattern
used by the individual helpers.
The output helpers now differ only in their prefix, color, and
visibility condition, making future formatting changes easier and less
error-prone.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Rename the old savings log feature to size report across the CLI,
configuration, documentation, man page, and bash completion. The new
`--size-report` option keeps the existing `-s` shorthand, while
`--saving`, `--saving-file`, and the `[saving]` config section are
replaced by `--size-report`, `--size-report-file`, and `[size_report]`.
Extend reporting beyond successful encodes. The TSV log now gains a
leading `status` column and records encoded files, codec skips,
only-if-larger skips, and failed inputs. Size-report output also prints
per-file feedback for encoded and skipped-larger files, including
human-readable original/new sizes, bytes saved, and saved percentage.
Track batch-level report counters and print an end-of-run summary for
multi-file runs with encoded/skipped/failed counts, total bytes saved,
and the overall weighted saving percentage across successful encodes.
Document the new TSV schema in the README and man page, update examples
and config snippets, and adjust bash completion for the renamed options.
BREAKING CHANGE: `--saving` is now `--size-report`. `--saving-file` is
now `--size-report-file`. `[saving]` in config.toml is now
`[size_report]`. The TSV log gains a leading `status` column and may
contain skipped and failed rows in addition to successful encodes.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Expand compact shell conditionals into explicit if blocks throughout
config loading, codec parsing, cleanup, and file-list handling. Rename
short local variables in encode_one to more descriptive names, including
the input file, temporary output path, command array, and progress
counters.
Also align preset-list output with the shared msg helper and update
colors for preset names.
This makes the main transcoding path easier to read and maintain without
changing the intended encoding behaviour.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Both tools were used for simple arithmetic that bash handles natively.
awk: fps rounding (num/den) replaced with round-half-up integer
arithmetic: (num + den/2) / den.
bc: savings percentage replaced with bash $(( )) arithmetic. bc was a
conditional dependency (only required with --saving), which made the
dependency story inconsistent. Removing it means the full feature set is
available with only ffmpeg, ffprobe, nice, and optionally tomlq.
Updated README requirements table, man page --saving description, SEE
ALSO section, and exit-code 127 entry accordingly.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Print all *.sh files found in $PRESET_DIR, one per line, with a one-line
description extracted from the first line of each file if it matches a
`# description: …` comment. Presets without such a comment are listed
without a description.
Symlinks pointing to another preset inside $PRESET_DIR are shown as
"<name> - Symlinked to <target>" rather than duplicating the
description. Symlinks pointing outside $PRESET_DIR are followed and
treated as regular preset files.
Column width for preset names is calculated from the longest name in the
directory so descriptions align with minimal padding.
Also extracts the repeated readlink/realpath idiom into a dedicated
resolve_path() helper and adds a doc comment to filesize().
Exits immediately after printing (same pattern as --version/--help).
Honours --quiet/NO_COLOR via the existing msg() and color
infrastructure.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add --hwaccel [METHOD] / --no-hwaccel flags to control whether -hwaccel
is passed to ffmpeg before the input file. The METHOD argument is
optional and defaults to "auto", letting ffmpeg select the best
available hardware decoder with automatic software fallback.
Hardware acceleration is enabled by default (method: auto). Users on
hosts where hwaccel causes compatibility or stability issues can opt out
with --no-hwaccel or config.toml [encoding] hwaccel = false.
The config key accepts false (disable), true (auto), or a method string
such as "vaapi" or "cuda". CLI flags take precedence as usual.
Bash completion is extended with a hwaccel_methods word list (auto,
cuda, vaapi, dxva2, d3d11va, videotoolbox, qsv) for both the space form
(--hwaccel <TAB>) and the equals form (--hwaccel=<TAB>).
The completion script is also reformatted from 4-space to 2-space
indentation for consistency with transcode.sh itself.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
PATH='/bin:/usr/bin:/usr/local/bin' was intended as a security measure
against PATH injection. For a script invoked manually in the user's own
shell the benefit is marginal: if an attacker controls the user's PATH
they already have larger problems. The cost is real — tools installed
outside these three directories (Homebrew, Nix, ~/.local/bin) silently
fail, and the documented workaround of prepending a path at invocation
time does not work because the script overwrites PATH immediately on
startup.
Remove the PATH reset and all associated documentation. The remaining
hardening measures (unalias -a, hash -r, strict set -o flags, umask) are
retained.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
After ffmpeg exits successfully, run ffprobe against the temporary
output file to confirm it is a valid, playable media file before
replacing the original. If the probe fails the temporary file is removed
and the encode is treated as a runtime failure, leaving the original
untouched.
This guards against cases where ffmpeg exits 0 but has written a
truncated or corrupt container (e.g. due to a disk-full condition
mid-write, a codec bug, or a preset producing an unreadable stream).
The check is enabled by default and can be disabled via
--no-verify-output or [encoding] verify_output = false in config.toml
for large batch jobs on trusted encoders where the extra ffprobe
round-trip is undesirable.
The --continue flag is honoured: a failed integrity check counts as a
runtime failure for the purposes of deciding whether to proceed to the
next file.
Docs, man page, bash completion, and README updated accordingly.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add input_frame_rate, input_fps, and output_gop_size to the set of
variables available to preset files at source time.
input_frame_rate is the raw ffprobe fraction (e.g. 30000/1001).
input_fps rounds that fraction to the nearest integer via awk.
output_gop_size is derived as roughly five seconds of video (input_fps *
5), capped at 300 frames.
The ffprobe invocation is extended to request r_frame_rate alongside the
existing codec_name and pix_fmt entries; a missing frame rate is now
treated as a hard error. Dry-run and verbose output are updated to
display the new values. Documentation (header comment, --help text, man
page, README) is updated accordingly.
|
| |
|
|
|
|
|
|
|
|
|
| |
The contact address dennis.fink@c3l.lu has been replaced with
me+coding@dennisfink.me across all files where it appeared:
SPDX-FileCopyrightText, AUTHOR constant, --version output,
README footer, LICENSE file, and the man page AUTHOR section.
SPDX licence headers were also added to transcode.sh.1 and
transcode.sh.bash-completion to bring all files into full
REUSE compliance.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a structured config file so common defaults can live in one place
instead of being repeated in aliases or shell wrappers. CLI flags keep
precedence, which keeps one-off overrides predictable.
Use tomlq only when a config file is present, and fail early on missing
dependencies or invalid TOML so configuration mistakes do not silently
change encode behavior.
Move the persistent skip-codec list from the legacy skip.conf file to
[skip] codecs in config.toml. Config codecs are merged with --skip-codec
so global defaults and per-run skips can be combined.
Document the new format in the README and man page, update dependency
notes, and extend bash completion for config-file paths and the new
negative boolean flags.
BREAKING CHANGE: skip.conf is no longer read for codec skips. Migrate
its entries to [skip] codecs in config.toml and remove the old file.
BREAKING CHANGE: --encodefile and --encodefile= are replaced by
--encode-file and --encode-file=. Update scripts, aliases, and
completion usage to use the hyphenated option name.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Rewrite `print_help` to use the full color palette and group options into
labeled sections (Encoding, Input, Savings log, Output, General, and a
new Configuration files section). The Configuration files section
documents the preset directory and skip.conf path, including the
variables available to preset authors and the security note about
trusted sources.
Default values for `--preset`, `--nice`, and `--saving-file` are now shown
inline using `$PRESET_NAME`, `$NICE_VALUE`, and `$SAVING_FILE` rather than
being hardcoded, so they always reflect the actual defaults.
Rewrite `print_version` to inline the BSD-3-Clause license text directly
instead of conditionally catting `LICENSES/BSD-3-Clause.txt`. This makes
`--version` self-contained regardless of where the script is invoked from.
Apply the same color treatment to the short usage hint printed when no
arguments are given.
|
| | |
|
| |
|
|
|
|
|
| |
Reverts commit b10b81fefbe529be7db14ca65ec4b4a293782d39.
The nameref approach did not work as intended; reverting to restore
correct behaviour.
|
| | |
|
| |
|
|
| |
Joining into a single string ensures the entire list renders uniformly.
|
| |
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- 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
|
| | |
|
| |
|
|
|
| |
Replaces $$.$RANDOM with mktemp, which provides cryptographically
random names and atomic file creation.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|