ssmithxandClaude Fable 5 6dd541b1a4 fix: blossom v4 config schema, container-internal blossom URL, e2e suite
- blossom-server 4.4.1 expects rules nested under storage: — the top-level
  rules list was ignored, leaving an empty ruleset that rejected all uploads
- podpuddle now verifies blobs and uploads recordings via BLOSSOM_URL_INTERNAL
  (http://blossom:3000) while feeds keep the browser-facing URL; unreachable
  blossom now returns 502 instead of a 500
- mediamtx: fix deprecated allow-origin params, disable MoQ
- scripts/e2e.mjs: 14 API checks (login, replay/URL rejection, upload,
  episode, feed, stream keys, mediamtx auth) — all green, plus verified
  live: RTMP publish with key → HLS 200, wrong key refused, status
  planned→live→ended via poller, recording remuxed + published as episode,
  feed XML well-formed with 2 items

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 19:21:03 +00:00

podpuddle

Self-hosted, nostr-native podcast publishing and livestreaming.

  • Log in with nostr — NIP-07 browser extension (Alby, nos2x, …); the server verifies NIP-98 signed requests. No passwords, no email.
  • Upload an mp4 → it is stored on a Blossom server (bundled, or point at any external one) and published in an RSS 2.0 podcast feed with Podcasting 2.0 <podcast:value> lightning-address payment info.
  • Go live — stream from OBS (RTMP) or straight from the browser (WebRTC/WHIP) through MediaMTX; viewers watch via HLS and the stream is announced on nostr as a NIP-53 (kind 30311) live event.
  • Publish recordings — live streams are recorded; one click remuxes and publishes a recording as a podcast episode.

Quick start

cp .env.example .env   # edit PUBLIC_HOST if not localhost
docker compose up --build -d

Then open http://localhost:8095, log in with a NIP-07 extension, and follow the wizard.

Services / ports

Service Host port Purpose
podpuddle 8095 Web UI + API + RSS feeds
MediaMTX 1935 RTMP ingest (OBS)
MediaMTX 8889 (+8189/udp) WebRTC/WHIP ingest (browser)
MediaMTX 8890 HLS playback
blossom-server 8098 Media blob storage (sha256-addressed)

Streaming with OBS

Create a stream in the UI; it gives you:

  • Server: rtmp://<host>:1935/live
  • Stream key: <streamId>?key=<secret>

The HLS playback URL (http://<host>:8890/live/<streamId>/index.m3u8) is public and never contains the secret.

Development

docker compose up mediamtx blossom -d   # backends
cd server   && npm install && npm run dev   # API on :8095
cd frontend && npm install && npm run dev   # Vite on :5173, proxies /api + /feeds

Tests: cd server && npm test.

Data

Everything lives in named docker volumes: podpuddle-data (SQLite, server nostr key, covers), mediamtx-recordings (stream recordings, 7-day retention), blossom-data (media blobs).

S
Description
No description provided
Readme
260 KiB
Languages
TypeScript 69.6%
Vue 24.8%
JavaScript 4.3%
Dockerfile 0.6%
CSS 0.6%
Other 0.1%