Skip to content

divaprabhu/Podcast-AI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Podcast-AI

πŸŽ™οΈ Podcast-AI

Automated arXiv research paper β†’ conversational podcast pipeline

Python 3.13+ MIT License Status: Active


πŸ“– Overview

Podcast-AI is a lightweight automated pipeline that transforms a selected arXiv research paper into a short conversational podcast episode. From paper discovery through RSS distribution (and optionally YouTube upload), every step is driven by a single command or run incrementally step by step.

Fetch β†’ Select β†’ PDF β†’ Chunk Summary β†’ Final Summary β†’ Script β†’ Audio β†’ Video β†’ Release β†’ RSS β†’ Upload


✨ Features

  • πŸ“„ Paper Discovery – Fetches latest papers from arXiv by category
  • πŸ€– Multi-Provider LLM – Supports OpenRouter, Ollama, GitHub, LM Studio, and Ollama Cloud
  • πŸ“ Smart Summarization – Chunked PDF summarization + final synthesis
  • 🎀 Natural TTS – Conversational script generation with edge-tts
  • 🎬 Video Assembly – Combines album art + audio into a shareable video
  • πŸ“‘ RSS & Releases – Generates a podcast RSS feed and GitHub Releases
  • ☁️ YouTube Upload – Optional automated upload to YouTube
  • πŸ” CI/CD Ready – Ships with a GitHub Actions workflow for fully automated runs

🧱 Pipeline Architecture

Step Description
fetch Pull recent papers from arXiv based on configured category
select Choose the best paper via LLM scoring
pdf Download and extract text from the paper PDF
chunk_summary Summarise each chunk of the PDF independently
final_summary Synthesise chunk summaries into a coherent overview
script Generate a conversational podcast script from the summary
audio Produce TTS audio (MP3) for each host using edge-tts
video Assemble video from album art + generated audio
release Prepare release artifacts and update episode history
rss Generate an RSS feed (feed.xml)
upload Upload episode to YouTube (requires credentials)
clear Remove all cached data

Run the full pipeline with a single command, or execute any step in isolation via --step.


πŸ“‹ Prerequisites

  • Python β‰₯ 3.13
  • FFmpeg – required for the video step (install guide)
  • API credentials – for LLM providers and/or YouTube (optional depending on your chosen features)

πŸš€ Installation

Option 1 β€” pip (classic)

git clone https://github.com/your-username/Podcast-AI.git
cd Podcast-AI
python -m venv .venv
source .venv/bin/activate   # On Windows: .venv\Scripts\activate
pip install -r requirements.txt

Option 2 β€” uv (fast)

git clone https://github.com/your-username/Podcast-AI.git
cd Podcast-AI
uv venv
source .venv/bin/activate
uv sync

A uv.lock is included β€” uv sync restores the exact dependency tree.


βš™οΈ Configuration

config.json (required)

All runtime settings live in config.json at the repository root. Key sections:

Section Purpose
paper arXiv category, fetch count, chunk sizes
llm Default provider, per-provider base URLs & timeouts, step-specific overrides
script Target word count for the generated script
podcast Show name, description, host names
voice TTS voice names, speaking rate, pitch, timeouts
output Paths and base URLs for releases and RSS
cache Cache directory and filenames
logging Log level (DEBUG, INFO, etc.)
prompts Prompt templates used during selection, summarisation, and script generation

Environment variables / .env

Create a .env file (or export variables) for any API keys your providers require:

Variable Required for
OPENROUTER_API_KEY OpenRouter provider
GH_API_KEY GitHub-hosted models
OLLAMA_API_KEY Ollama Cloud provider
YOUTUBE_CLIENT_ID YouTube upload
YOUTUBE_CLIENT_SECRET YouTube upload
YOUTUBE_REFRESH_TOKEN YouTube upload

🎯 Usage

Full pipeline

python main.py

This runs every step in order: fetch β†’ select β†’ pdf β†’ chunk_summary β†’ final_summary β†’ script β†’ audio β†’ video β†’ release β†’ rss β†’ upload.

Single step

Run any step in isolation:

python main.py --step fetch
python main.py --step select
python main.py --step script
python main.py --step clear

Available steps: fetch, select, pdf, chunk_summary, final_summary, script, audio, video, release, rss, upload, clear.

Cache management

Cache files are stored under the directory configured in cache.directory (default: .podcast_cache). To wipe all cached data:

python main.py --step clear

🧩 LLM Providers

