/scripts

Primary LanguageShell

scripts

Personal collection of small utility scripts. This README summarizes what each script does, its requirements, usage, and examples.

Contents


auto_deint.zsh

  • Path: auto_deint.zsh
  • Purpose: For interlaced camera footage (e.g., .MTS/.m2ts), automatically decide whether to deinterlace, optionally join in‑camera “split” files, and write output with shoot-time metadata suitable for editing/archival.
  • How it works:
    • Uses ffmpeg idet sampling to estimate Progressive vs Interlaced ratio;
    • When deinterlacing is needed, applies bwdif with smart field order selection (TFF/BFF/auto);
    • Detects adjacent split parts (size near card limit, close timestamps, optional fingerprint match) and concatenates them;
    • Writes Make/Model/creation_time and can sync output mtime to the shoot time.

Requirements

  • zsh
  • ffmpeg/ffprobe (recent versions recommended)
  • macOS or Linux (handles both BSD/GNU stat)

Usage

./auto_deint.zsh <input_dir> <output_dir>
# Example: process MTS parts in current dir to ./out
./auto_deint.zsh . ./out
  • Matches *.MTS/*.m2ts under the input directory; default output is ./out.
  • You can pass a higher‑level camera/card directory (e.g. /Volumes/KESU/DV/TF_.../). The script will auto‑detect a nested .../AVCHD/BDMV/STREAM (case‑insensitive) that contains MTS files. Passing the STREAM folder directly still works as before.
  • Decision logic:
    • If Progressive ratio ≥ threshold (default 0.90), keep progressive path;
    • Otherwise deinterlace with majority vote or preferred parity.

Common environment variables (override per run)

  • Sampling and threshold
    • FRAMES: number of frames to sample (default 1500)
    • PROG_THRESH: progressive ratio threshold 0–1 (default 0.90)
  • Deinterlace/encoding and audio
    • PREFERRED_PARITY: preference when TFF/BFF close (tff/bff, default tff)
    • VCODEC: encoder: hevc_vt_main | hevc_vt_main10 | prores_hq | prores_4444 | x264_lossless (default hevc_vt_main)
    • VT_QUALITY: VideoToolbox quality 0–100 (default 80)
    • AUDIO_COPY: copy audio on progressive path (1/0, default 1)
    • PROG_VIDEO_COPY: copy video on progressive path (1=copy, 0=re-encode via VCODEC, default 0)
  • Split detection and joining
    • JOIN_SPLITS: auto | off | force (default auto)
    • MIN_SPLIT_BYTES: size considered “near limit” (bytes), e.g. 2045841408
    • SPLIT_NEAR_PCT: near-limit percentage (0–100, default 80)
    • MAX_GAP_SEC: max mtime gap between adjacent parts (seconds, default 1200)
    • CHECK_FP: verify video fingerprint (codec/size/fps/field/pixfmt) (1/0, default 1)
  • Metadata
    • MAKE/MODEL: camera info written to container and QuickTime tags

Examples

  • Deinterlace and export using ProRes HQ to a specific directory:
VCODEC=prores_hq ./auto_deint.zsh /Volumes/CAMCARD/DCIM ./out
  • Stricter progressive threshold, force join splits, do not copy audio:
PROG_THRESH=0.95 JOIN_SPLITS=force AUDIO_COPY=0 ./auto_deint.zsh . ./out

jellyfin_linker.py

  • Path: jellyfin_linker.py
  • Purpose: Symlink completed files from a downloader folder (default Transmission) into a sibling Jellyfin folder so your media server can index them. Uses a manifest to avoid duplicate links across runs.

Features

  • Recursively scans Transmission, ignoring files ending with .part;
  • Filters tiny video files by size threshold (default skip < 1 MiB; set --min-video-size 0 to disable);
  • Two linking modes:
    • --mirror (default): preserve subfolder structure inside Jellyfin;
    • --flatten: place all links in Jellyfin root; name collisions auto-suffixed with (1), (2), ...;
  • Records processed sources in Jellyfin/.link-manifest.json to avoid reprocessing;
  • Scans and removes broken symlinks in Jellyfin at the end.

Requirements

  • Python 3.8+
  • A filesystem that supports symlinks

Default layout

  • By default the script’s directory is the base containing:
    • Transmission/
    • Jellyfin/
  • Use -C/--workdir to pick another base; or override names with --transmission-name/--jellyfin-name.

Usage

# Mirror structure (default)
python3 jellyfin_linker.py

# Flatten into Jellyfin root
python3 jellyfin_linker.py --flatten

# Specify working directory
python3 jellyfin_linker.py -C /data/media

# Dry run
python3 jellyfin_linker.py --dry-run

# Ignore manifest and relink everything
python3 jellyfin_linker.py --force

# Adjust minimum video size (MiB)
python3 jellyfin_linker.py --min-video-size 5

Exit and summary

  • Prints a summary of created/skipped/collisions/cleanup so you can verify batch results.

Development

  • Platform: written and verified on macOS; works on Linux as well (mind ffmpeg/stat differences).
  • Tip: start with --dry-run or a small sample before batch runs.
  • Contributions: PRs/issues welcome; inline comments and improvements are appreciated.