Building a music downloading website

28 December 2016

It was Christmas Eve and my family was visiting me in Groningen. After a few hours of chit-chat I mentioned that downloading music is still something pretty "hard" to do. And if you think about it, it really is.

The problem

Say you want to download Taylor Swift's new hit song "Love Story". Right now there are only about two ways I can think off that are most common for someone not very tech savy to download a song they like.

  1. Google the song name and append mp3 download to it, click through a bunch of pay per click links and then finally get the download.
  2. Search the song on Youtube, copy the URL, and paste it into a Youtube to MP3 video converter website.

The problem isn't that these things don't work. Its just that they don't work great for non tech savy people. And the process isn't smooth. If your grandpa wanted to download a copy of "Love Story" do you think you can walk him through it without pulling your hairs out? Maybe. Maybe not.

The solution

So we've identified the problem. We have to make the experience more fluid. So what I've done is, I've borrowed from the simplicity giant Google and used tools and services that already exist to hack together a nifty piece of software that will hopefully make some people's lives easier. Here's what I did; I built a website that takes your search term, Searches youtube for videos matching that search term, and returns a list of those videos to you. You then have the option to press a downlaod button and it will go ahead and download that video for you in MP3 format.

Nothing new or fancy at all, in fact, I've actually built something like this before 3 years ago. execept, back then, it didn't have the search bar and was just a simple youtube to mp3 converter. But by adding that searchbar, you make the UX that much more simpler. Its no longer a tool that you use to convert videos to songs. Its now a tool to download music. Providing thats what you search for ofcourse.

The project is temporarily hosted on mogatu.tk. This is a temporary domain I use projects that don't have a home yet. The source code is also available on Github here


Writing a music player in Electron

11 December 2016

This week I wrote a minimal music player using electron. It was fun to build and I refreshed my knowledge on electron's dialog windows and the seemingly neverending urge to inlude JS packages into projects instead of doing it with "raw" JavaScript. This music player is built with zero packages. Making it slightly faster.

Designing the thing

I already had a clear idea of what I wanted it to look like, all I had to do now was write it in HTML and CSS. I know I wanted it to be small like some kind of module or something. And I wanted it to be dark in color. And have a track lists that is scrollable. Checkout the progress below.

Selecting files

Initally I wanted to turn this into an application you launch from the terminal and specify the source directory for the music as an argument to the script but I couldn't quite figure out how to to do that with Electron. So instead on launch of the application it prompts you to select the music you want to hear and then loads them in. This part was ridiculously simple to write and pretty much the whole thing was easy to write but here's what the code looks like to loop through and initialize tracks. could use some cleaning up I might add.

function loadMusic(){
    for (var i = 0; i < music.length; i++) {
        fileName = music[i];
        loadedMusic.push(new Audio(fileName));
    }
}

function openFile() {
    dialog.showOpenDialog({properties: ['openFile', 'multiSelections']}, function(fileNames) {
        count = 0;
        fileNames.forEach(function(file){
            tracks.innerHTML = tracks.innerHTML + '<li data-index="'+count+'" onclick="playTrack('+count+')">'+file+'</li>';
            music.push(file);
            count += 1;
        });
        loadMusic();
    });
}

openFile();

Playing and pausing tracks

Playining, pausing and stopping tracks is easy with the Web Audio API. Stopping is a bit tricky and doesn't behave the way you would expect. So Instead of stopping I pause and set the time back to 0. Skipping is trivial too. Stop the current track, advance one index in the array and play that song. Additionaly I created a variable called nowPlaying to keep track of what track was playing and to easy be able to go forward and backword through the track list. Here's what that looks like.

function playTrack(index){
    if (nowPlaying !== null){
        // this is the "stop" functionality I wrote about aove.
        loadedMusic[nowPlaying].pause(); 
        loadedMusic[nowPlaying].currentTime = 0;
    }

    loadedMusic[index].play();
    
    nowPlaying = index;

    document.getElementById('playPauseButton').innerHTML = '<i class="icon-pause" onclick="pause()" aria-hidden="true"></i>';
}

Todo

So believe it or not, as simple as this project was. I didn't finish it. One thing I really wanted to implement was getting the music file data and use that as the album cover section and getting the correct song names etc. Guess I'll do that at some later point.


Conway's Game of Life in JavaScript

06 December 2016

A few weeks/months/moments ago, I decided to start something I called coding challanges with a good friend of mine. The goal is to excersise our programming chops with little challanges that are to be completed in one week's time. One of the most memerable ones I made so far is Conway's Game of Life. Here's how I did it.

So one rule of the coding challanges are that you must try to not use any existing frameworks to perform core actions of the challange. So making GoL without any frameworks might be tricky. It all starts with a grid, and it needs a size. Then you would need to check if a cell in the grid is alive or dead and then check the other 8 cells around it.

So the grid is just a 2 dimmensional array and I loop through it. Then I check the cell on top of it, the one beneath it, the one in the top left and right corner and the left and right bottom corner. Each cell is 0 for dead and 1 for alive. I then sum up all the values of the cells. And then preform the game rules on that cell. These are shown below.

Then I wrote the code and that looks like this.

if (grid[x][y] === 0){
    switch (tiles){
        case 3:
            tempGrid[x][y] = 1; //if cell is dead and has 3 neighbours, switch it on
        break;
        default:
            tempGrid[x][y] = 0; //otherwise leave it dead
    }
}else if(grid[x][y] === 1){
    switch (tiles) {
        case 0:
        case 1:
            tempGrid[x][y] = 0; //die of lonelines
        break;
        case 2:
        case 3:
            tempGrid[x][y] = 1; //carry on living
        break;
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
            tempGrid[x][y] = 0; //die of overcrowding
        break;
        default:
        tempGrid[x][y] = 0; //
    }
}

