How to Implement a Simple Music Player In Go Programming Language

Recently, I spent several days implementing a web music player. Just for fun. With the player, I can listen to songs that are stored in my home computer. While at work, I just need to start a remote service at my house and then open the browser and input the IP and port in order to access my music list.

song list

What is the Go Programming Language

Go is a cross-platform language, no matter what OS you are using you can have fun with it. When I first came to Go, I was attracted to it because Golang is concise, clean, and efficient. I can implement some applications more quickly and efficiently than if I was using C/C++. Although the programming language is totally new to me it was very easy to learn.

How to Implement a Music Player in Go

Download and install Go.

To learn Golang, you can read the online documents.

This is a web-based music player with back-end service written in the Go language. The front-end is implemented in HTML5 and jQuery.

Create a working directory, in which to create a file named player.go and add the following source code:

package main

import (
	"encoding/json"
	"net/http"
	"os"
	"path/filepath"
)

type FileInfo struct {
	Name  string 
	IsDir bool
	Mode  os.FileMode
}

const (
	filePrefix = "/music/"
	root = "./music"
)

func main() {
	http.HandleFunc("/", playerMainFrame)
	http.HandleFunc(filePrefix, File)
	http.ListenAndServe(":8080", nil)
}

func playerMainFrame(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, "./player.html")
}

func File(w http.ResponseWriter, r *http.Request) {
	path := filepath.Join(root, r.URL.Path[len(filePrefix):])
	stat, err := os.Stat(path)
	if err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
		return
	}
	if stat.IsDir() {
		serveDir(w, r, path)
		return
	}
	http.ServeFile(w, r, path)
}

func serveDir(w http.ResponseWriter, r *http.Request, path string) {
	defer func() {
		if err, ok := recover().(error); ok {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	}()
	file, err := os.Open(path)
	defer file.Close();
	if err != nil {
		panic(err)
	}

	files, err := file.Readdir(-1)
	if err != nil {
		panic(err)
	}

	fileinfos := make([]FileInfo, len(files), len(files))

	for i := range files {
		fileinfos[i].Name  = files[i].Name()
		fileinfos[i].IsDir = files[i].IsDir()
		fileinfos[i].Mode  = files[i].Mode()
	}

	j := json.NewEncoder(w)

	if err := j.Encode(&fileinfos); err != nil {
		panic(err)
	}
}

Create a file named player.html, and add the following source code:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>a simple music player</title>		
<style>
	body{
  		font-family: sans-serifVerdana, Arial, Helvetica;
  		font-size: 10pt;
		}
	#playlist {
		border-radius: 10px;
		padding: 5px 5px 3px 5px;
		width: 290px;
		margin-left: 1px;
		margin-top: 10px;
		height: 500px;
		overflow: auto;
	}
	#btn {
		border-radius: 10px;
		width: 296px;
		margin-left: 1px;
		margin-top:  5px;
		height: 50px;
		overflow: auto;
		background: #EEB422;
		font-weight: bold;
		color: white;
	}
    #playlist a {
		display: block;
		cursor: pointer;
		padding: 2px 4px;
		border-radius: 5px;
		overflow: hidden;
		margin-bottom: 2px;
	}
	#playlist a.file { background: #66CDAA;}

	#playlist { background: #3CB371; }
	#playlist a { background: #7CCD7C; }
	#playlist a.playing { background: #9ACD32; font-weight: bold; color: red;}
	#playlist a:hover { background: #EEC900;}

</style>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">

var root = "/music/";
var path = [];

function init() {
	load(path);
	$('#player').bind('ended', next);
	$('#btn').click(next);
}
function load(path)  {
	var url = root+path.join('/');
	$.ajax({
			url: url,
			dataType: "json",
			success: function(data) {
				listFile(data)
			}
		});
}
function listFile(files) {
	var $b = $('#playlist').empty();
	function addToList(i, f) {
		if (f.Name[0] == '.' || f.Name[0] == ':') return;
    	var dir = f.IsDir;
		if(dir) return;
		f.Path = path.join('/');
		$('<a></a>').text(f.Name).data('file', f)
			.addClass("file")
			.appendTo($b)
			.click(clickFile);
	}
	$.each(files, addToList);
}

function clickFile(e) {
	var f = $(e.target).data('file');
	var name = f.Name;
	var path = f.Path;
	var url = root+path+'/'+name;
	$('#playlist a').removeClass('playing');
	$(e.target).addClass('playing')
	$('#player').attr('src', url);
	$('#player').play();
}
function next() {
	var $next = $('#playlist a.playing').next();
	if ($next.length) $next.click();
}

google.load("jquery", "1.3.1");
google.setOnLoadCallback(init);
</script>
	</head>
	<body>
		<audio id="player" controls autoplay autobuffer >
		<p>What? Your browser doesn't support</p>
		</audio>
		<div id="playlist"></div>
		<BUTTON id ="btn" title = "skip this song!">SKIP</BUTTON>
	</body>
</html>

Here is the project structure.

structure

The music folder contains the songs you want to listen to.

Now, in command line tool, type in go run player.go to start the server.

Open the browser and input your IP address and port. Make sure your browser supports HTML5. Chrome is recommended.

Now you can enjoy the music remotely.