I mostly use yt-dlp
for saving offline copies of technology tutorials and the like, so might need to adjust for your use-case. I like capturing a lot of non-standard metrics like # likes / # views / the date I downloaded the video, as I find this info useful when I've downloaded 4 or 5 tutorials and want to see which one had been the most popular at the time I downloaded them (helps me to pick the first one to watch). The link in the other answer is a very good reference. But since the (currently only) other answer didn't attempt to explain details very thoroughly or provide any concrete examples, I decided to attempt to add one based on my own experiences as well.
I use a large wrapper function and a lot of this is actually controlled by variables/function arguments in my setup but here is an example of the command that gets generated if I want to download a particular video format in 480p (generally on screen text commands become difficult to read at lower resolutions and high resolutions eat up more disk space).
This is from a bash
shell function on Linux but aside from how I use the variable, everything in yt-dlp
itself should be cross-platform. Obviously, you don't need all the options I am using; I just wanted to provide a complete example. The relevant options are explained below the snippet.
local downloadTimestamp="$(date +'%F %T %Z')";
# double-escape any colons ONCE to prevent them being interpreted by --parse-metadata
downloadTimestamp="${downloadTimestamp//:/\\:}";
yt-dlp -f "bestvideo+bestaudio/best" \
--format-sort res:480,+size,+br,codec \
-o "%(uploader)s_-_%(title)s.%(ext)s" \
--parse-metadata "${downloadTimestamp}:%(meta_download_date)s" \
--parse-metadata "%(like_count)s:%(meta_likes)s" \
--parse-metadata "%(dislike_count)s:%(meta_dislikes)s" \
--parse-metadata "%(view_count)s:%(meta_views)s" \
--parse-metadata "%(average_rating)s:%(meta_rating)s" \
--parse-metadata "%(release_date>%Y-%m-%d,upload_date>%Y-%m-%d)s:%(meta_publish_date)s" \
--restrict-filenames --windows-filenames \
--quiet --no-warnings \
--ignore-errors --prefer-free-formats \
--xattrs --no-overwrites \
--sub-lang en --embed-subs --add-metadata --merge-output-format mkv \
--write-auto-subs --embed-metadata --embed-thumbnail \
"${url}"
--parse-metadata
has a TO:FROM
argument syntax. Despite the name not being the most intuitive if your goal is to capture some kind of metadata from the page and have it embedded in the downloaded file, this is the most relevant option that you need to use for mapping values. The --embed-metadata
option is also important for having the metadata embedded into the audio/video file rather than as a 2nd file.
The TO
part of the --parse-metadata
argument can be a string literal or some text that you expand from a variable in a script. Or it can be another yt-dlp
format string like %(artist)s
or %(title)s
(Note: the format strings used here are the SAME ones that you use for creating the output template. The full list can be found here - look for the text "The available fields are"). The format string can also be customized like %(release_date>%Y-%m-%d)s
. You can even have a custom format string that falls back to secondary field if the first field is empty (e.g. %(release_date>%Y-%m-%d,upload_date>%Y-%m-%d)s
). If you are adding string literals or values from variables, it is important to make sure that either no colons (:
) are present or else to escape any colons that are intended as part of the value using backslashes as I have done with the downloadTimestamp
in the above. For example:
--parse-metadata "Tutorial\\:Intro to parse-metadata:%(meta_dummy)s"
or
--parse-metadata 'Foo\:Bar:%(meta_dummy)s'
The FROM
part of the --parse-metadata
argument is basically the word "meta" followed by an underscore and the name of an existing or new metadata field. The field name is specified as lowercase in --parse-metadata
but seems to be created in all caps in the actual file. All of the fields I am referencing in the above snippet are custom fields that I made up.
I could then view them in the downloaded file later using mediainfo
or similar tools. For example, on Linux, I can do this (note: mediainfo
is cross-platform and there is a GUI for it if you are not comfortable with terminal):
mediainfo --Language=raw --Full --Inform="General;%LIKES%" "${filePath}"
# 3
mediainfo --Language=raw --Full --Inform="General;%VIEWS%" "${filePath}"
# 95
mediainfo --Language=raw --Full --Inform="General;%PUBLISH_DATE%" "${filePath}"
# 2022-04-05
mediainfo --Language=raw --Full --Inform="General;%DISLIKES%" "${filePath}"
# NA
You would get NA
for the DISLIKES
field if it was never captured. This could happen for instance if you get a video from a site with no rating/dislike system. Or, for youtube specifically, if you tried to capture that metadata for a channel/video that doesn't enable dislikes (which is the default these days).