Skip to content

Instantly share code, notes, and snippets.

@TheOnlyWayUp
Last active December 19, 2024 14:09
Show Gist options
  • Save TheOnlyWayUp/4452b0a5c151740417c16f3518fb701e to your computer and use it in GitHub Desktop.
Save TheOnlyWayUp/4452b0a5c151740417c16f3518fb701e to your computer and use it in GitHub Desktop.
Like all songs in a Youtube Music Playlist

This script likes all the songs in a Youtube Music Playlist at once.

How to use:

  • Visit a Playlist's page on ytm (URL looks like: https://music.youtube.com/playlist?list=...
  • Press ctrl + shift + j. This opens the Developer Console.
  • Copy the script in this gist (That's in script.js)
  • Paste the code into the Developer Console on the ytm Tab, hit enter.
  • Great, you're done!

Star ⭐ this gist if it was useful. Follows to my GitHub Profile are appreciated.

Follow Badge


TheOnlyWayUp © 2024

// made by https://github.com/TheOnlyWayUp, if it helped, drop a follow!
// source: https://gist.github.com/TheOnlyWayUp/4452b0a5c151740417c16f3518fb701e
let interval = 10 // wait time between chunks in seconds
const chunk = size => array => array.reduce((result, item) => {
if (result[result.length - 1].length < size) {
result[result.length - 1].push(item);
} else {
result.push([item]);
}
return result;
}, [
[]
]); // Thanks https://stackoverflow.com/a/77372180
function likeall() {
let els = document.getElementById("contents").querySelectorAll(
"button[aria-pressed=false][aria-label='Like']")
console.log(`${els.length} to Like`)
let cels = chunk(5)(Array.from(els))
cels.forEach(function(items, index) {
setTimeout(function() {
console.log("start")
items.forEach(el => el.click())
console.log("end")
}, index *
interval * 1000); // Thanks https://stackoverflow.com/a/45500721
});
}
likeall()
@adiologydev
Copy link

Updated Version :) Now shows the progress!

let total = 0;
let left = 0;
let interval = 10  // wait time between chunks in seconds

const ytmLog = msg => console.log(`[YTM Liker] ${msg}`);

const chunk = size => array => array.reduce((result, item) => {
    if (result[result.length - 1].length < size) {
        result[result.length - 1].push(item);
    } else {
        result.push([item]);
    }
    return result;
}, [
    []
]);

function likeAll() {
    let els = document.getElementById("contents").querySelectorAll(
        "button[aria-pressed=false][aria-label='Like']");

    total = els.length; left = els.length;
    ytmLog(`Total Queue: ${total}`);

    let cels = chunk(5)(Array.from(els));
    cels.forEach(function(items, index) {
        setTimeout(function() {
            ytmLog('Liking next chunk.');
            items.forEach(el => el.click());
            left = left - 5;
            ytmLog('Chunk finished. Waiting to start the next.');
            ytmLog(`${left} songs left out of ${total}.`);
        }, index *
        interval * 1000);
    });
}

likeAll();

Haven't done enough testing so sometimes the numbers may be wrong, but it worked :)

Output:
image

@WhiteBearSpirit
Copy link

For those who get no songs by running this script: just check your language is set to English, so that YT music webpage has aria-label='Like' elements

@zamora
Copy link

zamora commented Jun 26, 2024

Be careful using this script. I used it when transferring my music to a new account, and my channel got suspended because YouTube thought I was doing "Fake Engagement" by automating likes.

@KnoBuddy
Copy link

KnoBuddy commented Aug 16, 2024

Be careful using this script. I used it when transferring my music to a new account, and my channel got suspended because YouTube thought I was doing "Fake Engagement" by automating likes.

Well we are about to find out. This is the account linked to an account I use google paid services on, and it is months old, and I have 1400ish songs to move. Which btw, you can't even view all 1400 songs in one go in the window so this script will have to be used multiple times and the liked playlist refreshed and possibly try and duplicate clicking the like button.

I may try changing the interval time to 20 seconds or so for the next batch, currently doing ~450 songs. I would love to see a modification to not like the button if already liked, maybe chat GPT can help me. I'm well versed in python but JS isn't my thing.

I tried doing this on both soundliz and tunemymusic,, I guess I needed it to create the playlist in the first place because you can't make your liked music a seperate playlist and a public link, but I only needed one of the services. Was hoping one of them had figured this out...

It also seems that music.youtube.com has about a 1000 song limit before it won't load any new tracks from a playlist. If you have a very large playlist you will need to refresh and rescroll and rerun the script several times to get all the songs added. Use the updated script below to help mitigate these issues.

@KnoBuddy
Copy link

KnoBuddy commented Aug 16, 2024

Made some changes and forked the gist. Hope this helps some people. Changes and credit is in the original script and I'll post the code here for others as well.

