Skip to main content

MediathekWatch

A Python CLI tool to monitor ARD Mediathek, ARTE.tv, and ZDF Mediathek series for new episodes and automatically download them using yt-dlp. State is tracked in a local DuckDB database.

Requirements

  • Python 3.10+
  • uv
  • yt-dlp installed and available in $PATH

Installation

# Clone or navigate to the project
cd /path/to/mediathekwatch

# Install with uv
uv sync

# Or install as editable
uv pip install -e .

Usage

The tool is installed as mediathekwatch command:

Add a series to monitor

mediathekwatch add "https://www.ardmediathek.de/serie/feuer-und-flamme/staffel-11/Y3JpZDovL3dkci5kZS9mZXVlcnVuZGZsYW1tZQ/11" --name "Feuer und Flamme"

ZDF Mediathek URLs are also supported:

mediathekwatch add "https://www.zdf.de/serien/die-anstalt" --name "Die Anstalt"

Assign to a group (see Groups):

mediathekwatch add "https://www.ardmediathek.de/serie/..." --name "My Show" --group "TVShows"

List monitored series

mediathekwatch list

Check for new episodes (intended for cron)

mediathekwatch check --target /mnt/media/TVShows

# Silent mode (suppress all output)
mediathekwatch check --target /mnt/media/TVShows --silent

When groups are configured, each group downloads to its own target folder and --target is not allowed:

mediathekwatch check --silent

Force redownload of a specific episode

# By series ID
mediathekwatch redownload 1 11 5 --target /mnt/media/TVShows

# By series name
mediathekwatch redownload "Feuer und Flamme" 11 5 --target /mnt/media/TVShows

If --target is omitted, the episode downloads to the series' group folder.

Download all episodes from a series URL

mediathekwatch download "https://www.ardmediathek.de/serie/feuer-und-flamme/staffel-11/Y3JpZDovL3dkci5kZS9mZXVlcnVuZGZsYW1tZQ/11" --target /mnt/media/TVShows

Works with ZDF Mediathek too:

mediathekwatch download "https://www.zdf.de/serien/die-anstalt" --target /mnt/media/TVShows

Remove a series

# By ID
mediathekwatch remove 1

# By name
mediathekwatch remove "Feuer und Flamme"

Groups

Groups let you organize series into separate download destinations. Each group has its own target folder. When any non-default group exists, check uses group folders instead of --target.

Create a group

mediathekwatch group create "TVShows" --target /mnt/media/TVShows

List groups

mediathekwatch group list

Update a group

mediathekwatch group update "TVShows" --name "TV Shows" --target /mnt/media/TV

Delete a group

mediathekwatch group delete "TVShows"

Move a series to a group

mediathekwatch set-group "Feuer und Flamme" "TVShows"

Global Options

  • --db PATH — Path to DuckDB database (default: ~/.config/mediathekwatch/mediathekwatch.db)
  • --target PATH — Target folder for downloads (default: current directory)

Cron Setup

Add to your crontab (e.g., every 6 hours):

0 */6 * * * /path/to/uv run mediathekwatch check --target /mnt/media/TVShows

Or if installed globally:

0 */6 * * * /home/user/.local/bin/mediathekwatch check --target /mnt/media/TVShows

Filename Format

Downloaded episodes are organized as:

<Target Folder>/<Series Name>/S<Season>/<Series> - S<season>E<episode> - <episode name>.mkv

Example:

/mnt/media/TVShows/Feuer und Flamme/S11/Feuer und Flamme - S11E05 - Der neue Fall.mkv

Database Schema

Three tables are maintained in DuckDB:

  • groups — download groups with target folders
  • monitored_series — series being tracked
  • downloaded_episodes — episodes already downloaded

Project Structure

src/mediathekwatch/
├── __init__.py    # Package init
├── main.py        # CLI entry point
├── cli.py         # Command handlers
├── models.py      # Episode/Series dataclasses
├── database.py    # DuckDB interface
├── api/           # API clients (ARD, ARTE, ZDF)
└── download.py    # yt-dlp wrapper & filename utils

Notes

  • The tool queries ARD Mediathek, ARTE.tv EMAC, and ZDF GraphQL APIs to discover episodes.
  • yt-dlp is invoked with flags for embedding thumbnails, subtitles, metadata, chapters, and info-json.
  • Episodes are skipped if they already exist in the downloaded_episodes table; use redownload to override.

Acknowledgments

  • Thanks to the MediathekView project for providing valuable insights into the structure of German public media APIs.

Development

# Run tests
uv run pytest

# Type check
uv run pyright

Download files

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

Source Distribution

mediathekwatch-0.1.1.tar.gz (76.0 kB view details)

Uploaded Source

Built Distribution

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

mediathekwatch-0.1.1-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file mediathekwatch-0.1.1.tar.gz.

File metadata

  • Download URL: mediathekwatch-0.1.1.tar.gz
  • Upload date:
  • Size: 76.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mediathekwatch-0.1.1.tar.gz
Algorithm Hash digest
SHA256 a367d51968daeb9bdc1ee3ca230cfdbd1d5a4874e6153d7c8d502aab74257435
MD5 a6731ab1254b68e9ddab343bdd901f9a
BLAKE2b-256 c78e651522810bda74cd39be878dc104167b190331d012c0a5ed607d7fe15c25

See more details on using hashes here.

File details

Details for the file mediathekwatch-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: mediathekwatch-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mediathekwatch-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e50074e2852c115ec6fad30379754a7cdb75c6924575014230285327c600d418
MD5 027d8f729f67a6abc325326b35b6effe
BLAKE2b-256 cbf2589a25d695de965c412dc16d95d02e1deccdf8e36a1aee2b3186748423a2

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

0.1.0

2 files

Supported by

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