Two session JSONL files captured from ~/.pi/agent/sessions/: - 2026-05-23T03-40... — initial setup phase (5 lines) - 2026-05-23T03-46... — full development session (361 lines, 683KB) These contain the complete conversation history including all tool calls, code changes, and decisions made during this session.
SlopTranscode Worker
Batch media transcoding daemon — pulls files from a shared queue, converts them to AV1 + EAC3, optionally burns in English PGS subtitle tracks (SDH heuristic), and uploads the result back.
Purpose
This tool automates bulk video transcoding for content that ships with multiple English subtitle tracks (e.g. DVD/Blu-ray rips with both normal SUB and SDH). It detects duplicate English PGS subs, picks the right one, burns it in, and passes everything else through. Built to run unattended on a server.
Usage
The worker pulls file paths from a shared text queue — one absolute path per line:
echo '/path/to/media/file.mkv' >> /tmp/transcode/list.txt
It downloads, transcodes, and uploads the result back to the same location (overwriting the original). Empty lines are skipped automatically.
Subtitle handling
| Format | What happens |
|---|---|
| PGS (Blu-ray/DVD bitmap) | If ≥ 2 English PGS subs exist, picks the shorter one and burns it in (SDH heuristic) |
| SRT / ASS / WebVTT | Always copied as selectable tracks — never burned in |
When multiple English PGS subs are found (common: normal SUB + SDH), this tool picks the track with fewer frames. If that track covers ≥ 25% of the longest, it's rasterized into the video; otherwise both are left as selectable tracks.
Getting Started
Install ffmpeg
The worker needs ffmpeg compiled with SVT-AV1 support:
# Ubuntu/Debian (requires backports or PPA for SVT-AV1)
sudo apt install ffmpeg libsvt-av1-dev
# Fedora/RHEL / NixOS
sudo dnf install ffmpeg # or: nix-shell -p ffmpeg
# Arch Linux
sudo pacman -S svt-av1 ffmpeg
Verify it works:
ffmpeg -version | grep SVT
which ffprobe
Set up the queue
Create the shared queue file (one path per line):
mkdir -p /tmp/transcode
echo '/path/to/your/video.mkv' > /tmp/transcode/list.txt
echo '/path/to/another/file.mp4' >> /tmp/transcode/list.txt
Create local config (optional)
Copy and edit the default config. The hostname field controls how files are transferred:
cp config.toml local.toml # git-ignored, safe to edit
For a server named "Clementine":
[host]
hostname = "Clementine"
For local-only operation:
[host]
hostname = "localhost"
Run it
Test with a single file before going infinite:
cd /path/to/transcodeScript
python3 transcode.py --iterations 1 --host localhost
Run indefinitely (Ctrl-C for graceful shutdown):
python3 transcode.py --host localhost
Logs go to stdout. Set log_file in local.toml for file-based logging.
Running as a Systemd Service
Create /etc/systemd/system/sloptranscode.service:
[Unit]
Description=SlopTranscode Worker
After=network.target
[Service]
Type=simple
User=YOUR_USER
WorkingDirectory=/path/to/transcodeScript
ExecStart=/usr/bin/python3 transcode.py --host localhost
Restart=on-failure
RestartSec=10
StandardOutput=append:/var/log/sloptranscode.log
StandardError=append:/var/log/sloptranscode.log
[Install]
WantedBy=multi-user.target
Then manage it:
sudo systemctl daemon-reload
sudo systemctl enable --now sloptranscode
sudo journalctl -u sloptranscode -f # follow logs
sudo systemctl stop sloptranscode # graceful shutdown
Configuration
Three layers of configuration — later layers override earlier ones:
| Layer | File/Flag | Purpose |
|---|---|---|
| Shipped defaults | config.toml (git-tracked) |
Sensible defaults matching the original shell script |
| User overrides | local.toml or --config FILE |
Server-specific settings (git-ignored) |
| CLI arguments | --host, --log-level, etc. |
Runtime one-off overrides |
Copy config.toml to local.toml and edit. Every key is commented in the shipped file.
Required software
- Python 3.13+ (stdlib only — no pip packages needed)
- ffmpeg + ffprobe with SVT-V1 AV1 encoder support
- SSH keys configured for the target host (not needed for
localhost)
Design
Shared Queue ──dequeue──► Worker ──download──► Transcode ──upload──► Shared Queue
(list.txt) (AV1+EAC3+subs) (overwritten)
- One file at a time — no concurrency, simple mental model
- Atomic queue ops via
fcntl.flock()— safe for single-worker use - Smart subtitle handling — detects duplicate English PGS subs, burns the right one only if it covers ≥ 25% of film duration (SDH heuristic)
- Graceful shutdown — SIGTERM/SIGINT waits for current file to finish
- Automatic retry — failed files go back to the top of the queue; gives up after 60 consecutive failures
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Completed (reached iteration limit or ran indefinitely) |
| 1 | Error: missing dependencies, upload failure |
| 2 | Interrupted by signal (Ctrl-C) |
| 3 | Queue stuck empty for 50 cycles |
| 4 | Too many consecutive failures (60+) |
Experiment Note
Built as an experiment using Qwen 3.6 35B A3B Q4_K_XL + the Pi agent. The original spec was written in shell; this is the Python rewrite. See SPEC.md for the full design specification and TODO.md for the implementation plan.