Skip to main content

Archive all episodes from your favorite podcasts

Project description

Podcast Archiver

Podcast Archiver Logo

version python downloads

Docker Build Tests

ruff poetry pre-commit

A fast and simple command line client to archive all episodes from your favorite podcasts.

Podcast Archiver takes the feed URLs of your favorite podcasts and downloads all available episodes for you—even those "hidden" in paged feeds. You'll end up with a complete archive of your shows. The archiver also supports updating an existing archive, so that it lends itself to be set up as a cronjob.

Demo of podcast-archiver

Setup

Install via pipx:

pipx install podcast-archiver

Install via brew:

brew install podcast-archiver

Or use it via Docker:

docker run --tty --rm codeberg.org/janw/podcast-archiver --help

By default, the docker image downloads episodes to a volume mounted at /archive.

Usage

Podcast Archiver supports command line arguments, environment variables, and a config file to set it up. The most simple invocation, passing feeds as command line arguments, would like like this:

podcast-archiver --dir ~/Podcasts --feed https://feeds.feedburner.com/TheAnthropoceneReviewed

What constitutes a "feed"

Podcast Archiver expects values to its --feed/-f argument to be URLs pointing to an RSS feed of a podcast.

If you are not certain if the link you have for a show that you like, you can try and pass it to Podcast Archiver directly. The archiver supports a variety of links from popular podcast players and platforms, including Apple Podcasts, Overcast.fm, Castro, and Pocket Casts:

# Archive from Apple Podcasts URL
podcast-archiver -f https://podcasts.apple.com/us/podcast/black-girl-gone-a-true-crime-podcast/id1556267741
# ... or just the ID
podcast-archiver -f 1556267741

# From Overcast podcast URL
podcast-archiver -f https://overcast.fm/itunes394775318/99-invisible
# ... or episode sharing links (will resolve to all episodes)
podcast-archiver -f https://overcast.fm/+AAyIOzrEy1g

Supported services

The table below lists most of the supported services and URLs. If you think that some service you like is missing here, please let me know!

Service Example URL
Apple Podcasts https://podcasts.apple.com/us/podcast/the-anthropocene-reviewed/id1342003491
Overcast https://overcast.fm/itunes394775318/99-invisible, https://overcast.fm/+AAyIOzrEy1g
Castro https://castro.fm/podcast/f996ae94-70a2-4d9c-afbc-c70b5bacd120
SoundCloud https://soundcloud.com/chapo-trap-house

Local files

Feeds can also be "fetched" from a local file:

podcast-archiver -f file:/Users/janw/downloaded_feed.xml

Testing without downloading

To find out if you have to the right feed, you may want to use the --dry-run option to output the discovered feed information and found episodes. It will prevent all downloads.

podcast-archiver -f https://feeds.feedburner.com/TheAnthropoceneReviewed --dry-run

Using a config file

Podcast Archiver can be configured using a YAML config file as well. This way you can easily add and remove feeds to the list and let the archiver fetch the newest episodes, for example using a daily cronjob.

A simple config file can look like this:

archive_directory: ~/Podcasts
filename_template: '{show.title}/{episode.published_time:%Y-%m-%d} - {episode.title}.{ext}'
write_info_json: true
feeds:
  - https://feeds.feedburner.com/TheAnthropoceneReviewed  # The Anthropocene Reviewed
  - https://feeds.megaphone.fm/heavyweight-spot  # Heavyweight

To create a config file, you may use podcast-archiver --config-generate to emit an example configuration locally. You can also find a pre-populated config file here. The example config contains descriptions and default values for all available parameters. After modifying it to your liking, you can invoke the archiver by bassing the config file as a command line argument:

podcast-archiver --config config.yaml

