Last active
June 26, 2024 16:18
-
-
Save erkobridee/a1928f8bb63a43007ca250567ba71c28 to your computer and use it in GitHub Desktop.
how to get the chapters information from a youtube video
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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