Type in your question below and we'll check to see what answers we can find...
Loading article...
Submitting...
If you couldn't find any answers in the previous step then we need to post your question in the community and wait for someone to respond. You'll be notified when that happens.
Simply add some detail to your question and refine the title if needed, choose the relevant category, then post.
Before we can post your question we need you to quickly make an account (or sign in if you already have one).
Don't worry - it's quick and painless! Just click below, and once you're logged in we'll bring you right back here and post your question. We'll remember what you've already typed in so you won't have to do it again.
Please see below the most popular frequently asked questions.
Loading article...
Loading faqs...
Please see below the current ongoing issues which are under investigation.
Loading issue...
Loading ongoing issues...
NOTE: If you don't care about my story, jump to the bold text below and ignore the rest.
After using Google Play Music for a year, I started to miss some of Spotify's details.
On Google Music, you can be listening to calm, relaxing music, and get jump scared when the next song starts playing because the volume isn't equal for every song.
I also missed Spotify's humanized shuffle, where the shuffle feels random even though it isn't, or Spotify's artificial inteligence, that always recommended me amazing songs.
A year ago, I made the switch because no matter how many times Chromecast support was requested, Spotify wouldn't listen. That, together with a poor GNU/Linux client, made me dislike Spotify.
A year later, Spotify now has Chromecast support,
with a poor GNU/Linux client.
Because I miss some of Spotify's details and they, finally, listened to the community, it's time to come back, hopefully, to stay.
Now, the subject of this post says "[Release]" because I have a 931 song playlist on Google Music and I'm not transfering it manually, so I made a little script.
Tested on Chrome (02-01-2017).
Github \ (The instructions are in the script).
/* Unportify is a script that exports your Google Play music to text. Copyright (C) 2016 Arnau Villoslada This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Copy of License: https://www.gnu.org/licenses/gpl-3.0.html */ /* HOW TO USE (Chrome): 1. Go to Google Play Music 2. Once loaded, right click anywhere in the page and left click on "Inspect" (or press CTRL + SHIFT + I) 3. Go to the "Console" tab. 4. There's a little dropdown, select "top". 5. Paste this script next to the ">" and press enter. 6. You can now close the console. (Click the X at the right or press CTRL + SHIFT + I). 7. Go to the playlist you want to export. 8. Press 0 to start the export process. If pressing 0 does nothing, reload the page and make sure you you inject the code on "top" (step #4). 9. Follow on-screen instructions. 10. Once it's done, a file containing your playlist will download, paste it here: https://labs.villoslada.me/unportify. NOTE: If the number of catched songs is lower than the number of songs in your playlist, you might have duplicates, if not, try lowering the scroll speed. */ /* Pre-start variables */ unportify_url = 'https://labs.villoslada.me/unportify'; message = {}; message['startup-1'] = 'Unportify v1.4.3 injected, you can now close this window.'; message['startup-2'] = 'Press 0 at any time to start exporting your playlist.'; message['albums'] = 'Would you like to also export the albums? \n(Not needed for Unportify importer)'; message['scroll'] = 'How fast would you like me to scroll? (Leave at default if you\'re not sure).\n\ Lower if it\'s not catching the entire playlist', '100'; message['scroll-error'] = 'Please, only use numbers.\nDefault should work fine on a average speed Internet connection'; message['scroll-startup'] = 'I\'m going to start scrolling, I\'ll warn you when I\'m done.\nPlease, don\'t switch tabs.'; message['open-unportify'] = 'Would you like to import this to Spotify? \n(Opens ' + unportify_url + ')'; console.log(message['startup-1']); alert(message['startup-2']); // Sets the starting variables function startingVariables() { // JSON containing playlist playlist_string = '{"tracks": ['; // Google Music uses a main container to scroll instead of the browser window, get it. main_container = document.querySelector("#mainContainer"); // Ask if the user would like to export albums export_albums = confirm(message['albums']); // This function keeps asking for the scroll speed until a number is given function askAutoScrollSpeed() { auto_scroll_speed = prompt(message['scroll'], '100'); if (isNaN(parseInt(auto_scroll_speed))) { alert(message['scroll-error']); askAutoScrollSpeed(); } } askAutoScrollSpeed(); // Scroll margin. Used to make sure the script detects that the bottom of the page has been reached. scroll_margin = 50; alert(message['scroll-startup']); // Set the scroll speed to the user's desired speed auto_scroll_speed = parseInt(auto_scroll_speed); // Go to the top of the playlist main_container.scrollTop = 0; // Set the starting auto scroll position auto_scroll_pos = main_container.scrollTop; } // Gets all of the loaded songs from the playlist function getSongs() { var i, j, playlist_div = document.querySelectorAll('.song-row'); for (i = 0, j = playlist_div.length; i < j; i++) { var track = playlist_div[i]; var title = encodeURI(track.querySelector('[data-col="title"] span.column-content').textContent); var artist = encodeURI(track.querySelector('[data-col="artist"] span.column-content').textContent); var album = encodeURI(track.querySelector('[data-col="album"] span.column-content').textContent); // Clean possible characters that could mess up the JSON title = title.replace(/"/g, '\\"'); artist = artist.replace(/"/g, '\\"'); album = album.replace(/"/g, '\\"'); // Checks if the album needs to be exported if (export_albums) { var song = ('{"artist": "' + artist + '", "title": "' + title + '", "album": "' + album + '"},'); } else { var song = ('{"artist": "' + artist + '", "title": "' + title + '"},'); } // Only add if the song isn't already added the list if (playlist_string.includes(song) != true) { playlist_string += song; } // Will contain the last processed song last = track; } } // As Trump would say, we will do many many things, and it will be great. function scrollAction() { var last_song_pos = last.offsetTop; var window_scroll_pos = main_container.scrollTop; // Checks if we reached the last loaded song if(window_scroll_pos >= last_song_pos) { getSongs(); } var limit = main_container.scrollHeight - main_container.offsetHeight - scroll_margin; // Checks if we arrived at the bottom of the playlist if (window_scroll_pos >= limit) { // Stops the page scroll clearTimeout(scroll_delay); // Get the playlist name var playlist_title = document.querySelector('h2[slot="title"]').textContent; // Remove theh last , playlist_string = playlist_string.replace(/.$/, ''); // Close JSON. playlist_string += '], "playlist": "' + playlist_title + '", "exported_by": "Unportify"}'; // Convert to human readable JSON playlist_string = JSON.stringify(JSON.parse(playlist_string), null, 4); // Exports the playlist alert('Catched ' + (playlist_string.match(/"artist":/g) || []).length + ' songs.'); var blob = new Blob([playlist_string], {type: 'text/plain;charset=utf-8'}); saveAs(blob, playlist_title + '.txt'); if (confirm(message['open-unportify'])) { window.open(unportify_url, '_blank'); } // Awaits for the user to press the start key again window.onkeypress = function(event){startExport(event)} } } // This funcion makes the page scroll automatically. function pageScroll() { main_container.scrollTop = auto_scroll_pos; scroll_delay = setTimeout(pageScroll,10); scrollAction(); auto_scroll_pos = auto_scroll_pos + auto_scroll_speed; } // Starts everything when the user presses the start key. function startExport(event) { if (event.keyCode == 48) { window.onkeypress = null; startingVariables(); getSongs(); pageScroll(); } } window.onkeypress = function(event){startExport(event)}; /* Everything below is not my code */ // Used to save the playlists in a file. /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ var saveAs=saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,i=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},a=/constructor/i.test(e.HTMLElement),f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},d="application/octet-stream",s=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,s)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(i){u(i)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,s){if(!s){t=p(t)}var v=this,w=t.type,m=w===d,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&a)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;i(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define([],function(){return saveAs})}
I've been having some trouble with the unportify portion. The script is pulling the playlists perfectly, but sometimes unportify stops working with certain playlists. It continually says importing without actually finishing. I broke the original playlist down into segments and it only didn't work for certain segments, even small (~25 songs) segments.
Any ideas?
Attached are the original playlist (which didn't work) and two subdivisions, G did work, H did not work.
reply to Esragoria:
Just updated the export script, try exporting it again with the new version.
There's no need to split the playlist, Unportify does that internally in order to contact Spotify; it wasn't working because of a formatting error.
I hope this works.
Unfortunately I am still having the same problem as Esragoria has. I tried your new script and the Unportify site keeps hanging on the import. The new playlist does get created on Spotify but it never gets populated.
reply to noname580:
Huh, that's weird. Maybe the saveas script saves in different formats. Can I take a look at the text file of the playlist? I'll try chaning the server instead, so it makes sure it's in the right format.
reply to noname580:
Thank you! The files have come in handy; I updated the script again. Also changed the server to adapt to the new format.
Tell me if it works!
reply to noname580:
Alright, that took a while to find but I finally found where the problem was coming from. It wasn't with the code but the database collation, for some reason, it was in swedish instead of utf8. Never experienced that problem before.
Now it should be working just fine, I tried your file and was able to import 900 songs, the ones that were not found are remixes and "feat. ARTIST". I'll have to improve the code on that side, since Spotify's API is not able to find tracks with titles like that.
The importation time for you should be really short now, since Unportify has learned from me when I imported them and should find your tracks really fast.
Thank you for all the feedback!
Arnau.
Everything seems to be working much better.
Interestingly enough, the export with Albums found 6 more songs than without. 911 with albums and 905 without.
Glad I could be of assistance.
Frustrating that neither company allows for exporting and importing. The labeling needs to be more uniform but I am starting to rant now.
Thanks for your script and program.
reply to noname580:
It finds more songs with albums because some are duplicates with different album names.
No problem about the rambling, I agree.
They don't offer this feature because it allows you to switch services really easily, something that the other company would not like at all and generate legal issues, potentially going to court.
TBH, I'm surprised I didn't get any email yet threatening with legal actions against Unportify.
You are a wonderful person, thank you so much for working on this. The imports are working fine now, excluding the remixes and featuring ARTIST type songs.
Thanks.
Esra
The former problem with special Characters (äöü ...) is fixed with the latest release of the script!
Many thanks for this great tool.
Like the person above said, thank you very much for making this. I really appreciate this.
But! (there is always a but) Unportify says that 55 out of 218 songs weren't found after the import finished. However, when I copy/paste the titles into Spotify they're found, although not all of them. (then again, good luck with
High Contrast - Wish You Were Here (S.P.Y. Remix) [feat. Selah Corbin])
Also "ã" and "é" got b0rked.
reply to ouphe:
No problem! I'm glad it was of use.
About the tracks that were not found, it's not Unportify that doesn't find them but Spotify's API. The API seems to be worst than the actual search bar of their application, I'll make some modifications to the code to try and improve it on my side but I'm a little bit limited.
works like a charm! It's catching the vast majority of songs on my playlists. Thanks for creating this and continuing to support it.
Used the latest version on 12-23-16. Works like a charm. Thanks for putting this out there, absolutely fantastic tool.
Hey,
THX great script!
Keep it going
Unfortunately I get this error which I have attached.
reply to scepticore:
When you paste the code, on Chrome/Chromium, make sure you've selected "top" on the dropdown:
Hope this helps.
Hey there you, Yeah, you! 😁 Welcome - we're glad you joined the Spotify Community! While you here, let's have a fun game and get…