Skip to main content

Automate downloading and metadata generation with YoutubeDL

Project description

ytdl-sub

Automate downloading and metadata generation with YoutubeDL.

codecov Code Qaulity Checks License

ytdl-sub is a command-line tool that downloads media via yt-dlp and prepares it for your favorite media player, including Kodi, Jellyfin, Plex, Emby, and modern music players. No additional plugins or external scrapers are needed.

We recognize that everyone stores their media differently. Our approach for file and metadata formatting is to provide maximum flexibility while maintaining simplicity.

YouTube Channels as TV Shows

Plex

unknown

Jellyfin

jellyfin

Music Videos and Concerts

Kodi

kodi

Jellyfin

jelly_mv

SoundCloud Albums and Singles

MusicBee (any file or tag-based music player)

sc_mb

Bandcamp Discography

Navidrome (any file or tag-based music server)

bc_nav

How it Works

ytdl-sub uses YAML configs to define a layout for how you want media to look after it is downloaded. See our walk-through guide on how to get started. Ready-to-use example configurations can be found here alongside our readthedocs for detailed information on config fields.

Config

The config.yaml defines how our downloads will look. For this example, let us download YouTube channels and generate metadata to look like TV shows using ytdl-sub's prebuilt presets. No additional plugins or programs are needed for Kodi, Jellyfin, Plex, or Emby to recognize your downloads. This can also be used to download any yt-dlp supported URL, including YouTube playlists, Bitchute channels, etc.

# Set the working directory which will be used to stage downloads
# before placing them in your desired output directory.
configuration:
  working_directory: '.ytdl-sub-downloads'

# Presets are where you create 'sub-configs' that can can be
# merged together to dictate what is downloaded, how to format it,
# and what metadata to generate.
presets:

  # Let us create a preset called `only_recent_videos` that will
  # only download recent videos in the last 2 months.
  only_recent_videos:

    # Use the `date_range` plugin to specify ytdl-sub to only
    # download videos after today MINUS {download_range}, which
    # is an override variable that we can alter per channel.
    date_range:
      after: "today-{download_range}"

    # Any yt-dlp argument can be passed via ytdl-sub. Let us set
    # yt-dlp's `break_on_reject` to True to stop downloading after
    # any video is rejected. Videos will be rejected if they are
    # uploaded after our {download_range}.
    ytdl_options:
      break_on_reject: True

    # Deletes any videos uploaded after {download_range}.
    output_options:
      keep_files_after: "today-{download_range}"

    # Set the override variable {download_range} to 2months.
    # This will serve as our default value. We can override
    # this per channel or in a child preset.
    overrides:
      download_range: "2months"

  ####################################################################

  # Now let us create a preset that downloads videos and formats
  # as TV shows.
  tv_show:

    # Presets can inherit all attributes from other presets. Our
    # `tv_show` preset will inherit these presets built into ytdl-sub.
    preset:
      # Let us specify all the TV show by date presets to support all
      # players. You only need to specify one, but this ensures
      # compatibility with all players.
      - "kodi_tv_show_by_date"
      - "jellyfin_tv_show_by_date"
      - "plex_tv_show_by_date"
      # Now we choose a preset that defines how our seasons and
      # episode numbers look.
      - "season_by_year__episode_by_month_day"

    # Set override variables that will be applicable to all downloads
    # in main presets.
    overrides:
      tv_show_directory: "/tv_shows"  # Replace with desired directory

Subscriptions

The subscriptions.yaml file is where we define content to download using presets in the config.yaml. Each subscription can overwrite any field used in a preset.

# The name of our subscription. Let us create one to download
# ALL of Rick A's videos
rick_a:
  # Inherit our `tv_show` preset we made above
  preset:
    - "tv_show"
  
  # Set override variables to set the channel URL and the
  # name we want to give the TV show.
  overrides:
    tv_show_name: "Rick A"
    url: "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw"

# Let us make another subscription that will only download Rick A's
# video's in the last 2 weeks.
rick_a_recent:
  # Inherit our `tv_show` AND `only_recent_videos` preset
  # Bottom-most presets take precedence.
  preset:
    - "tv_show"
    - "only_recent_videos"
  
  # Set override variables for this subscription. Modify the
  # `download_range` to only download and keep 2 weeks' worth
  # of videos.
  overrides:
    tv_show_name: "Rick A"
    url: "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw"
    download_range: "2weeks"

The download can now be performed using:

ytdl-sub sub subscriptions.yaml

To preview what your output files before doing any downloads, you can dry run using:

ytdl-sub --dry-run sub subscriptions.yaml

One-time Download

There are things we will only want to download once and never again. Anything you can define in a subscription can be defined using CLI arguments. This example is equivalent to the subscription example above:

ytdl-sub dl \
    --preset "tv_show" \
    --overrides.tv_show_name "Rick A" \
    --overrides.url: "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw"

Download Aliases

In the config.yaml, we can define aliases to make dl commands shorter.

configuration:
  dl_aliases:
    tv: "--preset tv_show"
    name: "--overrides.tv_show_name"
    url: "--overrides.url"

The above command can now be shortened to

ytdl-sub dl \
    --tv \
    --name "Rick A" \
    --url "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw"

Output

After ytdl-sub runs, the end result will download and format the channel files into something ready to be consumed by your favorite media player or server.

/path/to/tv_shows/Rick Aß
  /Season 2021
    s2021.e0317 - Pattys Day Video-thumb.jpg
    s2021.e0317 - Pattys Day Video.mp4
    s2021.e0317 - Pattys Day Video.nfo
  /Season 2022
    s2022.e1225 - Merry Christmas-thumb.jpg
    s2022.e1225 - Merry Christmas.mp4
    s2022.e1225 - Merry Christmas.nfo
  poster.jpg
  fanart.jpg
  tvshow.nfo

Beyond TV Shows

The above example made heavy-use of ytdl-sub prebuilt presets and hides many features that are offered. ytdl-sub strives to support any use case that first requires a download via yt-dlp. Use ytdl-sub to download, format, and convert media for your media player to recognize downloads as:

  • Movies
  • TV shows
    • From a single channel or playlist
    • From multiple channels or playlists
    • From individual videos
  • Extracted audio as podcasts
  • Music videos
  • Music, including:
    • Individual songs
    • Albums
    • Discographies

Installation

The ytdl-sub docker image uses LinuxServer's base alpine image. It looks, feels, and operates like other LinuxServer images. This is the recommended way to use ytdl-sub.

The docker image is intended to be used as a console. For automating subscriptions.yaml downloads to pull new media, see this guide on how set up a cron job in the docker container.

Docker Compose

services:
  ytdl-sub:
    image: ghcr.io/jmbannon/ytdl-sub:latest
    container_name: ytdl-sub
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Los_Angeles
    volumes:
      - <path/to/ytdl-sub/config>:/config
      - <path/to/tv_shows>:/tv_shows # optional
      - <path/to/movies>:/movies # optional
      - <path/to/music_videos>:/music_videos # optional
      - <path/to/music>:/music # optional
    restart: unless-stopped

Docker CLI

docker run -d \
    --name=ytdl-sub \
    -e PUID=1000 \
    -e PGID=1000 \
    -e TZ=America/Los_Angeles \
    -v <path/to/ytdl-sub/config>:/config \
    -v <OPTIONAL/path/to/tv_shows>:/tv_shows \
    -v <OPTIONAL/path/to/movies>:/movies \
    -v <OPTIONAL/path/to/music_videos>:/music_videos \
    -v <OPTIONAL/path/to/music>:/music \
    --restart unless-stopped \
    ghcr.io/jmbannon/ytdl-sub:latest

PIP

You can install our PyPI package with:

python3 -m pip install -U yt-dlp

Building Docker Image Locally

Run make docker in the root directory of this repo to build the image. This will build the python wheel and install it in the Dockerfile.

Virtualenv

With a Python 3.10 virtual environment, you can clone and install the repo using

git clone https://github.com/jmbannon/ytdl-sub.git
cd ytdl-sub

pip install -e .

Contributing

There are many ways to contribute, even without coding. Please take a look in our GitHub Issues to ask questions, submit a feature request, or pick up a bug.

Support

We are pretty active in our Discord channel if you have any questions. Also see our FAQ for commonly asked questions.

Project details


Release history Release notifications | RSS feed

Download files

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

Source Distribution

ytdl-sub-2023.2.24.tar.gz (102.2 kB view details)

Uploaded Source

Built Distribution

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

ytdl_sub-2023.2.24-py3-none-any.whl (128.9 kB view details)

Uploaded Python 3

File details

Details for the file ytdl-sub-2023.2.24.tar.gz.

File metadata

  • Download URL: ytdl-sub-2023.2.24.tar.gz
  • Upload date:
  • Size: 102.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.2

File hashes

Hashes for ytdl-sub-2023.2.24.tar.gz
Algorithm Hash digest
SHA256 e0e5d39a14a3ccd7ab4c7155bda07f67a4131d8732faca78f52f3dd9a998a002
MD5 d3065f583b004b25b37cf475e257555c
BLAKE2b-256 ed2d6fad8c71af5afbfb734d780434f37b0e0483a7e15b1aaa00e25ca6f54666

See more details on using hashes here.

File details

Details for the file ytdl_sub-2023.2.24-py3-none-any.whl.

File metadata

  • Download URL: ytdl_sub-2023.2.24-py3-none-any.whl
  • Upload date:
  • Size: 128.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.2

File hashes

Hashes for ytdl_sub-2023.2.24-py3-none-any.whl
Algorithm Hash digest
SHA256 8a67c5f5831e9632c97e439d676750560f3af129a6402292f5084747062ab42c
MD5 c6b5e4cbdf31c494a191fdb64f9fc3fe
BLAKE2b-256 40a5075f0027c4e2f8839d529e23cf6d55d10591de9415bf1b9b8024679219a9

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