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

Metadata

Release files for mediathekwatch 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mediathekwatch 0.1.1
File Size Uploaded
mediathekwatch-0.1.1.tar.gz 76.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mediathekwatch 0.1.1
File Interpreter ABI Platform
mediathekwatch-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 100.4 kB

Release files / mediathekwatch-0.1.1.tar.gz

Download URL mediathekwatch-0.1.1.tar.gz
Size 76.0 kB
Tags Source
SHA-256 checksum
How to use checksums
a367d51968daeb9bdc1ee3ca230cfdbd1d5a4874e6153d7c8d502aab74257435
BLAKE2b-256 checksum
How to use checksums
c78e651522810bda74cd39be878dc104167b190331d012c0a5ed607d7fe15c25
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release files / mediathekwatch-0.1.1-py3-none-any.whl

Download URL mediathekwatch-0.1.1-py3-none-any.whl
Size 24.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e50074e2852c115ec6fad30379754a7cdb75c6924575014230285327c600d418
BLAKE2b-256 checksum
How to use checksums
cbf2589a25d695de965c412dc16d95d02e1deccdf8e36a1aee2b3186748423a2
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page