Changes Made:

  1. likeNext Function: This function is responsible for processing each song one by one.
  2. Conditionally Engage Wait: If a song is already liked (aria-pressed="true"), it skips the wait period and moves to the next song immediately.
  3. Wait Only for Unliked Songs: The wait period is only applied when a song is actually liked.
  4. Timer Initialization: The script initializes a startTime at the beginning of the script using Date.now().
  5. Elapsed Time Calculation: After each action (whether a song is liked or skipped), the script calculates the elapsed time by subtracting startTime from the current time and then converts it to seconds with two decimal precision.
  6. Output with Timer: The elapsed time is appended to each log output, providing a real-time view of how long the script has been running after each action.
  7. Updated Remaining Count for Skipped Songs: When a song is already liked, the script now subtracts one from the left count, updating the remaining number of songs.
  8. Log Message Update: The log message now reflects the updated number of songs left, regardless of whether the song was liked or skipped.

Hope this helps others. New gist is: https://gist.github.com/KnoBuddy/9498ec7fd6cf9a32f8bc530ef43cfb57

// script originally made by https://github.com/TheOnlyWayUp, if it helped, drop a follow!
// source: https://gist.github.com/TheOnlyWayUp/4452b0a5c151740417c16f3518fb701e
// added features by https://github.com/KnoBuddy
// new source: https://gist.github.com/KnoBuddy/9498ec7fd6cf9a32f8bc530ef43cfb57
// Added features by KnoBuddy:
// 1. likeNext Function: This function is responsible for processing each song one by one.
// 2. Conditionally Engage Wait: If a song is already liked (aria-pressed="true"), it skips the wait period and moves to the next song immediately.
// 3. Wait Only for Unliked Songs: The wait period is only applied when a song is actually liked.
// 4. Timer Initialization: The script initializes a startTime at the beginning of the script using Date.now().
// 5. Elapsed Time Calculation: After each action (whether a song is liked or skipped), the script calculates the elapsed time by subtracting startTime from the current time and then converts it to seconds with two decimal precision.
// 6. Output with Timer: The elapsed time is appended to each log output, providing a real-time view of how long the script has been running after each action.
// 7. Updated Remaining Count for Skipped Songs: When a song is already liked, the script now subtracts one from the left count, updating the remaining number of songs.
// 8. Log Message Update: The log message now reflects the updated number of songs left, regardless of whether the song was liked or skipped.

let total = 0;
let left = 0;
let interval = 10;  // wait time between clicks for unliked songs in seconds
const startTime = Date.now();

const ytmLog = msg => {
    const elapsedTime = ((Date.now() - startTime) / 1000).toFixed(2); // time in seconds
    console.log(`[YTM Liker] ${msg} (Elapsed Time: ${elapsedTime}s)`);
};

function likeAll() {
    let els = document.getElementById("contents").querySelectorAll(
        "button[aria-pressed='false'][aria-label='Like']"
    );

    total = els.length; 
    left = els.length;
    ytmLog(`Total Queue: ${total}`);

    function likeNext(index) {
        if (index >= els.length) {
            ytmLog('All songs processed.');
            return;
        }

        let el = els[index];

        // Check if the song is unliked
        if (el.getAttribute("aria-pressed") === "false") {
            el.click();
            left--;
            ytmLog(`Liked a song. ${left} songs left out of ${total}.`);

            // Wait before liking the next unliked song
            setTimeout(() => likeNext(index + 1), interval * 1000);
        } else {
            left--;  // Subtract the skipped song from the remaining count
            ytmLog(`Song already liked. Skipping wait. ${left} songs left out of ${total}.`);
            likeNext(index + 1);  // No wait, move to the next song
        }
    }

    likeNext(0);
}

likeAll();

@KnoBuddy
Copy link

KnoBuddy commented Aug 16, 2024

Dropped a reddit post about this with better explanation for end users with less tech skills. You can find it here: Seamlessly Transfer Your Liked Songs to a New Google Account—No Playlists Needed, Just Pure Likes! YouTube Music will know you just as it did in the old account.

Also added a randomized timing script that will take much longer than the standard 10 second interval script to possibly avoid the "Fake Engagement" problem.

@TheOnlyWayUp
Copy link
Author

Dropped a reddit post about this with better explanation for end users with less tech skills. You can find it here: Seamlessly Transfer Your Liked Songs to a New Google Account—No Playlists Needed, Just Pure Likes! YouTube Music will know you just as it did in the old account.

Also added a randomized timing script that will take much longer than the standard 10 second interval script to possibly avoid the "Fake Engagement" problem.

Heya, this is a cool tool!
The readme asks users to make the playlist public, maybe mention that unlisted playlists would work just as fine?

Thanks for the credit on the readme :)

@KnoBuddy
Copy link

KnoBuddy commented Aug 18, 2024

Good idea unlisted would work as well!

Didn't see a license file so... I was just hoping you'd be cool with it if I dropped you some credit. 👍👍👍

@aawezhussain
Copy link

aawezhussain commented Sep 21, 2024

The code isn't working currently. It says all songs processed but it haven't liked more than 3 songs.
image

So I wrote a code myself which could be found in https://github.com/aawezhussain/Youtube-Music-Auto-Playlist-Liker

@TheOnlyWayUp
Copy link
Author

TheOnlyWayUp commented Sep 27, 2024

The code isn't working currently. It says all songs processed but it haven't liked more than 3 songs. image

So I wrote a code myself which could be found in https://github.com/aawezhussain/Youtube-Music-Auto-Playlist-Liker

Credit in your repo would've been nice.

I like the idea of using scrollBy, that's smart, cc @KnoBuddy

Edit: The code looks original/rewritten, nice work.

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