Converting YouTube Playlists to Spotify using JavaScript

YouTube is a great platform for music. It has a wealth of content, including official tracks, remixes and versions of songs. It also has lots of unofficial remixes, mashups, live, cover and original songs which you can't find on other music platforms such as Spotify.



Updated 28/10/15: support for new YouTube Data API with new format

As a result, many people (including myself) use YouTube for browsing and creating music playlists. This is great but creates problems when you want to play the songs on another device or at a party. YouTube has lots of adverts which can also disrupt the playlist.

There are many sites which claim to convert your YouTube playlists to Spotify, but most error or fail at some stage. So I thought, why not make my own using JavaScript. As it turns out it's extremely easy!

Firstly we need some html on the page to allow us to enter a playlist ID, run the search and then show the matches:

<input type="text" id="id" value="PL07D6B14E58F50900" />
<input type="submit" id="submit" value="Load" />

<h1>Failed</h1>
<div id="failed"></div>

<h1>Success</h1>
<div id="success"></div>

<h1>Matches</h1>
<div id="content"></div>

For the first part of our javascript we will grab a reference to those html elements and create the empty object ready for our data:

var start = 1,
    index = 0,
    matches = [],
    pageToken = '',
    success = document.getElementById('success'),
    failed = document.getElementById('failed'),
    content = document.getElementById('content');

The next part is a helper load function to handle the ajax requests easily (Modern browsers only). If you prefer you can leave this out and use a library such as jquery instead:

function load(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                callback(JSON.parse(xhr.responseText));
            } else {
                callback([{}]);
            }
        }
    };
    xhr.send();
}

Next we have a load page function which loads the YouTube Playlist API, using the ID and a start page number:

function loadPage(id) {
    if (!id) {
        id = document.getElementById('id').value;
    }

    load('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&key=AIzaSyBxGbqNZL1EXK7aaZWGC4pohdsMcYliy_s&playlistId=' + id + '&pageToken=' + pageToken + '&max-results=50', function (e) {
        console.log('loadPage', e);
        if (e.items) {
            searchSpotify(e.items);
        }
        if (e.nextPageToken) {
            pageToken = e.nextPageToken;
        }
    });
}

If data is found it runs the next function which strips some characters from the video title. This is a little bit messy but is a quick fix to get better matches on Spotify. Afterwards it searches the Spotify API using the video title and then puts it into the success or failed lists:

function searchSpotify(items) {
    var name = items[index].snippet.title || [];
    name = name.match(/[\w']+/g)
        .join(' ')
        .replace(/official/ig, '')
        .replace(/featuring/ig, '')
        .replace(/feat/ig, '')
        .replace(/video/ig, '')
        .replace(/1080p/ig, '')
        .replace(/music/ig, '');

    load('http://ws.spotify.com/search/1/track.json?q=' + encodeURIComponent(name), function (e) {
        if (e.tracks && e.tracks[0]) {
            console.log('success', name, e);
            // success
            matches.push(e.tracks[0]);
            success.innerHTML += name + '
';
            content.innerHTML += e.tracks[0].href + '
';
        } else {
            console.log('fail', name, e);
            // fail
            failed.innerHTML += name + '
';
        }

        if (index < items.length - 1) {
            index += 1;
            searchSpotify(items);
        } else {
            console.log(matches);
            start += 50;
            index = 0;
            loadPage();
        }
    });
}

The final function is to get the submit button to trigger the loading function. In this it also resets the page number and the matched results

document.getElementById('submit').addEventListener('click', function () {
    index = 0;
    matches = [];
    loadPage();
});

Needs a bit of tidying up but you get the idea!



After clicking load, you should see the results load into the success and failed lists. The third list contains matches. Just copy the list of spotify id urls and paste into a new Spotify playlist:

spotify:track:7ef9bjBe2hS8D7rWfrQtlQ
spotify:track:1LiM9ZTRa2UiUwbn4pFSxI
spotify:track:4qGZllhHMvoUKzYieScTvv
spotify:track:1BaKUUtrZpuTbQuZLPckuT
spotify:track:4cV8mxbufbv0coupgZZDT9

You can view a working version here: