10

Some YouTube content creators split their videos into chapters. A subset of them kindly offer the list of chapters titles on description video, with their starting timestamp. Sometimes they decide not to show them.

How can I get the list of chapters titles?

1

3 Answers 3

8

One-liner to do this using yt-dlp (better alternative to youtube-dl) and jq JSON processor:

yt-dlp --dump-json videoIDorURL | jq --raw-output ".chapters[].title" 

To get starting timestamps:

 | jq --raw-output ".chapters[].start_time" | awk '{printf("%d:%02d:%02d\n",($1/60/60%24),($1/60%60),($1%60))}' 

With paste and process substitution you can combine both. This is a function you could add to your .bashrc/.zshrc:

function get_chapters_times() { paste <(yt-dlp --dump-json $1 | jq --raw-output ".chapters[].start_time" | awk '{printf("%d:%02d:%02d\n",($1/60/60%24),($1/60%60),($1%60))}') <(yt-dlp --dump-json $1 | jq --raw-output ".chapters[].title") } 

Will return:

$ get_chapters_times https://youtu.be/DxL2HoqLbyA 0:00:00 Intro 0:02:15 History 0:04:16 Ideal Engine 0:09:48 Entropy 0:11:03 Energy Spread 0:14:49 Air Conditioning 0:17:26 Life on Earth 0:19:35 The Past Hypothesis 0:21:43 Hawking Radiation 0:23:31 Heat Death of the Universe 0:24:52 Conclusion 

Use yt-dlp --split-chapters to download each chapter.

0
1

In python, you can do this:

import datetime import yt_dlp ydl = yt_dlp.YoutubeDL({'dumpjson':True } ) dnwl_setting = False with ydl: result = ydl.extract_info( ytdl_variables.video_url, download=dnwl_setting ) for chpt in result['chapters'] : str_start_time = chpt['start_time'] str_start_time_cnv = str(datetime.timedelta(seconds=str_start_time) ) str_title = chpt['title'] # for youtube timecodes print ( f"time = {str_start_time_cnv} | title = {str_title } ") 
0

Here's a fancier one-liner inspired by Pablo's answer that does away with process substitution and having to define functions:

yt-dlp videoURL --dump-json | jq -r ".chapters[] | {start_time, title}" | awk -v count="2" '++count==4{$0=sprintf(" \"start\":%d:%02d:%02d",($2/60/60%24),($2/60%60),($2%60));count=0} 1' | awk -F '":' '{print $2}' | gsed -r -e '/^\s*$/d' -e 's/^ "|"$//g' | paste -d " " - -

The awks and gsed could probably be merged into each other at the cost of more complexity.

If using yt-dlp, you may also benefit from --embed-chapters (alias: --add-chapters) argument.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.