Alternatively (for example, if you're running podcast-archiver in Docker), you may point it to the config file using the PODCAST_ARCHIVER_CONFIG=path/to/config.yaml environment variable.

If the --config parameter is omitted, the archiver will look for a config file in its app config directory. The location of this directory is OS-specific; it is printed with the podcast-archiver --help output (next to the --config option help text).

Using environment variables

Most settings of Podcast Archiver are available as environment variables, too. Check podcast-archiver --help for options with env var: … next to them.

export PODCAST_ARCHIVER_FEEDS='https://feeds.feedburner.com/TheAnthropoceneReviewed'  # multiple must be space-separated
export PODCAST_ARCHIVER_ARCHIVE_DIRECTORY="$HOME/Podcasts"

podcast-archiver

Advanced use

Continuous mode

When the --sleep-seconds option is set to a non-zero value, Podcast Archiver operates in continuous mode. After successfully populating the archive, it will not terminate but rather sleep for the given number of seconds until it refreshes the feeds again and downloads episodes that have been published in the meantime.

If no new episodes have been published, no download attempts will be made, and the archiver will go to sleep again. This mode of operation is ideal to be run in a containerized setup, for example using docker compose:

services:
  podcast-archiver:
    restart: always
    image: codeberg.org/janw/podcast-archiver
    volumes:
      - ./archive:/archive
    command:
      - --sleep-seconds=3600  # sleep for 1 hour between updates
      - --feed=https://feeds.feedburner.com/TheAnthropoceneReviewed
      - --feed=https://feeds.megaphone.fm/heavyweight-spot

Changing the filename format

Podcast Archiver has a --filename-template option that allows you to change the particular naming scheme of the archive. The default value for --filename-template. is shown in podcast-archiver --help, as well as all the available variables. The basic ones are:

  • Episode: episode.title, episode.subtitle, episode.author, episode.published_time, episode.original_filename
  • Podcast: show.title, show.subtitle, show.author, show.language

Note here that episode.published_time is a Python-native datetime, so its exact format can be adjusted further a la {episode.published_time:%Y-%m-%d %H%M%S} using strftime-placeholders. By default it uses %Y-%m-%d (e.g. 2024-12-31).

Examples

  • More precise published time

    {show.title}/{episode.published_time:%Y-%m-%d %H%M%S %Z} - {episode.title}.{ext}
    

    Results in …/That Show/2023-03-12 123456 UTC - Some Episode.mp3

  • Using the original filename (roughly equivalent to pre-1.0 --subdirs)

    {show.title}/{episode.original_filename}
    

    Results in …/That Show/ts001-episodefilename.mp3

  • Using the original filename (roughly equivalent to pre-1.0 --subdirs + --date-prefix)

    {show.title}/{episode.published_time} {episode.original_filename}
    

    Results in …/That Show/2023-03-12 ts001-episodefilename.mp3

All available options

Run podcast-archiver --help to see all available parameters and the corresponding environment variables.

podcast-archiver --help

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

podcast_archiver-2.3.5.tar.gz (29.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

podcast_archiver-2.3.5-py3-none-any.whl (37.9 kB view details)

Uploaded Python 3

File details

Details for the file podcast_archiver-2.3.5.tar.gz.

File metadata

  • Download URL: podcast_archiver-2.3.5.tar.gz
  • Upload date:
  • Size: 29.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.10.12 Linux/6.8.0-64-generic

File hashes

Hashes for podcast_archiver-2.3.5.tar.gz
Algorithm Hash digest
SHA256 1c157df1202d1ce05e2303d7d729e4e1e87ba202cba6f51c6024b38a2236b937
MD5 e85dc3e5c5f0f07e56885681e399f506
BLAKE2b-256 96058f08025cbfb32ad8a0589d90e69c9da04d4ecf201b48815569a114ffed2e

See more details on using hashes here.

File details

Details for the file podcast_archiver-2.3.5-py3-none-any.whl.

File metadata

  • Download URL: podcast_archiver-2.3.5-py3-none-any.whl
  • Upload date:
  • Size: 37.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.10.12 Linux/6.8.0-64-generic

File hashes

Hashes for podcast_archiver-2.3.5-py3-none-any.whl
Algorithm Hash digest
SHA256 241ce28febca85ebcc74d842e8f3befb786f1dbf763322bff3c61b0378051a74
MD5 24d3a772c5e18db2a6f04f1b4f1578e7
BLAKE2b-256 9c345544b529cc7c96bd813af93e589456d7c0130c9795b678d573503b787827

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page