update
This commit is contained in:
commit
b95395bd04
7 changed files with 334 additions and 0 deletions
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Created by https://www.toptal.com/developers/gitignore/api/vim
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=vim
|
||||
|
||||
# Sphinx build output
|
||||
/docs/build/
|
||||
|
||||
# Optional extras
|
||||
docs/source/_build/
|
||||
docs/source/*.mo
|
||||
|
||||
|
||||
### Vim ###
|
||||
# Swap
|
||||
[._]*.s[a-v][a-z]
|
||||
!*.svg # comment out if you don't need vector files
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-rt-v][a-z]
|
||||
[._]ss[a-gi-z]
|
||||
[._]sw[a-p]
|
||||
|
||||
# Session
|
||||
Session.vim
|
||||
Sessionx.vim
|
||||
|
||||
# Temporary
|
||||
.netrwhist
|
||||
*~
|
||||
# Auto-generated tag files
|
||||
tags
|
||||
# Persistent undo
|
||||
[._]*.un~
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/vim
|
||||
167
convert_dir.sh
Normal file
167
convert_dir.sh
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#!/bin/bash
|
||||
|
||||
debug() { echo "🛠️ DEBUG: $*" >&2; }
|
||||
|
||||
# Convert .avi and .mkv files to .mp4
|
||||
# Supports --dry-run to simulate actions
|
||||
# --source is required; --archive is optional
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --- Defaults ---
|
||||
DRY_RUN=false
|
||||
DEBUG=false
|
||||
SRC_DIR=""
|
||||
ARCHIVE_DIR=""
|
||||
LOG_FILE="log.convert"
|
||||
QUALITY="23"
|
||||
|
||||
SRC_TYPES=()
|
||||
|
||||
# --- Help Message ---
|
||||
show_help() {
|
||||
echo "Usage: $0 --source <src_dir> [--archive <archive_dir>] [--quality ] [--dry-run] [--debug]"
|
||||
echo
|
||||
echo " --source Directory to scan for .avi and .mkv files"
|
||||
echo " --archive Directory to move originals after conversion (optional)"
|
||||
echo " If omitted, originals will be deleted"
|
||||
echo " --quality Quality of the video 18-28 (18 is high quality, 23 is default, 28 is low)"
|
||||
echo " --dry-run Show actions without performing them"
|
||||
echo " --debug Output debug statements"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Parse Arguments ---
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--source)
|
||||
SRC_DIR="$(realpath "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--archive)
|
||||
ARCHIVE_DIR="$(realpath "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN=true
|
||||
shift
|
||||
;;
|
||||
--debug)
|
||||
DEBUG=true
|
||||
shift
|
||||
;;
|
||||
--src-type)
|
||||
SRC_TYPES+=("${2,,}") # normalize to lowercase
|
||||
shift -2
|
||||
;;
|
||||
--help|-h)
|
||||
show_help
|
||||
;;
|
||||
--quality)
|
||||
QUALITY="$2"
|
||||
if ! [[ "$QUALITY" =~ ^[0-9]+$ ]] || ((QUALITY < 18 || QUALITY > 28)); then
|
||||
echo "❌ Error: --quality must be an integer between 18 and 28." >&2
|
||||
exit 1
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "${#SRC_TYPES[@]}" -eq 0 ]]; then
|
||||
SRC_TYPES=("avi" "mkv") # default id none specified
|
||||
fi
|
||||
|
||||
# --- Validate Source Directory ---
|
||||
if [[ -z "$SRC_DIR" ]]; then
|
||||
echo "❌ Error: --source is required." >&2
|
||||
show_help
|
||||
fi
|
||||
|
||||
if [[ ! -d "$SRC_DIR" ]]; then
|
||||
echo "❌ Error: Source directory does not exist: $SRC_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔍 Scanning: $SRC_DIR"
|
||||
$DRY_RUN && echo "🧪 Dry-run mode enabled"
|
||||
|
||||
# --- Gather file list once ---
|
||||
mapfile -d '' FILE_LIST < <(find "$SRC_DIR" \( -iname '*.avi' -o -iname '*.mkv' \) -print0)
|
||||
|
||||
# --- Preview list if in debug mode ---
|
||||
if [[ "${DEBUG:-false}" == "true" ]]; then
|
||||
echo "🗂️ DEBUG: File list to process:"
|
||||
for file in "${FILE_LIST[@]}"; do
|
||||
echo " - $file"
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# --- Find and Process Files ---
|
||||
# Using process substitution instead of a pipe, so the while loop runs in the current shell
|
||||
for src_file in "${FILE_LIST[@]}"; do
|
||||
# abs_src_file="$(realpath "$src_file")"
|
||||
# rel_path="${abs_src_file#$SRC_DIR/}"
|
||||
|
||||
# Use absolute path If the source file path is not absolute
|
||||
# (doesn't start with '/'), prepend the source directory to
|
||||
# make it an absolute path.
|
||||
[[ "$src_file" != /* ]] && src_file="$SRC_DIR/$src_file"
|
||||
|
||||
rel_path="${src_file#$SRC_DIR/}"
|
||||
|
||||
base_name="${rel_path%.*}"
|
||||
dst_file="$SRC_DIR/$base_name.mp4"
|
||||
|
||||
echo "▶️ Converting: $rel_path"
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo " [dry-run] Would convert to: $dst_file"
|
||||
[[ -n "$ARCHIVE_DIR" ]] && echo " [dry-run] Would move original to: $ARCHIVE_DIR/$rel_path" || echo " [dry-run] Would delete original"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Create output directory if needed
|
||||
mkdir -p "$(dirname "$dst_file")"
|
||||
|
||||
if [[ "${DEBUG:-false}" == "true" ]]; then
|
||||
debug "dirname dst_file: $(dirname "$dst_file")"
|
||||
debug "src_file: $src_file"
|
||||
# debug "abs_src_file: $abs_src_file"
|
||||
debug "rel_path: $rel_path"
|
||||
debug "base_name: $base_name"
|
||||
debug "dst_file: $dst_file"
|
||||
debug ""
|
||||
debug "command:"
|
||||
debug "ffmpeg -i \"$src_file\" -c:v libx264 -preset slow -crf $QUALITY -c:a aac -b:a 128k -movflags +faststart \"$dst_file\" -y >> $LOG_FILE 2>&1"
|
||||
fi
|
||||
|
||||
# Convert video with ffmpeg and log output
|
||||
ffmpeg \
|
||||
-i "$src_file" \
|
||||
-c:v libx264 \
|
||||
-preset slow \
|
||||
-crf "$QUALITY" \
|
||||
-c:a aac \
|
||||
-b:a 128k \
|
||||
-movflags +faststart \
|
||||
"$dst_file" \
|
||||
-y >> "$LOG_FILE" 2>&1
|
||||
|
||||
# Archive or delete original
|
||||
if [[ -n "$ARCHIVE_DIR" ]]; then
|
||||
archive_file="$ARCHIVE_DIR/$rel_path"
|
||||
mkdir -p "$(dirname "$archive_file")"
|
||||
mv "$src_file" "$archive_file"
|
||||
else
|
||||
rm "$src_file"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "✅ Done."
|
||||
20
docs/Makefile
Normal file
20
docs/Makefile
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = source
|
||||
BUILDDIR = build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
35
docs/make.bat
Normal file
35
docs/make.bat
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
@ECHO OFF
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set SOURCEDIR=source
|
||||
set BUILDDIR=build
|
||||
|
||||
%SPHINXBUILD% >NUL 2>NUL
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.https://www.sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
goto end
|
||||
|
||||
:help
|
||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||
|
||||
:end
|
||||
popd
|
||||
28
docs/source/conf.py
Normal file
28
docs/source/conf.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'convert-dirs'
|
||||
copyright = '2025, Ronny Abraham'
|
||||
author = 'Ronny Abraham'
|
||||
release = '1.0.0'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
|
||||
extensions = []
|
||||
|
||||
templates_path = ['_templates']
|
||||
exclude_patterns = []
|
||||
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
html_theme = 'alabaster'
|
||||
html_static_path = ['_static']
|
||||
25
docs/source/index.rst
Normal file
25
docs/source/index.rst
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
.. convert-dirs documentation master file, created by
|
||||
sphinx-quickstart on Mon May 12 02:16:34 2025.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to convert-dirs's documentation!
|
||||
========================================
|
||||
|
||||
A Bash script to batch convert `.avi`, `.mkv`, etc. to `.mp4` using ffmpeg.
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
usage
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
26
docs/source/usage.rst
Normal file
26
docs/source/usage.rst
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
Usage Guide
|
||||
===========
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./convert-dirs.sh --source ./tv \
|
||||
--src-type avi \
|
||||
--src-type mkv \
|
||||
--quality 23 \
|
||||
--dry-run
|
||||
|
||||
Options:
|
||||
|
||||
- ``--source``: Directory to scan (required)
|
||||
- ``--archive``: Where to move originals
|
||||
- ``--src-type``: File extension to include (repeatable)
|
||||
- ``--quality``: CRF value for ffmpeg (18 = high, 28 = low)
|
||||
- ``--dry-run``: Simulate actions
|
||||
- ``--debug``: Show extra output
|
||||
|
||||
Requirements
|
||||
|
||||
- bash
|
||||
- ffmpeg
|
||||
Loading…
Add table
Reference in a new issue