Skip to content

ChrisCarden/auto-transcode-watcher

Repository files navigation

Auto Transcode Watcher (Python + watchdog + FFmpeg)

A production-ready folder watcher that automatically transcodes newly added video files using ffmpeg, with safe file stabilization (waits until copy finishes), queueing, retries, renaming templates, and rotating logs.

Features

  • Watch a directory (recursively or not) and transcode new files as they arrive
  • File stabilization: wait until size stops changing before processing
  • Queue + worker pool to handle bursts
  • Robust rename templates: {event}, {date}, {time}, {basename}, {ext}, {counter}
  • Atomic writes: encode to *.tmp then rename to final name
  • Rotating logs in ./logs/transcoder.log
  • Configurable via YAML
  • Cross-platform (macOS, Windows, Linux)

Requirements

  • Python 3.9+ recommended
  • FFmpeg installed (available in your PATH), or set ffmpeg_path in the config

Quickstart

# 1) Setup venv (recommended)
python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS/Linux:
source .venv/bin/activate

# 2) Install deps
pip install -r requirements.txt

# 3) Create config from example
cp config.example.yaml config.yaml
# Edit config.yaml as needed (watch_dir, output_dir, event_name, etc.)

# 4) Create folders (or let the script do it)
mkdir -p input_videos output_videos logs

# 5) Run watcher
python watch_and_transcode.py -c config.yaml

One-shot mode (process any existing files and exit)

python watch_and_transcode.py -c config.yaml --once

Config (config.example.yaml)

event_name: "StudioEvent"
output_dir: "output_videos"
rename_template: "{event}_{date}_{basename}.mp4"

watch_dir: "input_videos"
recursive: true
include_extensions: [".mov", ".mxf", ".avi", ".mp4", ".m4v", ".mkv", ".wmv", ".mts"]

ffmpeg_path: "ffmpeg"
video_codec: "libx264"
preset: "fast"
crf: 23
audio_codec: "aac"
audio_bitrate: "192k"
copy_audio_when_possible: false

stabilization_seconds: 4
stabilization_poll_interval: 1
max_retries: 2
retry_backoff_seconds: 5

workers: 2

log_dir: "logs"
log_level: "INFO"

Rename Template Variables

  • {event}event_name from config
  • {date}YYYY-MM-DD (current)
  • {time}HH-MM-SS (current)
  • {basename} → source file name without extension
  • {ext} → source file extension without the dot
  • {counter} → optional index if you add it to the template; the script also auto-appends _02, _03, ... on collisions

Simulate Incoming Files

Use the included script to simulate slow file arrival (like camera copies or network ingest):

# Activate venv, then:
python tools/simulate_ingest.py input_videos path/to/BigVideo.mov --chunk-bytes 262144 --sleep 0.5

It copies the file in chunks into the watch folder so you can verify stabilization behavior.

Service/Daemon Examples

Linux (systemd)

Create /etc/systemd/system/auto-transcode.service:

[Unit]
Description=Auto Transcode Watcher
After=network.target

[Service]
Type=simple
WorkingDirectory=/path/to/auto-transcode-watcher
ExecStart=/path/to/auto-transcode-watcher/.venv/bin/python watch_and_transcode.py -c config.yaml
Restart=on-failure
User=youruser
Group=yourgroup
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target

Enable & start:

sudo systemctl daemon-reload
sudo systemctl enable auto-transcode.service
sudo systemctl start auto-transcode.service

macOS (launchd)

Create ~/Library/LaunchAgents/com.studio.auto-transcode.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key><string>com.studio.auto-transcode</string>
    <key>ProgramArguments</key>
    <array>
      <string>/path/to/auto-transcode-watcher/.venv/bin/python</string>
      <string>/path/to/auto-transcode-watcher/watch_and_transcode.py</string>
      <string>-c</string>
      <string>/path/to/auto-transcode-watcher/config.yaml</string>
    </array>
    <key>WorkingDirectory</key><string>/path/to/auto-transcode-watcher</string>
    <key>RunAtLoad</key><true/>
    <key>StandardOutPath</key><string>/path/to/auto-transcode-watcher/logs/launchd.out</string>
    <key>StandardErrorPath</key><string>/path/to/auto-transcode-watcher/logs/launchd.err</string>
  </dict>
</plist>

Load it:

launchctl load ~/Library/LaunchAgents/com.studio.auto-transcode.plist
launchctl start com.studio.auto-transcode

Windows

  • Use Task Scheduler to run the script at logon, or
  • Use NSSM to wrap the script as a service:
    1. nssm install AutoTranscodeWatcher
    2. Application path: C:\path\to\auto-transcode-watcher\.venv\Scripts\python.exe
    3. Arguments: watch_and_transcode.py -c config.yaml
    4. Startup directory: C:\path\to\auto-transcode-watcher

Roadmap Ideas

  • Simple desktop GUI (PyQt/Tkinter)
  • E-mail/Slack notifications on failures
  • Cloud upload (S3/Drive) after success
  • Optional rewrap-only (copy video/audio) if codecs already compliant
  • Thumbnail generation & basic proxy workflows

License

MIT (see LICENSE)

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages