The Problem
Many podcast‑style apps cannot natively pull video‑only platforms such as YouTube or Bilibili, leaving users to manually download, convert, and manage media. Organizations that want a self‑hosted “listen‑anywhere” solution must stitch together API access, download tooling, and RSS generation themselves.
What This Does
pigeon-pod is a Spring Boot service that turns YouTube and Bilibili channels, playlists, or single videos into authenticated RSS feeds that any podcast client can consume.
The core server lives in backend/src/main/java/top/asimov/pigeon/. The entry point is App.java, which boots the Spring context and wires configuration classes such as AppBaseUrlResolver.java, AuthProperties.java, and S3ClientConfig.java. Media handling is encapsulated in helper classes (YoutubeHelper.java, BilibiliApiClient.java, DownloadHandler.java) and a set of scheduled jobs (ChannelSyncer.java, DownloadScheduler.java) that keep feeds fresh and trigger yt‑dlp downloads. Controllers under backend/src/main/java/top/asimov/pigeon/controller/ expose REST endpoints for account management, feed CRUD, RSS generation, and public episode sharing. The RSS route (RssController.java) returns a signed feed URL that podcast apps can subscribe to without exposing raw credentials.
How To Use It
Setup
The project is built with Maven and distributed as a Docker image. The simplest path is the Docker‑Compose snippet shown in the README:
docker-compose.yml (example) version: '3.9' services: pigeon-pod: image: ghcr.io/aizhimou/pigeon-pod:latest restart: unless-stopped containername: pigeon-pod ports: '8834:8080' environment: SPRINGDATASOURCEURL=jdbc:sqlite:/data/pigeon-pod.db PIGEONAUTHENABLED=true # set false only behind a trusted proxy volumes: data:/data volumes: data:
If you prefer to build locally:
Build the Docker image
docker build -t pigeon-pod:dev . Or run the Spring app directly cd backend mvn clean package -DskipTests # produces target/pigeon-pod.jar java -jar target/pigeon-pod.jar
Configuration
SPRINGDATASOURCEURL points to a SQLite file (default path /data/pigeon-pod.db). PIGEONAUTHENABLED toggles the built‑in login system. API keys are read from Spring properties files or environment variables referenced in YoutubeApiKeyHolder.java and BilibiliResolverHelper.java. Proxy settings are supplied via ProxyRuntimeConfigApplier.java and can be toggled with PIGEONPROXYTYPE (not documented in the repo, but the code reads ProxyType enum).
Running it
The service starts on port 8080 (mapped to 8834 in the compose file). Open http://localhost:8834 to reach the UI. API calls are defined under /api/ as per the Controller classes; for example, adding a YouTube channel uses POST /api/channel handled by ChannelService.java.
Real‑World Use
A small media‑curation team can deploy pigeon-pod behind an existing reverse proxy (e.g., Nginx). They store a shared YouTube API key in the host environment, enable PIGEONAUTH_ENABLED=false, and let their users add channels via the web UI. Each channel automatically generates an RSS URL like https://pigeon.example.com/rss/abcd1234, which employees add to their preferred podcast app. The built‑in download scheduler ensures new videos are fetched nightly, and the failed‑download notifier emails the ops team when quota limits are approached (YoutubeQuotaService.java).
Code Health & Issues
Low – Maven dependencies lack a lockfile – backend/pom.xml specifies versions but no dependencyManagement lock; reproducibility depends on Maven Central availability. Medium – Sparse test coverage – Only 3 test files are present for a codebase of ~160 Java classes; many service and controller paths are untested. Low – Secrets handling – API keys are expected via environment variables, but the repo contains no .gitignore entry for a local application.yml; developers could accidentally commit credentials. Low – CI only builds Docker image – .github/workflows/build-and-publish.yml builds and pushes the image but does not run unit tests, missing an early quality gate. Low – Documentation fragmented – README provides a Docker‑Compose example but lacks a quick‑start for local Maven execution or a list of required environment variables beyond the two shown. Low – License present – LICENSE file is included, satisfying legal compliance.
Overall, the project follows standard Spring conventions, uses clear package separation, and the Dockerfile (Dockerfile) correctly copies the built JAR. No obvious security‑critical code patterns (e.g., raw SQL) were found.
The Bottom Line
pigeon-pod delivers a functional, self‑hosted bridge between YouTube/Bilibili and podcast clients with a clean Spring architecture and ready‑made Docker deployment. It is suitable for teams that can tolerate limited automated testing and are comfortable managing their own API keys and proxy configuration. For production use, augment the CI pipeline with unit/integration tests and consider pinning Maven dependencies to improve build reproducibility.