Skip to content

Instantly share code, notes, and snippets.

@dcalacci
Forked from jmiserez/export_google_music.js
Last active August 2, 2022 15:15
Show Gist options
  • Save dcalacci/7f8853174797c0c56c49 to your computer and use it in GitHub Desktop.
Save dcalacci/7f8853174797c0c56c49 to your computer and use it in GitHub Desktop.
Export your Google Music Library and Playlists (Google Play Music All Access) (see http://webapps.stackexchange.com/questions/50311/print-playlist-from-google-play-music for more)
// A little bit of Javascript to let you export your Google Music library :)
//
// 1. Go to: https://play.google.com/music/listen#/all
//
// 2. Open a developer console (F12 for Chrome). Paste
// code below into the console.
//
// 3. All scraped songs are stored in the `allSongs` object
// and copied to the clipboard. I'd recommend saving this
// somewhere for future use.
//
// 4. If you would like the output in a text format, can call
// the songsToText() function. You can select a style and
// choose if only liked/thumbed up songs should be exported.
// The resulting list will then be pasted into the clipboard.
// Styles are `artist`, `artistalbum`, `artistsong`,
// `artistalbumsong`. Likedonly can be left out (defaults to
// false) or set to true, and will filter all songs with
// ratings greater or equal to 5.
// E.g: `songsToText("artistsong",true)` will export all liked songs.
//
// 5. You can then paste the data anywhere you like, for
// example http://www.ivyishere.org/ if you want to add the
// songs or albums to your Spotify account. To make Ivy
// recognize full albums, use the "artistalbum" style. For
// songs, use the "artistsong" style.
// originally answered here: http://webapps.stackexchange.com/a/73791/77056
var allsongs = [];
(function(){
var intervalms = 1; //in ms
var timeoutms = 3000; //in ms
var retries = timeoutms / intervalms;
var total = [];
var seen = {};
var topId = "";
var interval = setInterval(function(){
var songs = document.querySelectorAll("table.song-table tbody tr.song-row");
if (songs.length > 0) {
var currId = songs[0].getAttribute("data-id");
if (currId == topId){ // page has not yet changed
retries--;
scrollDiv = document.querySelector("div#music-content");
isAtBottom = scrollDiv.scrollTop == (scrollDiv.scrollHeight - scrollDiv.offsetHeight)
if (isAtBottom || retries <= 0) {
clearInterval(interval); //done
copy(total);
allsongs = total;
console.log("Done! " + total.length + " songs copied to clipboard.");
}
} else {
retries = timeoutms / intervalms;
topId = currId;
// read page
for (var i = 0; i < songs.length; i++) {
var curr = {name: songs[i].childNodes[0].textContent,
length: songs[i].childNodes[1].textContent,
artist: songs[i].childNodes[2].textContent,
album: songs[i].childNodes[3].textContent,
plays: songs[i].childNodes[4].textContent,
rating: songs[i].childNodes[5].getAttribute("data-rating"),
id: songs[i].getAttribute("data-id")
}
if (!seen.hasOwnProperty(curr.id)){ // hashset
total.push(curr);
seen[curr.id] = true;
}
}
songs[songs.length-1].scrollIntoView(true); // go to next page
}
}
}, intervalms);
}());
var songsToText = function(style, likedonly){
var likedonly = likedonly || false; // defaults to false
if (likedonly) {
console.log("Only selecting liked songs");
}
var outText = ""
var numEntries = 0;
var seen = {};
for (var i = 0; i < allsongs.length; i++) {
var curr = ""
if (!likedonly || (likedonly && allsongs[i].rating >= 5)){
if (style == "artist"){
curr = allsongs[i].artist;
} else if (style == "artistalbum"){
curr = allsongs[i].artist + " - " + allsongs[i].album;
} else if (style == "artistsong"){
curr = allsongs[i].artist + " - " + allsongs[i].song;
} else if (style == "artistalbumsong"){
curr = allsongs[i].artist + " - " + allsongs[i].album + " - " + allsongs[i].song;
} else {
console.log("style not defined");
}
if (!seen.hasOwnProperty(curr)){ // hashset
outText = outText + "\n" + curr;
numEntries++;
seen[curr] = true;
}
}
}
copy(outText);
console.log("Done! " + numEntries + " lines copied to clipboard. Used " + numEntries + " songs out of " + allsongs.length + ".");
}
@mikeyiss
Copy link

Getting the following error. How do I fix?

listen.js:1181 Uncaught gx {message: “Error in protected function: copy is not defined”, Osb: true, cause: ReferenceError: copy is not defined
at songsToText (:87:1)
at :130:1
…, stack: “ReferenceError: copy is not defined↵ at songsTo…0d8e628d55fb15f8053919494d29a/listen.js:1180:471)“}

@zhenyanevis
Copy link

Thank you a lot! You made my day!

@slumtrimpet
Copy link

Try https://musconv.com/ for export of the Google Music across many music platforms.

Actually don't this company spams the world with single-use throw away accounts to push their paid service.

@iozhukau
Copy link

Thanks so much for the script!!! It best solution!!!

Maybe you can replace allsongs[i].{spmething} on some like that:

getSongAttribute(i,'artist')

var getSongAttribute = function(index, attribute) {
  return allsongs[index][attribute].replace('\n','').replace('\r','').trim()
}

Because now there are escape characters and it brokes csv.

@diegogteixeira
Copy link

Thank you very much!

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