Skip to content

l5yth/podserv-b

Repository files navigation

podserv-b

Rust Codecov GitHub Release Crates.io AUR Nix Flake Gentoo Top Language License: Apache-2.0

a minimalist podcast server (type b) for serving media files on the web.

screenshot of the first version

scans a provided directory of mp3 files, reads their id3 tags, and serves a minimalist-themed single-page web page with an embedded audio player, album art, and download links. supports flat and nested media directories.

Demo: archiv.funkfabrik-b.de

installation

cargo install podserv-b

for linux packages see archlinux/PKGBUILD or gentoo/podserv-b-9999.ebuild

to deploy as a systemd service (packages handle the user/dir automatically):

# if installed via a linux package:
cp /etc/podserv-b.toml.example /etc/podserv-b.toml

# if installed via cargo install, create /etc/podserv-b.toml manually —
# all fields are optional, see the configuration section below for the schema.

systemctl enable --now podserv-b

usage

podserv-b binds to 127.0.0.1:8447 and serves mp3 files in ./media by default

podserv-b v0.1.2
a minimalist podcast server (type b) for serving media files on the web
apache v2 (c) 2026 l5yth

Command-line arguments

Usage: podserv-b [OPTIONS]

Options:
  -c, --config <CONFIG>    Path to the TOML configuration file [default: /etc/podserv-b.toml]
  -m, --media <MEDIA>      Directory containing MP3 files to serve [default: media]
  -b, --bind <BIND>        Address to bind the HTTP server to [default: 127.0.0.1:8447]
      --file-to-meta       Parse a date from the episode filename and use it as the publication date
      --listens <LISTENS>  Path to the JSON file used to persist listen counts [default: /var/lib/podserv-b/listens.json]
  -h, --help               Print help
  -V, --version            Print version

configuration

the config file is a TOML file read at startup. pass its path with -c / --config (or the CONFIG env var). the default path is /etc/podserv-b.toml.

title       = "My Podserv B"
description = "Station for Podcast Lovers, Listeners, and Dogs"
website     = "https://example-b.com"

# RSS feed fields
base_url    = "https://pods.example-b.com"  # absolute URL prefix for enclosure links
author      = "Jane Smith"                  # <itunes:author> / <managingEditor>
language    = "en"                          # BCP 47 language tag
explicit    = false                         # <itunes:explicit>

all fields are optional; defaults are used when the file is absent.

endpoints

route description
GET / episode browser (HTML)
GET /rss RSS 2.0 + iTunes podcast feed (XML)
GET /media/<file> audio file with range-request support
GET /art/<file> embedded cover art
GET /listens JSON object mapping each episode path to its listen count

listen counting

initial play requests (no Range header, or Range: bytes=0-…) are counted per episode. counts are persisted to a JSON file on every update so they survive restarts. the default path is /var/lib/podserv-b/listens.json (created automatically by the systemd unit via StateDirectory=podserv-b). override with --listens <path> or the LISTENS_FILE env var.

filename dates (--file-to-meta)

pass --file-to-meta (or set FILE_TO_META=1) to parse a date from each episode's filename and use it as the RSS <pubDate>. supported patterns: YYYY-MM-DD, YYYY_MM_DD, YYYYMMDD. falls back to the file modification time when no valid date is found.

About

a minimalist podcast server (type b) for serving media files on the web

Topics

Resources

License

Stars

Watchers

Forks

Contributors