Convert ytdl-sub output directories into podcast RSS feeds.
Project description
sub2pod
Convert ytdl-sub output directories into
standards-compliant podcast RSS feeds. Point it at a directory full of downloaded
audio, and it writes feed.xml into each channel subdirectory — ready to serve or
submit to podcast directories.
What it does
- Reads Kodi
tvshow.nfoand per-episode.nfosidecars produced by ytdl-sub - Discovers date-prefixed audio files (
YYYY-MM-DD - <title>.<ext>) in each channel directory - Generates RSS 2.0 + iTunes namespace
feed.xmlper channel - Emits correct MIME types for
.opus,.mp3, and.m4aenclosures - Produces an
opml.xmlindex at the root level for one-click feed import - Falls back to filename parsing when
.nfosidecars are absent
What it does not do
- No download or subscription management (that's ytdl-sub's job)
- No web server — feed files are static XML; serve them however you like
- No podcast client or player
Installation
From PyPI
pip install sub2pod
From source
git clone https://codeberg.org/marvin8/sub2pod.git
cd sub2pod
uv sync
uv run sub2pod --help
Usage
sub2pod /path/to/ytdl-sub/output https://podcast.example.com
This walks the parent directory looking for subdirectories containing tvshow.nfo
and generates:
| Output | Location | Description |
|---|---|---|
feed.xml |
Each channel subdirectory | RSS 2.0 + iTunes podcast feed |
opml.xml |
Parent directory root | OPML index of all feeds |
Options
--dry-run Print paths without writing any files
--verbose Log per-episode details during generation
Example
# After ytdl-sub downloads new episodes:
sub2pod /home/NAS/ytdl-sub/mark/podcast https://podcasts.example.com
# Preview without writing:
sub2pod /home/NAS/ytdl-sub/mark/podcast https://podcasts.example.com --dry-run
# See what's being generated:
sub2pod /home/NAS/ytdl-sub/mark/podcast https://podcasts.example.com --verbose
How it works
- Channel discovery — Walks the parent directory for subdirectories containing
tvshow.nfo - Metadata parsing — Reads channel title and genre from
tvshow.nfo; reads per-episode title, description, date, runtime, and source URL from.nfosidecars - Episode discovery — Finds all date-prefixed audio files, pairs them with their
.nfosidecars, sorts newest-first - Feed generation — Builds RSS 2.0 XML with iTunes podcast namespace elements (
<itunes:image>,<itunes:duration>,<itunes:category>), writesfeed.xml - OPML index — Writes
opml.xmlat the root listing every channel feed
Input format
Each channel directory is expected to contain:
Links with Friends/
├── tvshow.nfo ← Channel metadata (title, genre)
├── poster.jpg ← Podcast artwork → <itunes:image>
├── 2026-05-19 - Episode Title.opus ← Audio file
├── 2026-05-19 - Episode Title.nfo ← Episode metadata sidecar
└── 2026-05-19 - Episode Title-thumb.jpg ← Episode thumbnail
Documentation
- ytdl-sub Integration Guide — Configuring ytdl-sub to produce sub2pod-compatible output: NFO tags, episode thumbnails, trigger strategies, and Opus MIME type guidance.
Licence
Copyright (C) 2026 Marvin8
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sub2pod-0.2.0.tar.gz.
File metadata
- Download URL: sub2pod-0.2.0.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8272f3586390917e72ac54c8dfe2438571f64cb2ba203c3b51fa44773229cc21
|
|
| MD5 |
e83b7ed670d87291b96b0e61ba9efc64
|
|
| BLAKE2b-256 |
18c5f864ceefdb11ac8a640796e16fb2418cd629ceac82be66395efc0a8028be
|
File details
Details for the file sub2pod-0.2.0-py3-none-any.whl.
File metadata
- Download URL: sub2pod-0.2.0-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b9476286d98c1b71046a8aeb06b7e4a8d4e1c69123548ad7b8f35ec9246810c
|
|
| MD5 |
cc93122f86c0ddd9ca5bacd6f23ac45f
|
|
| BLAKE2b-256 |
d83df1894b51ff5fd3e4a1bb524f735432e1bf217ad3b5e6e5232f5276f4f6c8
|