Skip to content

Instantly share code, notes, and snippets.

@aroques
Last active April 23, 2023 13:48
Show Gist options
  • Save aroques/09b124f674260887c0ea1dc9e895b022 to your computer and use it in GitHub Desktop.
Save aroques/09b124f674260887c0ea1dc9e895b022 to your computer and use it in GitHub Desktop.
/**
* Get statistics for YouTube playlists.
*
* Navigate to YouTube playlist before executing.
* For example:
* https://www.youtube.com/playlist?list=PL3NaIVgSlAVLHty1-NuvPa9V0b0UwbzBd
*/
function getYouTubePlaylistStats() {
const timeElementsSelector = 'ytd-playlist-video-list-renderer ytd-thumbnail-overlay-time-status-renderer #text';
const timeElements = Array.from(document.querySelectorAll(timeElementsSelector));
if (!timeElements.length) throw new Error(`No elements for selector '${timeElementsSelector}'.`);
const secondsOfEachVideo = timeElements
.map(element => element.innerText)
.filter(timeText => timeText)
.map(timeTextToTimestampArray)
.map(timestampArrayToSeconds);
const total = sum(secondsOfEachVideo);
const count = secondsOfEachVideo.length;
return {
count,
total: secondsToTimestamp(total),
avg: secondsToTimestamp(total / count),
min: secondsToTimestamp(Math.min(...secondsOfEachVideo)),
max: secondsToTimestamp(Math.max(...secondsOfEachVideo)),
};
}
/**
* Example Output:
* - **Average:** 00:54:17 / 7 = 00:07:45
* - **Range:** 00:03:10 - 00:12:27
*/
function format(statistics) {
const {count, total, avg, min, max} = statistics;
const indentationLevel = 4;
const indentation = ' '.repeat(indentationLevel);
return [
`**Average:** ${total} / ${count} = ${avg}`,
`**Range:** ${min} - ${max}`
].map(line => indentation + '- ' + line).join('\n');
}
function sum(array) {
return array.reduce((sum, value) => sum + value, 0);
}
function secondsToTimestamp(seconds) {
const date = new Date(0);
date.setSeconds(seconds);
return date.toISOString().substring(11, 19);
}
function timestampArrayToSeconds(timestampArray) {
const [hours, minutes, seconds] = timestampArray;
return (hours * 60 * 60) + (minutes * 60) + (seconds);
}
/**
* Example YouTube timeText values: '0:56', '10:08', '9:56:46'.
*/
function timeTextToTimestampArray(timeText) {
const parts = timeText
.split(':')
.map(n => parseInt(n, 10));
return padArrayLeft(parts, 3, 0);
}
function padArrayLeft(array, length, element) {
const filledArray = Array(length).fill(element);
return filledArray.concat(array).slice(array.length);
}
console.log(format(getYouTubePlaylistStats()));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment