Skip to content

Instantly share code, notes, and snippets.

@Ghost---Shadow
Last active April 6, 2024 09:25
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save Ghost---Shadow/e11a4a0c00b7ac26f1c88418b3359c4b to your computer and use it in GitHub Desktop.
Save Ghost---Shadow/e11a4a0c00b7ac26f1c88418b3359c4b to your computer and use it in GitHub Desktop.
Calculate the total length of a youtube playlist. Just open javascript console, paste and press enter.
/**
USAGE
1. Open the playlist you want
2. Right click > Inspect element > Console
3. Copy this and paste. Hit enter.
4. For watch later make sure to click the Edit button
Make sure &disable_polymer=true flag is set
e.g.
https://www.youtube.com/playlist?list=WL&disable_polymer=true
*/
const table = document.getElementById("pl-video-table")
const rows = Array.from(table.rows)
const toSeconds = s => s ? s.split(':').map(v => parseInt(v)).reverse().reduce((acc,e,i) => acc + e * Math.pow(60,i)) : 0
const getTimestamp = row => toSeconds(row.children[6].children[0].children[0].innerText)
let seconds = rows.reduce((acc,e) => acc + getTimestamp(e),0)
let mins = parseInt(seconds / 60)
seconds %= 60
let hours = parseInt(mins / 60)
mins %= 60
console.log(hours+":"+mins+":"+seconds)
@surajsly
Copy link

surajsly commented Dec 1, 2019

It is not working . can you provide any other solution.

@Ghost---Shadow
Copy link
Author

@surajsly
Copy link

surajsly commented Dec 5, 2019

Thanks @Ghost--Shadow it is working now.

@H-G-Hristov
Copy link

H-G-Hristov commented Jan 16, 2020

How about that:

function main(){
 const durationContainers = Array.from(document.getElementById("items").getElementsByClassName("style-scope ytd-thumbnail-overlay-time-status-renderer"));
 var durations = durationContainers.map(__span => __span.innerText).map(duration => {
   if (duration) {
     return duration.split(":").map(duration => parseInt(duration)).reverse().reduce((acc, e, i) => {
       return acc + e * Math.pow(60, i);
     });
   }
   else {
     return 0;
   }
 });
 durations = durations.filter(element => 0 !== element);
 console.log(durations);
 const totalSeconds = durations.reduce((acc, e, _) => {
   return acc + e;
 });

 const seconds = totalSeconds % 60;
 const minutes = Math.floor(totalSeconds / 60) % 60;
 const hours = Math.floor(totalSeconds / 3600)

 console.log(totalSeconds);
 console.log(hours + ":" + minutes + ":" + seconds);
};
main();

@Ghost---Shadow
Copy link
Author

LGTM

@abonzer
Copy link

abonzer commented Apr 23, 2020

var ytp = document.querySelectorAll("ytd-playlist-video-list-renderer > #contents > ytd-playlist-video-renderer");
var time = 0;

for (var i = 0; i < ytp.length; i++) {
    var a = ytp[i].getElementsByTagName('ytd-thumbnail-overlay-time-status-renderer')[0].innerText;
    var tx = a.split(':');
    if (tx.length < 3) {
        time = time + Number(tx[0]) * 60 + Number(tx[1]);
    } else if (tx.length = 3) {
        time = time + Number(tx[0]) * 60 * 60 + Number(tx[1]) * 60 + Number(tx[2]);
    }
}

var ytpT = convertS(time)
var show = 'YouTube Playlist \n --------------- \n Total Videos : ' + ytp.length + '\n Total Duration : ' + ytpT + '\n Avg. Duration  : ' + convertS(time / ytp.length);
alert(show);


function convertS(sec) {
    var hrs = Math.floor(sec / 3600);
    var min = Math.floor((sec - (hrs * 3600)) / 60);
    var seconds = sec - (hrs * 3600) - (min * 60);
    seconds = Math.round(seconds * 100) / 100

    var result = (hrs < 10 ? "0" + hrs : hrs) + ' Hours ';
    result += (min < 10 ? "0" + min : min) + " Min ";
    result += (seconds < 10 ? "0" + seconds : seconds) + ' Sec ';
    return result;
}

@Ghost---Shadow
Copy link
Author

Why is this so popular?

@jjisnow
Copy link

jjisnow commented Jun 11, 2020

Because the response is simple, doesn't require an app or too many weird permissions, and works via copy and paste. Also, playlists with durations are really needed

@mageddo
Copy link

mageddo commented Sep 25, 2020

Fully working, thx

@abhishekgoyal-a11y
Copy link

Get YouTube playlist length visit:- YouTube playlist length

@Ghost---Shadow
Copy link
Author

@abhishekgoyal-a11y Pretty good. Doesnt work on Watch Later though.

@abhishekgoyal-a11y
Copy link

@abhishekgoyal-a11y Pretty good. Doesnt work on Watch Later though.

Meaning?

@Ghost---Shadow
Copy link
Author

@abhishekgoyal-a11y Pretty good. Doesnt work on Watch Later though.

Meaning?

This https://www.youtube.com/playlist?list=WL

@gludion
Copy link

gludion commented Aug 13, 2021

