amuxify

Checks downloaded and purchased video before it goes into your Plex or Jellyfin library.

amuxify is a command-line tool for video you downloaded or bought. Run it on the files wherever they landed, on your laptop or on the download box: scan tells you which files are damaged or carry something that has no place in a video file, clean strips the metadata, and remux rebuilds the file into a sanitized MKV. Only then does the file move to your library or NAS. The same commands run unattended as a SABnzbd, NZBGet, Sonarr or Radarr script, where a bad file fails the job and never reaches the library. Streams are never re-encoded.

v0.4.0 · Linux, macOS, Docker · BSD-3-Clause

$ amuxify scan ~/incoming
PASS  /home/me/incoming/Show.S01E01.mkv
WARN  /home/me/incoming/Movie.2019.mkv
      WARN  LINK_IN_TAG        1 link(s) in metadata: tag COMMENT: http://tracker.example/x
BLOCK /home/me/incoming/Movie.2019.Sub.mkv
      BLOCK ATTACH_EXEC        attachment #1 "font.ttf" (font/ttf, 71 KiB) contains executable PE/DOS executable

BLOCK: 3 file(s) BLOCK=1 PASS=1 WARN=1

The third file has a Windows program packed inside it as a subtitle font. A media server would import it without complaint.

What it catches

The profile decides what gets fixed. The default one strips titles, tags and purchase details, keeps every audio and subtitle track, and drops font attachments only when the file has no text subtitle track that could use them. The other profiles also drop commentary tracks, languages you did not ask for, chapters or attachments. Before a rebuilt file is placed, each stream it kept is hashed and compared with the source. amuxify does not transcode, rename or organise your library; Sonarr and Radarr still do that.

Where it fits

The SABnzbd script is one line:

exec amuxify --profile "${AMUXIFY_PROFILE:-homelab}" hook sabnzbd "$@"

Scripts for each tool ship in contrib/hooks/ and the Docker image. Setup steps are in docs/hooks.md.

Install

amuxify needs MKVToolNix 50 or newer and ffmpeg 4.4 or newer on the same machine. exiftool and clamscan are optional. amuxify doctor tells you what is missing.

# release binary, Linux and macOS (verifies the SHA-256 checksum)
curl -fsSL https://raw.githubusercontent.com/amuxify/amuxify/main/install.sh | sh

# Homebrew
brew install --cask amuxify/tap/amuxify

# Docker, run as the uid that owns the library, never root
docker run --rm -u 1000:1000 -v /srv/media/incoming:/data ghcr.io/amuxify/amuxify scan /data

The install guide covers package names per distro, pinning a version and the Docker image.

Safety

A rebuilt file is written beside the destination and only takes its place once every kept stream's hash matches the source; if one does not, the rebuilt file is deleted and the original stays. amuxify will not write over some other file that already sits at the destination, and it skips symlinks. It refuses to modify files as root unless told to, and no flag overrides a BLOCK. docs/safety.md lists all ten guarantees, each with a test.

Reference

Commands

CommandWhat it doesWrites
scanReport findings and a verdict per filenothing, unless --quarantine moves BLOCK files into a mirrored tree under that directory
ingestScan, then rebuild into a verified MKV or clean in placethe file in place; a rebuild is hash-verified before it replaces the original
hookRun ingest from SABnzbd, NZBGet, Sonarr or Radarr and exit the way that program expectsas ingest
watchPoll a directory and run ingest on each file once it has stopped changing; for a sidecar container or a drop folderas ingest
remuxRebuild into a sanitized MKV in a mirrored tree beside the input root, or replace the original with --in-place<root>__remuxed/, --output or --in-place
cleanStrip metadata in place, tracks untouchedthe file; MP4, MOV, AVI and FLV are rewritten to a temp file and hash-verified before they replace the original, MKV and WebM headers are edited in place by mkvpropedit
doctorCheck tools, version floors, profile and environmentnothing
profileList the built-in profiles or print onenothing

Reads MKV, WebM, MP4, M4V, MOV, AVI, MPEG-TS, M2TS, MPG, VOB and FLV. A rebuilt file is always MKV, written by mkvmerge; clean keeps MP4-family and AVI files in their own container.

Verdicts

VerdictExitMeaning
PASS0Nothing to report
WARN1Worth knowing; the file is usable
FAIL3The file failed a check and nothing is written for it: truncated, unparseable, mislabeled, a rebuilt copy whose hashes did not match, a destination that already exists, or a finding such as a tracker link that the profile treats as a failure
BLOCK4Dangerous: executable payload, polyglot, hidden characters in the filename or blocked sidecar

The worst verdict of the run is the exit code; 2 means a usage error and 130 an interruption. --json prints the full report, described in docs/report.md.

Profiles

ProfileLanguagesChaptersFontsCommentaryLinks / provenanceVerify
homelab (default)keep all, prefer originalkeepkeep if text subskeepwarnquick
animekeep all, prefer originalkeepkeepdropwarnquick
archiveEnglish onlydropdropdropfailquick
strictEnglish onlydropdropdropfailfull + ClamAV

A profile is a TOML file; amuxify profile show homelab prints one to start from. Unknown keys are rejected, so a typo cannot loosen a policy. All keys are in docs/profiles.md.