Archive for the ‘ Music ’ Category

Let’s get fucked up and play records

DJ2009

It’s ok to laugh at that picture. I had to go way back to spring of 2009 to dig it up. In a way, it’s the inspiration for my latest series, “State Dependent Learning.” See back when I first learned to DJ, I was always annihilated. My house has always been the go-to afterparty house because I have exactly zero qualms about paying noise complaint fees and fielding calls from angry landlords to… my voicemail. So whenever I’d come home from the bars, it was usually with the party crew and the first order of business was always to get some music going. At that time I wasn’t really too concerned with mastering my craft or even practicing for that matter. On the few occasions that I did try playing sober, I sounded like shit. This confused me because I FUCKING ROCKED IT WHENEVER I WAS WASTED! The obvious conclusion is that I was suffering from State Dependent Learning. Per Wikipedia,

State-dependent memory, or state-dependent learning is the phenomenon through which memory retrieval is most efficient when an individual is in the same state of consciousness as they were when the memory was formed. The term is often used to describe memory retrieval while in states of consciousness produced by psychoactive drugs – most commonly, alcohol, but has implications for mood or non-substance induced states of consciousness as well.

For more years than I care to admit, I would just simply refuse to play sober. I’d get a few cocktails in me and the jams would just flow. In addition to my ongoing “Bowling,” series that you’ve gotten to hear for the past 2 weeks; I’ll be periodically be making sets where basically all I’m doing is letting the liquor do the thinking and recording mixes. For this first one, I was drinking some fancy bourbon that I took from my roommate’s liquor cabinet (Sorry not sorry Dan). Towards the end of the set I got a little too drunk so I pulled my signature move of drinking Coors Light to sober up. Without any further introduction, let’s get fucked up… play records!

State Dependent Learning – Vol 1 (3/11/2015)

Tracklist

  • 1 – Ninetoes – Finder
  • 2 – Monkey Safari – Watching the Stars
  • 3 – Joyce Muniz – Sleepless
  • 4 – Rey & Klajek – Animal vs Beast
  • 5 – Doctor Dru – 2 Know U
  • 6 – Adana Twins (feat. Digitaria) – Reaction
  • 7 – Go Freek – The Way You Dance
  • 8 – Alexis Raphael – Assault Weapon (German Brigante Remix)
  • 9 – Wonkers – Firecity
  • 10 – Antonio Giacca – Alright
  • 11 – Turntablerocker – Grow up
  • 12 – Ardalan – Catchup
  • 13 – The Holy Mash – Gifted
  • 14 – Dustin Nantais – Arm Bar

One more thing…

Before I move onto talking about the music hosting awesomeness that I can hardly contain my excitement over, I want to give a shoutout to French producer The Holy Mash for giving me permission to include their track Gifted in this set. It’s definitely one of my new favorites and I’m looking forward to see what else comes from them!

Now for that techie goodness that you all really came here for…

Well I’ve got to say, this music service has really taken on a life of its own. I did get a few feature requests so I went ahead and added the most common one, download links. The headers of the sets should now be just that! There really isn’t anything too technically special about what I did. Just updated setplayer.js to insert an A tag into the header element with the set’s file location. Now whenever you visit http://imjustinbraun.com/djsets/index.php?Request=DisplaySets, you can download whatever there. As always, you can see the final working product on my jsfiddle. I did run into one little pitfall on line 92 of setplayer.js – basically I’m loading in the first track by searching for the first A element in the output. Since the download link is now the first A tag, I modified the line to mean the first A element immediately preceded by an LI element. Simple enough.

