octotep cfa5d06740 docs: add Pi conversation session files as artifacts
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.
2026-05-23 00:53:26 -04:00

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.

Description
Slop translation of Beck's bash script to python to test local AI in anger
Readme 271 KiB
Languages
Python 100%