One mistake I made was, I was updating the grid while I was still itterating through it to check the cells. This totally messes up the game mechanics because the grid state will be modified. I solved this problem by using two grids, one is the current grid being displayed and the other grid would be a temporary grid to store the next grid frame thats goign to be showed. So when I itterate through I only update then temporary grid. And when I'm done looping I copy the temporary grid to the original grid and redraw the grid on the screen.

This worked but was super slow because I was drawing the pixels using a bunch of divs that were 1 x 1 px with a background color. I needed it to be faster and then remembered that HTML5 Canvas is perfect for rendering things quicker. I did a google search on how to render a pixel on the screen using canvas and hacked that code to fit my modular grid. That functions looks like this.

function drawGrid(){
   for (var x = 0; x < size; x++) {   
       for (var y = 0; y < size; y++) {
            if (grid[x][y] === 0){
                context.fillStyle = "white";
                context.fillRect(x, y, 1, 1);
            }else{
                context.fillStyle = "blue";
                context.fillRect(x, y, 1, 1);
            }
       }
   } 
}

et voilĂ  shes complete. It works and is pretty quick and looks fluid when the grid is small enough. Now on to the next coding challange!


I built a wifi controlled tank robot

18 November 2016

Many weeks ago I built a wifi controlled robot tank. Me and my friends called it Philip. Here's how I built him.

Philip is built with a Raspberry Pi model B, an L293D motor driver, AA batteries, a portable battery bank and a RC tank part from china. I started by looking at what parts I needed, a quick Google search yielded that I needed a motor driver, a raspberry pi and a breadboard with jumper cables.

Now that I live in Groningen, there are a lot more electronic parts I can get my hands on quickly! So to the local okaphone I went with my list, got all the parts I needed too! I preceided to follow the guide I found on the internet and quickly realized something was off. The guide was written for a Raspberry Pi model A, and I had a model B. I had to connect the jumper cables from the GPIO pins on the raspberry pi to the breadboard. But since the model B has more GPIO pins than the model A nothing was working. So i googled the GPIO pins for the model A and B and cross refferenced them to figure out which pins of the model A match with the model B. (Comparison)

So after I figured out the correct pins, I hooked the jumper cables to the breadboard and to the motors. at which point everything looked like this.

Now it was time to write code to make sure this thing actually works. Python has a nice GPIO library that you can use to communicate with the Raspberry Pi's GPIO pins. This made everything super easy! All I had to do was import the library, define my pins, and tell it to either send power to it or not. Here's some sample code of what that looks like.

import RPi.GPIO as GPIO
from time import sleep
 
GPIO.setmode(GPIO.BOARD)
 
Motor1A = 16
Motor1B = 18
Motor1E = 22
 
GPIO.setup(Motor1A,GPIO.OUT)
GPIO.setup(Motor1B,GPIO.OUT)
GPIO.setup(Motor1E,GPIO.OUT)
 
print "Turning motor on"
GPIO.output(Motor1A,GPIO.HIGH)
GPIO.output(Motor1B,GPIO.LOW)
GPIO.output(Motor1E,GPIO.HIGH)
 
sleep(2)
 
print "Stopping motor"
GPIO.output(Motor1E,GPIO.LOW)
 
GPIO.cleanup()

Hooray! the motors spin! it was now time to tackle the biggest problem; fitting everything together. Since I couldn't find any 3mm wheels I couldnt make a robot with wheels. Enter Aliexpress. I did a search for RC wheels and this is what I found. It was perfect! It was big enough to house everything and looked cool as f*ck! without hesitation I ordered it! and 10 days later I got it in the mail. Immedietly I started putting all the pieces together Since I don't have access to a soldering iron or any other kind of board that isn't a breadboard.

I slapped a nice thick layer of tape over the jumpers and trimmed all the cables. It was secure enough. I wrote all the code for forward, backward, left and right, connected the wifi antenna, the AA batteries and everything looked great! Only one more thing was needed, a power bank. A few hours later I went to the MediaMarkt and picked up a VARTA power bank. This was the most expensive part of the entire build. BUT it was finally complete! I even wrote a nice little web app with JavaScript to control it with the arrow keys on a laptop. Here is the finished build.


How to teach someone to code (casually)

07 October 2016

Over the past few months I've been thinking about what would be a good way to teach someone how to code. I could just point them to online free or paid resources and tell them to go at it. But most of the time people just want to create something, and going through those resources often means spending too much time on pointless distractons, having huge difficulty spikes etc. Not to mention you gotta pick one out first!

I believe there is no reason for anyone new to coding to ever do anything else than

  • stay in-browser as much as possible
  • learn the basics of HTML and CSS
  • learn the basics of jQuery
  • only then progress to something else

I think that's the only way beginners can actually create something interesting and usefull. If you start by teaching someone Ruby or Python, the best they can do is make some completely atrificial terminal programs like whats-my-name or something.

Even if someone needs to learn Ruby or Python I believe the best way is to first teach them web technologies, and then using a framework like Ruby on Rails or Django or Laravel they can build something useful. I don't recommend teaching someone "Javascript" as such. What people need is jsut the bare minimum to be able to do simple juery style manipulations. Non-jQuery Javascript is better left for far later.

A lot of resources try to teach beginners how to use terminals, text editors like Atom and SublimeText etc. before they get to any coding.

I don't know why anyone would start with this, It's a massive distraction frmo the goal of learning programming and writing useful programs. Fortunately there's a powerfull environment even absolute beginners are comfortable with, and that's the browser. It's important that beginners use a minimum of unfamiliar tools, and mostly stay in-browser. Github offers free and very easy to setup hosting for such apps.



Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.