Last week I promised that I was going to make a RESTFul back end for this whole thing, improve the player, and create an uploading service. That turned out to be a bit of a tall order considering that I have a fulltime job and I had a killer hangover the other day from recording the set that you’re currently enjoying. Also, this whole project has required a ton of architecting, planning, and well, thinking ahead. So instead of posting any code, I’m going to talk about the architecture I ultimately arrived at and why. Next week I’ll start sharing more code with you. In terms of initial requirements, I wanted whatever I designed to have the following properties:

  • Loose Coupling – I don’t want one API change to fuck up all of the clients and I have to spend a week listening to pissed off users that refuse to upgrade
  • Scalable - If by some miracle I’ve got 100K users banging down my door tomorrow wanting to listen to my drunken recordings, fuck yeah!
  • Platform Independent – Because nothing short of my superbowl commercial would serve my vanity better than having an imjustinbraun iphone, iwatch, ipad, and android apps
  • Orthogonal - At some point I’m going to want to open this thing up to other DJ’s, Producers, and Record Labels (their lawyers, however, can fuck off). I’ll need to be able to easily accommodate feature requests without breaking everything.
  • Easy - Ok so maybe I’m a genius and could write the thing in machine language or lolcode (yes that’s an actual thing), but if I ever bring on other developers to help me with this little project, I don’t want to use some obscure tech that only I can figure out.
  • The Architecture

    With those requirements in mind, I set out to fulfill them using the tools that I readily have available in my shed. I decided to use Amazon AWS as my hosting provider. I’m using what initially passes for a traditional LAMP stack (A few years ago I wrote a step-by-step guide for how to set one of these up here), though I have a few tricks up my sleeve this time. One thing that makes Amazon so powerful as a webhost is that they really have thought of everything. Between Elastic Load Balancing, Autoscaling groups, and Cloudfront – I can offer SERIOUS amounts of scalability with minute-by-minute sizing so that I’m never paying for what I’m not using.

    Regarding the API, I want to make sure that whatever clients interact with the back end aren’t coupled to any particular technology stack. The world seems to be in love with RESTFul API’s these days and I can see why. They’re simple, scalable, platform agnostic, and is incredibly easy to secure using HTTPS. Further, because it’s centered around resources rather than procedures, changes to the API seem like they’ll break a bit more gracefully (I’ve yet to test this theory, though I have little doubt that it will be tested at some point in this little adventure). I did give websockets a serious look, but I ultimately concluded that unless I decided to write my own streaming format, they’d be overcomplicated overkill.

    Writing a REST API from scratch in php is a serious undertaking and an entirely unnecessary one. There are TONS of frameworks out there that will do the heavy lifting for you. I ultimately selected RDev for a number of reasons. For starters, it’s a framework that I’m very comfortable with. I’ve deployed RDEV in major financial institutions, so I’m fairly familiar with how to make it work securely and how to make it scale. It doesn’t hurt that I’m personal friends with the guy who wrote it, so I can always bug him with questions and feature requests. But I think the main reason I continually choose RDEV is because it’s fucking awesome. I won’t go into the laundry list of features; Dave’s website can do that for you, but I will say that he is constantly adding little bits and pieces that make RDEV easy to use. It’s rock solid – He’s got some ridiculous amount of unit tests that he writes before he even builds features (a habit I need to start getting into myself).

    Looking Forward

    I hope you’ve enjoyed this musically charged rant! Next week the gameplan is to teach you guys how to get RDEV up and running and if there’s time, maybe I’ll even have a better player for you to listen to my mixes with. In the meantime, if you would like your music in my sets, feel free to email your tracks to imjustinbraun@gmail.com. You can also feel free to contact me with feature requests, comments, ideas, or questions. Till next week!!

    This one is for My Hurricane Bitches

    I couldn’t help myself. I SHOULD be making sets for all of my yoga instructors like I promised them I would, but I’m having so much fun doing these Bowling sets that I just HAD to post another one. I’ll never tell you who it’s for, but the name is a reference to a certain kind of woman. We all know the type; they come into your life wet and wild, then they leave with your lawn furniture. You know, like Hurricanes!

    Update: Do not try and click this player from the main page. Apparently it fights with the other players on this page. You need to go here instead

    Bowling – Hurricane (2/14/2015)

    Tracklist

    • 1 – Lana Del Rey – Brookly Baby (Konstantin Sibold Remix)
    • 2 – Oliver Heldens & Mr. Belt & Wezol – Pikachu
    • 3 – Hardsoul (feat. Hero) – Human
    • 4 – Claus Casper & Jean Philips – Anytime Anywhere (Dub Mix)
    • 5 – Rampue – Don’t Wanna Leave You (Nicone & Sascha Braemer Remix)
    • 6 – Fashion Lioness – If I leave You (The Mankeys Remix)
    • 7 – Adana Twins – Everyday (Amine Edge & Dance Remix)
    • 8 – Mineo – Get Out Fight
    • 9 – Alexis Raphael – Assault Weapon (German Brigante Remix)
    • 10 – Redondo – Waist Shake (Club Mix)
    • 11 – Rey & Klajek – Animal Vs Beast (Adritique Remix)
    • 12 – Della Zouch – Rebel (Raxon Mix)
    • 13 – Harada – Paws
    • 14 – Booka Shade (feat.Fritz Kalkbrenner) – Crossing Borders (Pleasurekraft Remix)
    • 15 – Jade Blue & Frequency – Lately (Vox Mix)
    • 16 – Lucas & Steve & Nothing But Funk – Clueless

    Now let’s indulge my ADD

    I have to say that I had a lot of fun writing my last post. The format of it was perfect if I do say so myself; let you guys listen to some good music while I go on about my antics (and hopefully learn a thing or two about writing code). Seems like having me around in real life, only less annoying because you can listen to music and tune my (written) voice out.

    I’ve been working like a madman on a number of projects in my day job so I haven’t had a ton of time, but I have been playing with my little music hosting service a little bit. I’ve been teaching myself java and re-learning php, so I figured that I might as well throw javascript into the mix before I become proficient at anything and start go get stuck in my ways.

    I hope you like javascript

    I figured that as I continue to add to the list of sets that I post, you’ll probably want to go back and see the whole list without having to scroll through each wordpress post that I make. So I went ahead and wrote this little javascript front end that implements the PHP back end that I shared in my last post. You can see the finished product here

    I know that a lot of this is sloppy with hard links all over the place and a complete disregard for any type of pattern or style, but at this point I’m just hacking things together to get them to work. I have literally ZERO javascript experience prior to writing this so I’m kind of learning as I go. I built all of the javascript bits in this jsfiddle and I wrote all of the php pieces in PHPStorm.

    I started by adding some methods to index.php that retrieves JSON arrays of all of my set data, and because I’m a bit more comfortable with PHP, I’m also relying on the server to organize the series data for me as well.

    index.php

    elseif ($request === "GetSets")
    {
    	print json_encode($sets->GetSets());
    }
    elseif ($request === "DisplaySets")
    {
    	print '
    			<link rel="stylesheet" href="//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
    			<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
    			<script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
    			<script src="'.$rootPath.'audiojs/audio.min.js"></script>
    			<script src="'.$rootPath.'js/setplayer.js"></script>
    			<link rel="stylesheet" href="'.$rootPath.'styles/playlist.css">
    			<link rel="stylesheet" href="/resources/demos/style.css">
    		<div id="wrapper">
    		 <h1 id="setHeader">Set Series — Set Name <em>(Release Date)</em></h1>
    
    		<audio preload="auto"></audio>
    		<div id="accordion"></div>
    	</div>
    	<div id="shortcuts">
    		<div>
    			 <h1>Keyboard shortcuts:</h1>
    
    			<p><em>&rarr;</em> Next track</p>
    			<p><em>&larr;</em> Previous track</p>
    			<p><em>Space</em> Play/pause</p>
    		</div>
    	</div>';
    	}
    elseif ($request === "GetSeriesNames")
    {
    	print json_encode($sets->GetSeriesNames());
    }
    

    Then I built the front end. Basically all I’m doing is using AJAX calls to my php script for set and tracklist information, then displaying it in the proper locations. If you find any bugs please let me know!!

    setplayer.js

    var seriesData = [];
    var setData = [];
    var baseURL = "http://imjustinbraun.com/djsets/";
    var audio = [];
    $.ajax({
        url: "http://imjustinbraun.com/djsets/index.php?Request=GetSeriesNames",
        dataType: 'application/json',
        complete: function (seriesResponse) {
            seriesNamesRetrieved(seriesResponse)
        }
    });
    
    function seriesNamesRetrieved(seriesResponse) {
        seriesData = JSON.parse(seriesResponse.responseText);
        $.ajax({
            url: "http://imjustinbraun.com/djsets/index.php?Request=GetSets",
            dataType: 'application/json',
            complete: function (data) {
                initialSetup(data)
            }
        });
    }
    
    function initialSetup(data) {
        var selectedSeriesIndex = 0;
        var selectedSetIndex = 0;
        setData = JSON.parse(data.responseText);
    
        var setCount = setData.length;
        var series = seriesData;
        var seriesCount = series.length;
    
        if (setCount == 0 || seriesCount == 0) return;
    
        for (var s = 0; s < seriesCount; s++) {
            var seriesName = series[s];
            var element = document.createElement("h3");
            element.setAttribute("id", "seriesTitle" + s);
            element.appendChild(document.createTextNode(seriesName));
            document.getElementById("accordion").appendChild(element);
    
            var setElement = document.createElement("div");
            setElement.setAttribute("id", "SetListDiv" + s);
            document.getElementById("seriesTitle" + s).appendChild(setElement);
    
            var setListElement = document.createElement("ol");
            setListElement.setAttribute("id", "SetList" + s);
            document.getElementById("SetListDiv" + s).appendChild(setListElement);
    
            for (var i = 0; i < setCount; i++) {
                var setSeries = setData[i].Series;
                if (setSeries == seriesName) {
                    var setTitle = setData[i].Name;
                    var setDate = setData[i].Date;
                    var setFile = setData[i].File;
                    var setTracklist = setData[i].Tracklist;
    
                    var setLineItem = document.createElement("li");
                    //setLineItem.setAttribute("id", "Set"+i);
                    setLineItem.innerHTML = '<a href="#" id="' + i + '" data-src="' + baseURL + setFile + '">' + setTitle + ' - <em>('+ setDate +')</em></a>';
                    document.getElementById("SetList" + s).appendChild(setLineItem);
    
                }
            }
        }
        document.getElementById("setHeader").innerHTML = setData[0].Series + " - " + setData[0].Name + " <em>(" + setData[0].Date + ")</em>";
        var trackListElement = document.createElement("h3");
        trackListElement.setAttribute("id", "tracklistHeader");
        trackListElement.appendChild(document.createTextNode("Tracklist"));
        document.getElementById("accordion").appendChild(trackListElement);
        var trackListDiv = document.createElement("div");
        trackListDiv.setAttribute("id", "tracklistDiv");
        document.getElementById("accordion").appendChild(trackListDiv);
        var trackListList = document.createElement("ol");
        trackListList.setAttribute("id", "tracklist");
        document.getElementById("accordion").appendChild(trackListList);    
        
        setTrackList(0);
        // Setup the player to autoplay the next track
        var a = audiojs.createAll({
            trackEnded: function () {
                var next = $('li.playing').next();
                if (!next.length) next = $('li').first();
                next.addClass('playing').siblings().removeClass('playing');
                audio.load($('a', next).attr('data-src'));
                audio.play();
            }
        });    
        
        // Load in the first track
        audio = a[0];
        first = $('a').attr('data-src');
        $('li').first().addClass('playing');
        audio.load(first);
    
        // Load in a track on click
        $('li').click(function (e) {        
        e.preventDefault();
        $('li.playing').removeClass('playing');
        $(this).addClass('playing').siblings().removeClass('playing');
        audio.load($('a', this).attr('data-src'));
        var setID = $('a', this).attr('id');
        document.getElementById("setHeader").innerHTML = setData[setID].Series + " - " + setData[setID].Name + " <em>(" + setData[setID].Date + ")</em>";
            setTrackList(setID);
        audio.play();
        });
        // Keyboard shortcuts
        $(document).keydown(function (e) {
            var unicode = e.charCode ? e.charCode : e.keyCode;
            // right arrow
            if (unicode == 39) {
                var next = $('li.playing').next();
                if (!next.length) next = $('ol li').first();
                next.click();
                // back arrow
            } else if (unicode == 37) {
                var prev = $('li.playing').prev();
                if (!prev.length) prev = $('ol li').last();
                prev.click();
                // spacebar
            } else if (unicode == 32) {
                audio.playPause();
            }
        })
    }
    
    function setTrackList(setID)
    {
        document.getElementById("tracklist").innerHTML = "";
        var tracklist = setData[setID].Tracklist;
        for (property in tracklist) { 
            var trackLineItem = document.createElement("li");
            trackLineItem.innerHTML = '<a href="#">' + tracklist[property] + '</a>';
            document.getElementById("tracklist").appendChild(trackLineItem);
        }
    }
    
    
    $(function () {
        $("#accordion").accordion({
            collapsible: true
        });
    });

    So from here I think I’m going to clean up the code itself. I started thinking that if I make the back end RESTful in nature, build a few simple javascript/html5 players, and create an uploading service, I’ll have a pretty convenient little way to upload my sets and I’ll have the future flexibility to go and create clients beyond simple web interfaces. Who knows, maybe I’ll make an imjustinbraun app someday!

    I’m a Cool Fucking Guy

    DJ LogoThis article will be an ADD kid’s dream come true. In it, I will drop the first installment of my new DJ series, touch briefly on copyright law as it applies to DJ mixes, and finally, give you a step-by-step guide to creating your own music hosting service.

    You’ll be here for awhile, so let’s start by clicking that play button below this paragraph. This is the first of many DJ sets in my new series entitled “Bowling.” The inspiration for this series has been you! My friends, frienemies, acquaintences, family, and people I don’t even like! Each week that I do a bowling set, I am picking a person who has at one point or another been an important part of my life and I’m making a set for them. I will NEVER tell ANYONE whose set is for who, or if a set is even for you. If you try and guess, I will neither confirm nor deny anything! With that said, I leave clues all over the place so if the set is for you, you’ll know. If you have to ask, I’m sorry but probably it isn’t yours. Who do you think it’s for? Ok well let’s go BOWLING!!

    Bowling – I’m a Cool Fucking Guy (2/27/2015)

    Tracklist

    • 1 – Celsius – Incoming
    • 2 – Martin Ikin – Rhythm
    • 3 – Oliver – MYB (Tchami Rmx)
    • 4 – Rob Mirage – Culture 1010 (Hector Couto Remix)
    • 5 – Ludacris – Stand Up (LeMarquis Remix)
    • 6 – Sugar Hill & Wasabi – It’s on You (Purple Disco Machine Remix)
    • 7 – Disciples – They Don’t Know
    • 8 – Habischman – Like This
    • 9 – Me & My Toothbrush – Something (Croatia Squad Remix)
    • 10 – Vanguard – Mount Helicon
    • 11 – Laidback Luke – Bae (feat. Gina Turner)
    • 12 – Anna Lunoe – Heartbreak In Motion (feat. Jesse Boykins III)
    • 13 – Kokiri – Flux
    • 14 – Do Santos & Simone Vitullo – My Bassline Friend
    • 15 – Beam – Controllers
    • 16 – Fabrico Pecanha – Teaser(Phonique Remix)

    Soundcloud Sucks! And so does Copyright law if you are a DJ

    So why did you have to click on the player here rather than just go to my SoundCloud page like a normal person? I’m glad you asked that. In what scientists around the globe are calling “fucking lame,” Soundcloud has (somewhat) recently declared the hobbyist and beginner DJ enemy number 1. To make a long story short, I tried uploading my latest set to Soundcloud last week, only to have it taken down due to an automated Copyright infringement claim. Apparently SoundCloud will now scan through your sets, looking for any tracks that might be copyrighted, and it will bitch slap your posting if its algorithms determine that you’re infringing! After poking around a bit, I stumbled upon numerous accounts of other people finding the same thing. Fuckers.

    Everyone knows that broadcasting copyrighted materials is infringement. But where is the line between infringement and fair use? If you play a song at your home and some friends who hadn’t purchased the music happen to be in the room, are you infringing? Can the RIAA come into my home and turn off my stereo? What about if you are playing at a club where people paid money at the door to get in? Does that constitute infringement? What if it’s at a concert with thousands of people, or if you publish a mix album?

    As it turns out, the distinction is not clearly defined. I naively thought that as long as I credit the original artist and don’t charge for the set, it was fair use. WRONG!! Per Wikipiedia, Frank Creighton, a director of anti-copyright infringement efforts for the Recording Industry Association of America, was quoted in New York Times as saying that “money did not have to be involved for copying to be illegal.” There’s a lot of nuance here and I’m not a lawyer, but for practical purposes, you pretty much have to have obtained permission from the original artist to play anything.

    One would think that an enthusiast who just wants to share good music with his friends should be free to do so; and while the internet makes this easier from a technological perspective, it apparently makes it more difficult from a legal one. In order to properly publish my mixes, I need to obtain written permission from every single artist in my set, fill out a form at copyright.gov, pay $40, and send in 2 hard copies of my set to the U.S. Copyright Office. After I do that, SoundCloud will let me dispute their bitch slap and my mix will be published…. whenever SoundCloud gets around to publishing it?

    Ef that noise! I like to pay what I call “pragmatic attention” to the rules. I’ll just boycott Soundcloud, fly under the radar, and be diligent about responding to DMCA takedown requests. But soundcloud is so effing easy and everyone has it! How do I distribute my music to my friends who want to listen on their devices? Now we get to the how-to portion of this article!

    A start at creating your own streaming music service

    HTML5 has been out for awhile now, though I can’t say that I’ve ever taken the time to learn anything about it until just now. Apparently though, HTML5 allows for <audio> tags that should be supported by any modern browser. Mobile included! I tested the player embedded in this article on both my iPhone 6, and my android burner phone (It’s not what you think I swear! I just get drunk and lose phones often enough to justify it) and it worked flawlessly on both! Yay now everyone can enjoy my music from their devices.

    That isn’t quite cool enough so I went and found this fancy little javascript player that makes the default HTML5 player look nice. Next I wrote a little script that makes the player look nice with a collapsible tracklist and automagically plays the set I want it to play. It pulls its tracklist and set information from an array that I hardcode. I intentionally left this thing expandable so that someday I can add a tracklist upload script and possibly serialize/deserialize the set metadata from a database or something.

    My code here:

    index.php

    <!--?php require_once("sets.php"); $rootPath = "http://imjustinbraun.com/djsets/"; $request = $_GET["Request"]; $setIndex = $_GET["SetIndex"]; $sets = new \JB\Music\Sets(); if ($request === "DisplaySet" && $setIndex !== "") { 	$set = $sets--->GetSet($setIndex);
    $seriesName = $set["Series"];
    $setName = $set["Name"];
    $publishDate = $set["Date"];
    $trackList = $set["Tracklist"];
    $filePath = $set["File"];
    
    print '
    	<link href="//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css" rel="stylesheet" /><script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.js"></script><script type="text/javascript" src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
    <script type="text/javascript" src="'.$rootPath.'audiojs/audio.min.js"></script>	<link href="/resources/demos/style.css" rel="stylesheet" /><script type="text/javascript">// <![CDATA[
    			$(function()
    			{
    				$( "#accordion" ).accordion({
    					collapsible: true
    				});
    			});
    
    // ]]></script>
    <script type="text/javascript">// <![CDATA[
    			audiojs.events.ready(function()
    				{
    					var as = audiojs.createAll();
    				});
    
    // ]]></script>
    <h1>'.$seriesName.' - '.$setName.' ('.$publishDate.')</h1>
    <audio width="300" height="32" preload="auto" src="'.$rootPath.$filePath.'">
    
    </audio>
    <div id="accordion">
    <h3>Tracklist</h3>
    <ul>
    <ul>';</ul>
    </ul>
    $i=1;
    foreach($trackList as $trackName)
    {
    print "
    <ul>
    	<li>$i - $trackName</li>
    </ul>
    &nbsp;
    
    ";
    $i++;
    }
    
    print '
    
    </div>
    ';
    }
    

    sets.php

    <!--?php namespace JB\Music; class Sets { 	private static $sets = array( 		"0" =-->
    [
    "Series" =&gt; "Bowling",
    "Name" =&gt; "I'm a Cool Fucking Guy",
    "Date" =&gt; "2/27/2015",
    "File" =&gt; "I'm a cool fucking guy.mp3",
    "Tracklist" =&gt;
    [
    "1" =&gt; "Celsius - Incoming",
    "2" =&gt; "Martin Ikin - Rhythm",
    "3" =&gt; "Oliver - MYB (Tchami Rmx)",
    "4" =&gt; "Rob Mirage - Culture 1010 (Hector Couto Remix)",
    "5" =&gt; "Ludacris - Stand Up (LeMarquis Remix)",
    "6" =&gt; "Sugar Hill &amp; Wasabi - It's on You (Purple Disco Machine Remix)",
    "7" =&gt; "Disciples - They Don't Know",
    "8" =&gt; "Habischman - Like This",
    "9" =&gt; "Me &amp; My Toothbrush - Something (Croatia Squad Remix)",
    "10" =&gt;"Vanguard - Mount Helicon",
    "11" =&gt;"Laidback Luke - Bae (feat. Gina Turner)",
    "12" =&gt; "Anna Lunoe - Heartbreak In Motion (feat. Jesse Boykins III)",
    "13" =&gt; "Kokiri - Flux",
    "14" =&gt; "Do Santos &amp; Simone Vitullo - My Bassline Friend",
    "15" =&gt; "Beam - Controllers",
    "16" =&gt; "Fabrico Pecanha - Teaser(Phonique Remix)"
    ]
    ]
    );
    
    public function GetSets()
    {
    return self::$sets;
    }
    
    public function GetSet($index)
    {
    return self::$sets[$index];
    }
    }
    

    Imjustinbraun.com is a wordpress site, so I need the ability to embed the output of http://imjustinbraun.com/djsets/index.php into the post. For that, I use the Insert PHP wordpress plugin, then in the post I add an insert_php shortcode with the url of the set I want. To make the tracklist fancy and collapsible, I used jquery accordion.

    So that’s it! I hope you like my music. In future articles I may post a bit more about any backend stuff that I add. Have a great weekend!!