Bookmarkable version of @abonzer proposal:
(use this as the URL for a bookmark, click on the bookmark when u're on a youtube playlist page)
javascript: function convertS(sec) {var hrs = Math.floor(sec / 3600); var min = Math.floor((sec - (hrs * 3600)) / 60); var seconds = sec - (hrs * 3600) - (min * 60); seconds = Math.round(seconds * 100) / 100;var result = (hrs < 10 ? "0" + hrs : hrs) + ' Hours '; result += (min < 10 ? "0" + min : min) + " Min "; result += (seconds < 10 ? "0" + seconds : seconds) + ' Sec '; return result; }; var ytp = document.querySelectorAll("ytd-playlist-video-list-renderer > #contents > ytd-playlist-video-renderer");var time = 0; for (var i = 0; i < ytp.length; i++) {var a = ytp[i].getElementsByTagName('ytd-thumbnail-overlay-time-status-renderer')[0].innerText;var tx = a.split(':'); if (tx.length < 3) {time = time + Number(tx[0]) * 60 + Number(tx[1]);} else if (tx.length = 3) {time = time + Number(tx[0]) * 60 * 60 + Number(tx[1]) * 60 + Number(tx[2]);}}; var ytpT = convertS(time); var show = 'YouTube Playlist \n --------------- \n Total Videos : ' + ytp.length + '\nTotal Duration : ' + ytpT + '\n Avg. Duration : ' + convertS(time / ytp.length);alert(show);

@1alexvash
Copy link

var ytp = document.querySelectorAll("ytd-playlist-video-list-renderer > #contents > ytd-playlist-video-renderer");
var time = 0;

for (var i = 0; i < ytp.length; i++) {
    var a = ytp[i].getElementsByTagName('ytd-thumbnail-overlay-time-status-renderer')[0].innerText;
    var tx = a.split(':');
    if (tx.length < 3) {
        time = time + Number(tx[0]) * 60 + Number(tx[1]);
    } else if (tx.length = 3) {
        time = time + Number(tx[0]) * 60 * 60 + Number(tx[1]) * 60 + Number(tx[2]);
    }
}

var ytpT = convertS(time)
var show = 'YouTube Playlist \n --------------- \n Total Videos : ' + ytp.length + '\n Total Duration : ' + ytpT + '\n Avg. Duration  : ' + convertS(time / ytp.length);
alert(show);


function convertS(sec) {
    var hrs = Math.floor(sec / 3600);
    var min = Math.floor((sec - (hrs * 3600)) / 60);
    var seconds = sec - (hrs * 3600) - (min * 60);
    seconds = Math.round(seconds * 100) / 100

    var result = (hrs < 10 ? "0" + hrs : hrs) + ' Hours ';
    result += (min < 10 ? "0" + min : min) + " Min ";
    result += (seconds < 10 ? "0" + seconds : seconds) + ' Sec ';
    return result;
}

This is amazing, thank you ♥♥♥♥

@wongcyrus
Copy link

The scripts is useful but my use case is to have the individual video length and I modified the script a bit.
You can get download the CSV file.

var ytp = document.querySelectorAll("ytd-playlist-video-list-renderer > #contents > ytd-playlist-video-renderer");
var time = 0;

function convertS(sec) {
    var hrs = Math.floor(sec / 3600);
    var min = Math.floor((sec - (hrs * 3600)) / 60);
    var seconds = sec - (hrs * 3600) - (min * 60);
    seconds = Math.round(seconds * 100) / 100

    var result = (hrs < 10 ? "0" + hrs : hrs) + ':';
    result += (min < 10 ? "0" + min : min) + ":";
    result += (seconds < 10 ? "0" + seconds : seconds);
    return result;
}
var videos = [];
for (var i = 0; i < ytp.length; i++) {
    var a = ytp[i].getElementsByTagName('ytd-thumbnail-overlay-time-status-renderer')[0].innerText;
    var tx = a.split(':');
    var title = ytp[i].getElementsByTagName("a")[1].title;
    if (tx.length < 3) {
        videoLength = Number(tx[0]) * 60 + Number(tx[1]);
        time = time + Number(tx[0]) * 60 + Number(tx[1]);
    } else if (tx.length = 3) {
        time = time + Number(tx[0]) * 60 * 60 + Number(tx[1]) * 60 + Number(tx[2]);
        videoLength = Number(tx[0]) * 60 * 60 + Number(tx[1]) * 60 + Number(tx[2]);
    }

    videos.push({ title, videoLength: convertS(videoLength), Seconds: videoLength });
}

function download_csv_file() {

    //define the heading for each row of the data  
    var csv = 'Video,Length,Seconds\n';

    //merge the data with CSV  
    videos.forEach(function (row) {
        csv += row.title + "," + row.videoLength + "," + row.Seconds;
        csv += "\n";
    });

    //display the created CSV data on the web browser   
    document.write(csv);


    var hiddenElement = document.createElement('a');
    hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
    hiddenElement.target = '_blank';

    //provide the name for the CSV file to be downloaded  
    hiddenElement.download = 'YoutubePlayList.csv';
    hiddenElement.click();
}

var ytpT = convertS(time)
var show = 'YouTube Playlist \n --------------- \n Total Videos : ' + ytp.length + '\n Total Duration : ' + ytpT + '\n Avg. Duration  : ' + convertS(time / ytp.length);
// alert(show);
// console.log(videos);
download_csv_file();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment