Using yt-dlp, you can distinguish between the following two types of subtitles:
-
Uploaded subtitles: Located in the
subtitlesfield, usually provided by the author, channel, or content provider. -
Auto-generated captions: Located in the
automatic_captionsfield, generated by YouTube's automatic speech recognition or auto-translation.
Note: The presence of uploaded subtitles does not necessarily mean they were manually created by the author.
For example, subtitles for some news videos might come from the program's built-in Closed Captions.
Test Videos
Has uploaded subtitles:
https://www.youtube.com/watch?v=7ARBJQn6QkM
No uploaded subtitles:
https://www.youtube.com/watch?v=SS5uEinPuncViewing the Subtitle List
yt-dlp \
--js-runtimes node \
--list-subs \
"https://www.youtube.com/watch?v=7ARBJQn6QkM"--list-subs will output separately:
Available automatic captions for ...and:
Available subtitles for ...The former refers to auto-generated captions, and the latter refers to uploaded subtitles.
When the output shows:
[info] Available subtitles for 7ARBJQn6QkM:
Language Name Formats
en English vtt, srt, ttml, srv3, srv2, srv1, json3It indicates that the video has uploaded subtitles with the language code en.
When the output shows:
SS5uEinPunc has no subtitlesIt indicates that the video does not have uploaded subtitles.
This does not mean the video definitely has no auto-generated captions; for automatic captions, you need to check the Available automatic captions section.
JavaScript Runtime
Parameter:
--js-runtimes nodeThis allows yt-dlp to use Node.js to execute YouTube's JavaScript challenge solver.
Before using this parameter, ensure that a compatible version of Node.js is installed on your system:
node --versionYou can also use other JavaScript runtimes supported by yt-dlp. For example, if Bun is installed, you can use:
--js-runtimes bunIn some cases, not specifying --js-runtimes still allows you to fetch video information, but there might be missing formats or features, so it is not recommended as a long-term configuration.
Using jq for Determination
--list-subs might output a large number of auto-generated and auto-translated captions. When you need to make determinations in a script, it is recommended to read the JSON output from yt-dlp instead of parsing terminal logs.
Installing jq
macOS:
brew install jqDetermining if Uploaded Subtitles Exist
yt-dlp \
--js-runtimes node \
--skip-download \
--dump-single-json \
"https://www.youtube.com/watch?v=7ARBJQn6QkM" \
| jq -r '
if ((.subtitles // {}) | length) > 0 then
"Has uploaded subtitles: " + ((.subtitles | keys) | join(", "))
else
"No uploaded subtitles"
end
'Possible output:
Has uploaded subtitles: enThis reads from:
subtitlesInstead of:
automatic_captionsTherefore, it will not mistakenly identify YouTube's auto-generated or auto-translated captions as uploaded subtitles.
Using grep for Determination
When doing a quick check in the Shell, you can also match the output of --list-subs:
output=$(
yt-dlp \
--js-runtimes node \
--list-subs \
"https://www.youtube.com/watch?v=7ARBJQn6QkM" \
2>&1
)
if echo "$output" | grep -q "Available subtitles for"; then
echo "Has uploaded subtitles"
else
echo "No uploaded subtitles"
fiThis method relies on yt-dlp's terminal output text, making it suitable for quick checks but not recommended as the core determination logic for a long-term workflow.
For long-term use, you should prioritize parsing the subtitles field returned by --dump-single-json.
Creating a Custom Command
You can encapsulate the determination logic into a globally available Shell command.
Creating the Script
Create the file:
~/MyFiles/bin/has-youtube-subsWith the following content:
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -ne 1 ]]; then
echo "Usage: has-youtube-subs <YouTube URL>" >&2
exit 1
fi
yt-dlp \
--js-runtimes node \
--skip-download \
--dump-single-json \
"$1" \
| jq -r '
if ((.subtitles // {}) | length) > 0 then
"Has uploaded subtitles: " + ((.subtitles | keys) | join(", "))
else
"No uploaded subtitles"
end
'Adding Execute Permission
chmod +x ~/MyFiles/bin/has-youtube-subsAdding the Script Directory to PATH
Open:
vim ~/.zshrcAdd:
export PATH="$HOME/MyFiles/bin:$PATH"Apply the configuration immediately:
source ~/.zshrcExecuting the Command
has-youtube-subs \
"https://www.youtube.com/watch?v=7ARBJQn6QkM"Output:
Has uploaded subtitles: enOnce this command is added to your PATH, it can be executed from any directory.
Determining on the YouTube Website
Open the video player and click in order:
Settings (gear icon)
→ Subtitles/CCAppearing:
EnglishUsually indicates that this track is not a YouTube auto-generated caption.
Appearing:
English (auto-generated)Explicitly indicates that this caption was generated by YouTube's automatic speech recognition system.
Please note:
EnglishOnly indicates that it is not a subtitle track labeled as auto-generated; you cannot conclusively determine based on this that the subtitles were manually created by the video author.