Skip to content

Instantly share code, notes, and snippets.

@erkobridee
Last active June 26, 2024 16:18
Show Gist options
  • Save erkobridee/a1928f8bb63a43007ca250567ba71c28 to your computer and use it in GitHub Desktop.
Save erkobridee/a1928f8bb63a43007ca250567ba71c28 to your computer and use it in GitHub Desktop.
how to get the chapters information from a youtube video
/*
code to be executed on the youtube video page at the web developer tools console tab
*/
// youtube video title
document.querySelector('meta[name="title"]').content
// youtube video description
document.querySelector('meta[name="description"]').content
// youtube video meta property starts with og:
for(const meta of document.querySelectorAll('meta[property^="og:"]')) { const {content} = meta; console.log({ property: meta.attributes['property'].value, content }); }
// youtube video meta name starts with twitter:
for(const meta of document.querySelectorAll('meta[name^="twitter:"]')) { const {content} = meta; console.log({ name: meta.attributes['name'].value, content }); }
// youtube video meta itemprop
for(const meta of document.querySelectorAll('meta[itemprop]')) { const {content} = meta; console.log({ itemprop: meta.attributes['itemprop'].value, content }); }
/*
document.querySelector('meta[itemprop="datePublished"]').content
document.querySelector('meta[itemprop="uploadDate"]').content
// publish date text
document.querySelector('#info-strings yt-formatted-string.style-scope.ytd-video-primary-info-renderer').innerText
*/
// youtube video channel name
let { href: channelUrl, textContent: channelName } = document.querySelector('.ytd-channel-name > a');
console.log({ channelName, channelUrl });
// youtube video details
console.log("video details:\n", ytInitialPlayerResponse.videoDetails);
// youtube video chapters
function parseChapters() {
const allElements = Array.from(
document.querySelectorAll(
"#panels ytd-engagement-panel-section-list-renderer:nth-child(2) #content ytd-macro-markers-list-renderer #contents ytd-macro-markers-list-item-renderer #endpoint"
)
);
const withTitleAndTime = allElements.map((node) => ({
title: node.querySelector(".macro-markers")?.textContent,
timestamp: node.querySelector("#time")?.textContent,
data: node.data
}));
const filtered = withTitleAndTime.filter(
(element) =>
element.title !== undefined &&
element.title !== null &&
element.timestamp !== undefined &&
element.timestamp !== null
);
const withoutDuplicates = [
...new Map(filtered.map((node) => [node.timestamp, node])).values(),
];
return withoutDuplicates;
}
function toMdLink(chapters) {
return chapters.map(({timestamp, title, data: { commandMetadata: { webCommandMetadata: { url } } }}) => `- [${timestamp.length === 4 ? `0${timestamp}` : timestamp}](https://www.youtube.com${url}) ${title}`).join('\n')
}
console.log(toMdLink(parseChapters()));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment