Golf Me a Random Dubstep of the Day List Aside of nursing my child, Vitsy, and dabbling in the art of code golf, I also am an avid dubstep fan, listening to all the new dubstep that Monstercat puts out as regularly as I can. I also share a random dubstep of the day, though not regularly, in the Nineteenth Byte. This last bit is what this challenge relates to; so, without further ado, let me get to what you actually need to think about:

The Challenge

You must generate a randomly sorted list of songs from this playlist in the following format:

&lt;Title> - &lt;Artist>: &lt;link to the video>

Rules


The output list must update with the playlist provided, or every byte used counts as 2 (your score would be double your byte count).
The output list must have no repeats.
The output list must be given in the specified format.
The output list must have all of the videos listed in the playlist provided.
You may not use builtins for array shuffling (such as Collections.shuffle(List&lt;?&gt; x) from Java)
You may not use the YouTube builtin shuffle mechanism (as this is not random).
There are no limits on runtime.


Example Output

Division - Ephixa: https://www.youtube.com/watch?v=M1mPFWhgYUM&list=PLF5C76212C58C464A&index=95
Wanna Know You (ft. Holly Drummond) - Direct: https://www.youtube.com/watch?v=6QWQfzYMJTs&list=PLF5C76212C58C464A&index=24
Edge of the World (feat. Becko) - Razihel & Xilent: https://www.youtube.com/watch?v=P0dQ55ZgNkw&index=4&list=PLF5C76212C58C464A
... until the final video ...
Way Too Deep - Grabbitz: https://www.youtube.com/watch?v=4T28WgVqdrA&index=8&list=PLF5C76212C58C464A

It may be worth perusing the YouTube API, but parsing the page with the playlist on it might save you some time.
JavaScript, 532 536 538 582 bytes

Thanks to @ӍѲꝆΛҐӍΛПҒЦꝆ and @Quill for a whole bunch of bytes.

I did do a couple of things here which may not be 100% to the spec - If they aren't admissible please tell me and I'll fix them:


I shortened the YouTube URL
The shuffle is VERY weak, and is not considered in any way close to
random.
There's a bit of whitespace due to the join.




I'd like to start by saying, to any JavaScript developers out there: I'm so sorry.

New version alternates captures to reduce on regex byte cost and strips some URL length, but sacrifices on alerts. Now instead of 3, you get like 20. Unfortunately the https on the URL's seem to be required or the page won't load, though that may be my setup :/.

This could possibly be improved with proper XML parsing and loops instead of weird recursion things with calls to other functions. I had fun taking advantage of the fact that XMLHttpRequest causes synchronous execution.

d="https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&amp;playlistId=PLF5C76212C58C464A&amp;key={REALLY SUPER LONG GOOGLE API KEY HERE}",h=[];o=l=&gt;{x=new XMLHttpRequest,x.open("GET",l,!1),x.send(0),j=x.responseText;y=`nextPageToken": "`;e(j)
j.includes(y)&amp;&amp;(q=j.split(y)[1].split('"')[0],o(d+"&amp;pageToken="+q));h.sort(b=&gt;.5-Math.random());alert(h.join `
`)}
e=v=&gt;{for(r=/(title": "(.*)\[)|(oId": "(.*)")/g;null!==(m=r.exec(v));)a=m[2]+": https://youtu.be/"+r.exec(v)[4],z="] - ",a.includes(z)&amp;&amp;(a=a.split(z)[1]),h.push(a)}
o(d)


Replace the {REALLY SUPER LONG GOOGLE API KEY HERE} with your 39 character long YouTube API key.

Ungolfed:

//Define base URL, sacrificing speed and pages for bytes
d = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&amp;playlistId=PLF5C76212C58C464A&amp;key={REALLY SUPER LONG GOOGLE API KEY HERE}";
h = [];
o = l =&gt; {
    //Grab API data
    x = new XMLHttpRequest();
    x.open("GET", l, false);
    x.send(0);
    j = x.responseText;
    //Set up a split since we use it twice
    y = `nextPageToken": "`;
    //At this point, jump off to the other function to deal with the output
    e(j);
    //If there are multiple pages of results, as we only get a couple from each API call to save bytes with URL's
    if (j.includes(y)) {
        //Get the ID for the next page
        q = j.split(y)[1].split("\"")[0];
        //Call again with an added parameter
        o(d + "&amp;pageToken=" + q)
    }
    //Taking advantage of XMLHttpRequest forcing this as synchronous, so all the above happens first
    //Bad shuffle
    h.sort(b =&gt; .5 - Math.random())
    alert(h.join `
        `);
}
e = v =&gt; {
    //Regex for titles/ID's - Grabbitz doesn't fit the "[Genre] - Song - Artist" mould so we need a slightly longer regex
    r = /(title": "(.*)\[)|(oId": "(.*)")/g;
    //Since we know there's one title to one video, we can run them both at the same time
    while ((m = r.exec(v)) !== null) {
        //Build the string
        a = m[2] + ": https://youtu.be/" + r.exec(v)[4];
        z = "] - ";
        //That Grabbitz edge case ruining my day again, I'm glad it's a good track...
        if (a.includes(z)) {
            a = a.split(z)[1];
        }
        h.push(a);
    }
}
o(d)