Skip to main content

Output Templates in yt-dlp

The -o option is used to indicate a template for the output file names while -P option is used to specify the path each type of file should be saved to.

Basic Usage​

The simplest usage of -o is not to set any template arguments when downloading a single file, like in yt-dlp -o funny_video.flv "https://some/video" (hard-coding file extension like this is not recommended and could break some post-processing).

It may however also contain special sequences that will be replaced when downloading each video. The special sequences may be formatted according to Python string formatting operations, e.g. %(NAME)s or %(NAME)05d. To clarify, that is a percent symbol followed by a name in parentheses, followed by formatting operations.

Field Formatting​

The field names themselves (the part inside the parenthesis) can also have some special formatting:

  1. Object traversal: The dictionaries and lists available in metadata can be traversed by using a dot . separator; e.g. %(tags.0)s, %(subtitles.en.-1.ext)s. You can do Python slicing with colon :; E.g. %(id.3:7)s, %(id.6:2:-1)s, %(formats.:.format_id)s. Curly braces {} can be used to build dictionaries with only specific keys; e.g. %(formats.:.{format_id,height})#j. An empty field name %()s refers to the entire infodict; e.g. %(.{id,title})s. Note that all the fields that become available using this method are not listed below. Use -j to see such fields

  2. Arithmetic: Simple arithmetic can be done on numeric fields using +, - and *. E.g. %(playlist_index+10)03d, %(n_entries+1-playlist_index)d

  3. Date/time Formatting: Date/time fields can be formatted according to strftime formatting by specifying it separated from the field name using a >. E.g. %(duration>%H-%M-%S)s, %(upload_date>%Y-%m-%d)s, %(epoch-3600>%H-%M-%S)s

  4. Alternatives: Alternate fields can be specified separated with a ,. E.g. %(release_date>%Y,upload_date>%Y|Unknown)s

  5. Replacement: A replacement value can be specified using a & separator according to the str.format mini-language. If the field is not empty, this replacement value will be used instead of the actual field content. This is done after alternate fields are considered; thus the replacement is used if any of the alternative fields is not empty. E.g. %(chapters&has chapters|no chapters)s, %(title&TITLE={:>20}|NO TITLE)s

  6. Default: A literal default value can be specified for when the field is empty using a | separator. This overrides --output-na-placeholder. E.g. %(uploader|Unknown)s

  7. More Conversions: In addition to the normal format types diouxXeEfFgGcrs, yt-dlp additionally supports converting to B = Bytes, j = json (flag # for pretty-printing, + for Unicode), h = HTML escaping, l = a comma separated list (flag # for \n newline-separated), q = a string quoted for the terminal (flag # to split a list into different arguments), D = add Decimal suffixes (e.g. 10M) (flag # to use 1024 as factor), and S = Sanitize as filename (flag # for restricted)

  8. Unicode normalization: The format type U can be used for NFC Unicode normalization. The alternate form flag (#) changes the normalization to NFD and the conversion flag + can be used for NFKC/NFKD compatibility equivalence normalization. E.g. %(title)+.100U is NFKC

Syntax Summary​

To summarize, the general syntax for a field is:

%(name[.keys][addition][>strf][,alternate][&replacement][|default])[flags][width][.precision][length]type

File Type Specific Templates​

Additionally, you can set different output templates for the various metadata files separately from the general output template by specifying the type of file followed by the template separated by a colon :. The different file types supported are subtitle, thumbnail, description, annotation (deprecated), infojson, link, pl_thumbnail, pl_description, pl_infojson, chapter, pl_video. E.g. -o "%(title)s.%(ext)s" -o "thumbnail:%(title)s\%(title)s.%(ext)s" will put the thumbnails in a folder with the same name as the video. If any of the templates is empty, that type of file will not be written. E.g. --write-thumbnail -o "thumbnail:" will write thumbnails only for playlists and not for video.

Note: Due to post-processing (i.e. merging etc.), the actual output filename might differ. Use --print after_move:filepath to get the name after all post-processing is complete.

Available Fields​

The available fields are:

Basic Video Information​

  • id (string): Video identifier
  • title (string): Video title
  • fulltitle (string): Video title ignoring live timestamp and generic title
  • ext (string): Video filename extension
  • alt_title (string): A secondary title of the video
  • description (string): The description of the video
  • display_id (string): An alternative identifier for the video

Uploader Information​

  • uploader (string): Full name of the video uploader
  • uploader_id (string): Nickname or id of the video uploader
  • uploader_url (string): URL to the video uploader's profile
  • license (string): License name the video is licensed under
  • creators (list): The creators of the video
  • creator (string): The creators of the video; comma-separated

Timestamps and Dates​

  • timestamp (numeric): UNIX timestamp of the moment the video became available
  • upload_date (string): Video upload date in UTC (YYYYMMDD)
  • release_timestamp (numeric): UNIX timestamp of the moment the video was released
  • release_date (string): The date (YYYYMMDD) when the video was released in UTC
  • release_year (numeric): Year (YYYY) when the video or album was released
  • modified_timestamp (numeric): UNIX timestamp of the moment the video was last modified
  • modified_date (string): The date (YYYYMMDD) when the video was last modified in UTC

Channel Information​

  • channel (string): Full name of the channel the video is uploaded on
  • channel_id (string): Id of the channel
  • channel_url (string): URL of the channel
  • channel_follower_count (numeric): Number of followers of the channel
  • channel_is_verified (boolean): Whether the channel is verified on the platform

Video Properties​

  • location (string): Physical location where the video was filmed
  • duration (numeric): Length of the video in seconds
  • duration_string (string): Length of the video (HH:mm:ss)
  • view_count (numeric): How many users have watched the video on the platform
  • concurrent_view_count (numeric): How many users are currently watching the video on the platform
  • like_count (numeric): Number of positive ratings of the video
  • dislike_count (numeric): Number of negative ratings of the video
  • repost_count (numeric): Number of reposts of the video
  • average_rating (numeric): Average rating given by users, the scale used depends on the webpage
  • comment_count (numeric): Number of comments on the video
  • age_limit (numeric): Age restriction for the video (years)

Live Stream Status​

  • live_status (string): One of "not_live", "is_live", "is_upcoming", "was_live", "post_live"
  • is_live (boolean): Whether this video is a live stream or a fixed-length video
  • was_live (boolean): Whether this video was originally a live stream

Availability and Access​

  • playable_in_embed (string): Whether this video is allowed to play in embedded players on other sites
  • availability (string): Whether the video is "private", "premium_only", "subscriber_only", "needs_auth", "unlisted" or "public"
  • media_type (string): The type of media as classified by the site, e.g. "episode", "clip", "trailer"

URL and Time Information​

  • start_time (numeric): Time in seconds where the reproduction should start, as specified in the URL
  • end_time (numeric): Time in seconds where the reproduction should end, as specified in the URL
  • webpage_url (string): A URL to the video webpage which, if given to yt-dlp, should yield the same result again
  • webpage_url_basename (string): The basename of the webpage URL
  • webpage_url_domain (string): The domain of the webpage URL
  • original_url (string): The URL given by the user (or the same as webpage_url for playlist entries)

Extractor Information​

  • extractor (string): Name of the extractor
  • extractor_key (string): Key name of the extractor
  • epoch (numeric): Unix epoch of when the information extraction was completed

Numbering and Sequence​

  • autonumber (numeric): Number that will be increased with each download, starting at --autonumber-start, padded with leading zeros to 5 digits
  • video_autonumber (numeric): Number that will be increased with each video
  • n_entries (numeric): Total number of extracted items in the playlist

Playlist Information​

  • playlist_id (string): Identifier of the playlist that contains the video
  • playlist_title (string): Name of the playlist that contains the video
  • playlist (string): playlist_title if available or else playlist_id
  • playlist_count (numeric): Total number of items in the playlist
  • playlist_index (numeric): Index of the video in the playlist padded with leading zeros according the final index
  • playlist_autonumber (numeric): Position of the video in the playlist download queue padded with leading zeros
  • playlist_uploader (string): Full name of the playlist uploader
  • playlist_uploader_id (string): Nickname or id of the playlist uploader
  • playlist_channel (string): Display name of the channel that uploaded the playlist
  • playlist_channel_id (string): Identifier of the channel that uploaded the playlist
  • playlist_webpage_url (string): URL of the playlist webpage

Categories and Tags​

  • categories (list): List of categories the video belongs to
  • tags (list): List of tags assigned to the video
  • cast (list): List of cast members

Special Field Categories​

All the fields in Filtering Formats can also be used.

Chapter Information​

Available for the video that belongs to some logical chapter or section:

  • chapter (string): Name or title of the chapter the video belongs to
  • chapter_number (numeric): Number of the chapter the video belongs to
  • chapter_id (string): Id of the chapter the video belongs to

Episode Information​

Available for the video that is an episode of some series or program:

  • series (string): Title of the series or program the video episode belongs to
  • series_id (string): Id of the series or program the video episode belongs to
  • season (string): Title of the season the video episode belongs to
  • season_number (numeric): Number of the season the video episode belongs to
  • season_id (string): Id of the season the video episode belongs to
  • episode (string): Title of the video episode
  • episode_number (numeric): Number of the video episode within a season
  • episode_id (string): Id of the video episode

Music Album Information​

Available for the media that is a track or a part of a music album:

  • track (string): Title of the track
  • track_number (numeric): Number of the track within an album or a disc
  • track_id (string): Id of the track
  • artists (list): Artist(s) of the track
  • artist (string): Artist(s) of the track; comma-separated
  • genres (list): Genre(s) of the track
  • genre (string): Genre(s) of the track; comma-separated
  • composers (list): Composer(s) of the piece
  • composer (string): Composer(s) of the piece; comma-separated
  • album (string): Title of the album the track belongs to
  • album_type (string): Type of the album
  • album_artists (list): All artists appeared on the album
  • album_artist (string): All artists appeared on the album; comma-separated
  • disc_number (numeric): Number of the disc or other physical medium the track belongs to

Section Information​

Available only when using --download-sections and for chapter: prefix when using --split-chapters for videos with internal chapters:

  • section_title (string): Title of the chapter
  • section_number (numeric): Number of the chapter within the file
  • section_start (numeric): Start time of the chapter in seconds
  • section_end (numeric): End time of the chapter in seconds

Available only when used in --print:

  • urls (string): The URLs of all requested formats, one in each line
  • filename (string): Name of the video file
  • formats_table (table): The video format table as printed by --list-formats
  • thumbnails_table (table): The thumbnail format table as printed by --list-thumbnails
  • subtitles_table (table): The subtitle format table as printed by --list-subs
  • automatic_captions_table (table): The automatic subtitle format table as printed by --list-subs

Post-Download Fields​

Available only after the video is downloaded (post_process/after_move):

  • filepath: Actual path of downloaded video file

SponsorBlock Fields​

Available only in --sponsorblock-chapter-title:

  • start_time (numeric): Start time of the chapter in seconds
  • end_time (numeric): End time of the chapter in seconds
  • categories (list): The SponsorBlock categories the chapter belongs to
  • category (string): The smallest SponsorBlock category the chapter belongs to
  • category_names (list): Friendly names of the categories
  • name (string): Friendly name of the smallest category
  • type (string): The SponsorBlock action type of the chapter

Usage Notes​

Each aforementioned sequence when referenced in an output template will be replaced by the actual value corresponding to the sequence name. E.g. for -o %(title)s-%(id)s.%(ext)s and an mp4 video with title yt-dlp test video and id BaW_jenozKc, this will result in a yt-dlp test video-BaW_jenozKc.mp4 file created in the current directory.

Note: Some of the sequences are not guaranteed to be present, since they depend on the metadata obtained by a particular extractor. Such sequences will be replaced with placeholder value provided with --output-na-placeholder (NA by default).

Tip: Look at the -j output to identify which fields are available for the particular URL

For numeric sequences, you can use numeric related formatting; e.g. %(view_count)05d will result in a string with view count padded with zeros up to 5 characters, like in 00042.

Output templates can also contain arbitrary hierarchical path, e.g. -o "%(playlist)s/%(playlist_index)s - %(title)s.%(ext)s" which will result in downloading each video in a directory corresponding to this path template. Any missing directory will be automatically created for you.

To use percent literals in an output template use %%. To output to stdout use -o -.

The current default template is %(title)s [%(id)s].%(ext)s.

In some cases, you don't want special characters such as 中, spaces, or &, such as when transferring the downloaded filename to a Windows system or the filename through an 8bit-unsafe channel. In these cases, add the --restrict-filenames flag to get a shorter title.

Output Template Examples​

$ yt-dlp --print filename -o "test video.%(ext)s" BaW_jenozKc
test video.webm # Literal name with correct extension

$ yt-dlp --print filename -o "%(title)s.%(ext)s" BaW_jenozKc
youtube-dl test video ''_ä↭𝕐.webm # All kinds of weird characters

$ yt-dlp --print filename -o "%(title)s.%(ext)s" BaW_jenozKc --restrict-filenames
youtube-dl_test_video_.webm # Restricted file name

# Download YouTube playlist videos in separate directory indexed by video order in a playlist
$ yt-dlp -o "%(playlist)s/%(playlist_index)s - %(title)s.%(ext)s" "https://www.youtube.com/playlist?list=PLwiyx1dc3P2JR9N8gQaQN_BCvlSlap7re"

# Download YouTube playlist videos in separate directories according to their uploaded year
$ yt-dlp -o "%(upload_date>%Y)s/%(title)s.%(ext)s" "https://www.youtube.com/playlist?list=PLwiyx1dc3P2JR9N8gQaQN_BCvlSlap7re"

# Prefix playlist index with " - " separator, but only if it is available
$ yt-dlp -o "%(playlist_index&{} - |)s%(title)s.%(ext)s" BaW_jenozKc "https://www.youtube.com/user/TheLinuxFoundation/playlists"

# Download all playlists of YouTube channel/user keeping each playlist in separate directory:
$ yt-dlp -o "%(uploader)s/%(playlist)s/%(playlist_index)s - %(title)s.%(ext)s" "https://www.youtube.com/user/TheLinuxFoundation/playlists"

# Download Udemy course keeping each chapter in separate directory under MyVideos directory in your home
$ yt-dlp -u user -p password -P "~/MyVideos" -o "%(playlist)s/%(chapter_number)s - %(chapter)s/%(title)s.%(ext)s" "https://www.udemy.com/java-tutorial"

# Download entire series season keeping each series and each season in separate directory under C:/MyVideos
$ yt-dlp -P "C:/MyVideos" -o "%(series)s/%(season_number)s - %(season)s/%(episode_number)s - %(episode)s.%(ext)s" "https://videomore.ru/kino_v_detalayah/5_sezon/367617"

# Download video as "C:\MyVideos\uploader\title.ext", subtitles as "C:\MyVideos\subs\uploader\title.ext"
# and put all temporary files in "C:\MyVideos\tmp"
$ yt-dlp -P "C:/MyVideos" -P "temp:tmp" -P "subtitle:subs" -o "%(uploader)s/%(title)s.%(ext)s" BaW_jenozKc --write-subs

# Download video as "C:\MyVideos\uploader\title.ext" and subtitles as "C:\MyVideos\uploader\subs\title.ext"
$ yt-dlp -P "C:/MyVideos" -o "%(uploader)s/%(title)s.%(ext)s" -o "subtitle:%(uploader)s/subs/%(title)s.%(ext)s" BaW_jenozKc --write-subs

# Stream the video being downloaded to stdout
$ yt-dlp -o - BaW_jenozKc