The project includes a modular LLM layer under podcast/llm/. Each provider module implements a common interface:

Provider Module Description
OpenRouter openrouter.py Routes queries through OpenRouter's multi-model API
Ollama ollama.py Local LLM inference via Ollama
Ollama Cloud ollama_cloud.py Managed Ollama endpoint
GitHub github.py GitHub-hosted models (requires GH_API_KEY)
LM Studio lm_studio.py Local LM Studio server

Select and configure your active provider in config.json under the llm section.


πŸ€– CI/CD

The repository includes a GitHub Actions workflow (.github/workflows/podcast.yml) that fully automates the pipeline:

  1. Installs system dependencies (FFmpeg) and Python
  2. Installs Python requirements
  3. Runs the full pipeline
  4. Commits updated episodes.json (if any changes)
  5. Creates a GitHub Release containing the generated MP3 and paper JSON
  6. Deploys feed.xml and assets to GitHub Pages

The release step detects CI mode via the GITHUB_ACTIONS=true environment variable (set automatically by GitHub Actions). The release tag is derived from the current UTC date in YYYYMMDD format (e.g. podcast-20250115).


πŸ“ Project Structure

Podcast-AI/
β”œβ”€β”€ main.py                 # CLI entry point and pipeline orchestration
β”œβ”€β”€ config.json             # All runtime configuration
β”œβ”€β”€ episodes.json           # Episode history (used by RSS generation)
β”œβ”€β”€ requirements.txt        # pip dependencies
β”œβ”€β”€ pyproject.toml          # Project metadata & uv/pip build config
β”œβ”€β”€ uv.lock                 # Locked dependency tree (uv)
β”œβ”€β”€ assets/
β”‚   └── album_art.png       # Podcast cover art
β”œβ”€β”€ podcast/
β”‚   β”œβ”€β”€ arxiv.py            # arXiv paper fetching
β”‚   β”œβ”€β”€ audio.py            # TTS audio generation
β”‚   β”œβ”€β”€ cache.py            # Atomic cache read/write helpers
β”‚   β”œβ”€β”€ chunk_summary.py    # Per-chunk LLM summarisation
β”‚   β”œβ”€β”€ config.py           # config.json loading & validation
β”‚   β”œβ”€β”€ episodes.py         # episodes.json management
β”‚   β”œβ”€β”€ final_summary.py    # Final synthesis of chunk summaries
β”‚   β”œβ”€β”€ log.py              # Logging setup
β”‚   β”œβ”€β”€ pdf.py              # PDF download & text extraction
β”‚   β”œβ”€β”€ release.py          # Artifact preparation & release management
β”‚   β”œβ”€β”€ rss.py              # RSS feed generation
β”‚   β”œβ”€β”€ script.py           # Conversational script generation
β”‚   β”œβ”€β”€ selection.py        # Best-paper selection via LLM
β”‚   β”œβ”€β”€ utils.py            # Shared utilities
β”‚   β”œβ”€β”€ video.py            # Video assembly (album art + audio)
β”‚   β”œβ”€β”€ youtube.py          # YouTube upload
β”‚   └── llm/                # LLM provider modules
β”‚       β”œβ”€β”€ _format.py
β”‚       β”œβ”€β”€ openrouter.py
β”‚       β”œβ”€β”€ ollama.py
β”‚       β”œβ”€β”€ ollama_cloud.py
β”‚       β”œβ”€β”€ github.py
β”‚       └── lm_studio.py
└── .github/workflows/
    └── podcast.yml         # GitHub Actions automation

πŸ”§ Troubleshooting

  • config.json not found – Ensure config.json exists at the project root (see config.json for a template).
  • TTS / audio step fails – The audio step requires network access to the edge-tts endpoint. Check your network and the voice settings in config.json.
  • FFmpeg not found – Install FFmpeg via your package manager (sudo apt install ffmpeg, brew install ffmpeg, or download from ffmpeg.org).
  • LLM provider errors – Verify that the required environment variable (e.g. OPENROUTER_API_KEY) is set and that the provider URL is reachable.
  • YouTube upload fails – Ensure YOUTUBE_CLIENT_ID, YOUTUBE_CLIENT_SECRET, and YOUTUBE_REFRESH_TOKEN are all set correctly.

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Open an issue to discuss your feature or bugfix
  2. Fork the repository and create a branch
  3. Make your changes, adding tests where appropriate
  4. Open a pull request

πŸ“„ License

This project is licensed under the MIT License. See the LICENSE file for details.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages