Files
flan 016a4ad0c1 Add M4 cut + serve: end-to-end ad-free feed pipeline (v0.4.0)
adscrub cut: merges overlapping ad spans from any source (chapter, LLM
-- no dedup rule needed, overlap-merging handles it), ffmpeg-extracts
the surviving audio, concatenates with -c copy (no re-encode). Episode
duration comes from ffprobe on the real file, not RSS metadata.

adscrub serve: stdlib http.server (dependency-free, same approach as
hark's web.py) regenerates a cleaned RSS feed live at GET /feed/<id>.
Cut episodes serve locally at /audio/<id>.<ext>; everything else keeps
its original audio_url unchanged -- nothing gets a local copy unless
it was actually cut. No login wall (trusted-network machine-consumed
feed, not a browsable dashboard). Warns instead of silently producing
a broken feed if --base-url is left at the unreachable localhost
default.

Split download_audio/probe_duration out of transcribe.py into a new
audio.py, since cut.py needed the same downloaded-audio cache.

Docker default CMD now runs adscrub serve (port 8711); pipeline stages
stay one-shot docker compose run commands.

Full pipeline (ingest -> chapters -> transcribe -> detect -> cut ->
serve) is now built end-to-end, all mocked/fixture-tested -- real
audio quality and AntennaPod compatibility are still unverified.
2026-07-10 23:57:18 +00:00

23 lines
811 B
YAML

# docker compose up -d serves the feed(s) :8711
# docker compose run --rm adscrub add-feed https://feeds.example.com/show
# docker compose run --rm adscrub ingest
# docker compose run --rm adscrub chapters
# docker compose run --rm adscrub transcribe # CPU by default — see compose.gpu.yaml
# docker compose run --rm adscrub detect
# docker compose run --rm adscrub cut
#
# ADSCRUB_BASE_URL must be set to wherever the podcast player can actually
# reach this container (not localhost) — it's embedded in generated feeds'
# audio links.
services:
adscrub:
build: .
image: adscrub:latest
ports:
- "8711:8711"
environment:
ADSCRUB_BASE_URL: ${ADSCRUB_BASE_URL:-http://localhost:8711}
volumes:
- ./data:/app/data
restart: unless-stopped