Archive for March, 2015

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!