Turn a YouTube channel into a podcast RSS feed with downloadable audio files.
- Fetches the latest videos from a YouTube channel (skips Shorts)
- Downloads each video's audio as an
.m4afile intomedia/ - Generates an RSS 2.0 feed (
feed.xml) with<enclosure>elements pointing to the local audio files - Can run locally or via GitHub Actions (scheduled daily) and deploy to GitHub Pages
This is the easiest way: fork the repo, configure it, and GitHub will regenerate and host your feed daily.
Fork this repo on GitHub.
Edit config.yml in your fork and add your YouTube channels:
feeds:
- name: my-podcast
channel_url: https://www.youtube.com/@YourChannelFollow the yt-dlp guide on exporting YouTube cookies to get a cookies.txt file.
You have two options:
Option A — GitHub secret (safer, recommended):
- Open your fork's Settings → Secrets and variables → Actions
- Create a new repository secret named
YT_COOKIES - Paste the entire contents of your
cookies.txtfile as the value
Option B — Commit cookies.txt (simpler, private forks only):
- Copy the exported
cookies.txtinto the repo root - It's already in
.gitignore— uncomment or remove it from.gitignoreif you want it committed
- Go to your fork's Settings → Pages
- Under Source, select GitHub Actions
- The feed will be available at
https://<your-username>.github.io/yt-pod-rss/feed.xml
- The workflow runs automatically every day at 06:00 UTC
- You can also trigger it manually: Actions → Generate RSS Feed → Run workflow
- After the first run, add the RSS feed URL to your podcast app
# Install dependencies
pip install -r requirements.txt
# Install Deno (required by yt-dlp for JS challenge solving)
curl -fsSL https://deno.land/install.sh | sh
export PATH="$HOME/.deno/bin:$PATH"
# Generate the feed (uses channel_url from config.yml)
python generate_feed.py
# Or specify a URL directly
python generate_feed.py "https://www.youtube.com/@channel/videos"
# Test mode (uses sample data, no network calls)
python generate_feed.py --test
# Custom number of videos
python generate_feed.py -n 10If you get bot-blocked, place a cookies.txt file in the repo root or set the YT_COOKIES environment variable.
# Build the image
docker build -t yt-pod-rss .
# Run with config.yml defaults (mount media/ and cookies.txt for persistence)
docker run -v "$PWD/media:/app/media" -v "$PWD/cookies.txt:/app/cookies.txt" yt-pod-rss
# Pass arguments directly to generate_feed.py
docker run -v "$PWD/media:/app/media" yt-pod-rss --test
# Single URL mode (override config)
docker run -v "$PWD/media:/app/media" yt-pod-rss "https://www.youtube.com/@channel" -n 5
# Use YT_COOKIES env var instead of a file
docker run -e YT_COOKIES="$(cat cookies.txt)" -v "$PWD/media:/app/media" yt-pod-rssyt-pod-rss/
├── config.yml # Feed list (name + channel_url per feed)
├── generate_feed.py # Main script
├── requirements.txt # Python dependencies
├── test_data.json # Sample data for --test mode
├── cookies.txt # YouTube cookies (optional, not committed)
├── Dockerfile # Docker image definition
├── media/ # Downloaded audio files (not committed)
├── *.xml # Generated RSS feeds (not committed)
└── .github/workflows/
└── generate.yml # GitHub Actions workflow (daily schedule)
Built by @andreparames with OpenCode