Building a Music/Video Streaming Server in Go – Using HLS
Tags: go, programming, tutorial
Published: 2019-12-03 18:31:34

---
title: Building a Music/Video Streaming Server in Go – Using HLS
published: true
date: 2019-12-03 16:23:39 UTC
tags: go,golang,Programming,Tutorial
canonical_url: https://qvault.io/2019/12/03/building-a-music-video-streaming-app-in-go-using-hls/?utm_source=rss&utm_medium=rss&utm_campaign=building-a-music-video-streaming-app-in-go-using-hls
---

![](https://qvault.io/wp-content/uploads/2019/12/photo-1470229538611-16ba8c7ffbd7-1024x683.jpeg)

In this tutorial, I’m going to walk you through building a streaming API using Golang. Don’t worry, its surprisingly easy to build a robust streaming server, especially if we utilize one of the more modern protocols: HLS.

## What is HLS?

> HTTP Live Streaming is an HTTP-Based adaptive bitrate streaming communications protocol developed by Apple.
> 
> <cite><a href="https://en.wikipedia.org/wiki/HTTP_Live_Streaming">https://en.wikipedia.org/wiki/HTTP_Live_Streaming</a></cite>

HLS allows us to serve large media files as many smaller text files that are broken up into ~10-second increments. By breaking them up in this way, our user’s client-side app only needs to buffer 10 seconds in advance, which saves them a lot of potential bandwidth and allows the song to start playing much faster.

Using [FFmpeg](https://www.ffmpeg.org/), we can easily convert mp3 files to the HLS format, which consists of multiple files. One of these files contains the metadata (.m3u8) and is served first. This metadata file tells the client where to get each data file, and what each data file contains. The data files have a .ts extension. Data files typically contain ~10 seconds of audio and are served one-at-a-time at the client’s request.

![](https://qvault.io/wp-content/uploads/2019/12/1_mgCxTQSqrTvKsmDRmuRa7w-1024x499.jpeg)

## Getting Started – Format Some Media

Download a sample .mp3:

[http://www.hubharp.com/web\_sound/BachGavotteShort.mp3](http://www.hubharp.com/web_sound/BachGavotteShort.mp3)

Install [FFmpeg](https://www.ffmpeg.org/). If you are on a Mac:

```
brew install ffmpeg
```

Navigate to the directory of the mp3 file and run

```
ffmpeg -i BachGavotteShort.mp3 -c:a libmp3lame -b:a 128k -map 0:0 -f segment -segment_time 10 -segment_list outputlist.m3u8 -segment_format mpegts output%03d.ts
```

This should result in three new files:

```
output000.ts output001.ts outputlist.m3u8
```

Congratulations! You are done with the hard part, you now have simple files that can be served over HTTP. Any modern client-side media library will know how to read HLS files.

## Building the Server

As I eluded to above, HLS is very simple on the server-side. All we need to do is serve a path to the .m3u8 file, and make sure the .ts files are served from the same path. In traditional file server architecture, this just means that they need to be in the same directory.

Let’s set up our project with the following folder structure:

![](https://qvault.io/wp-content/uploads/2019/12/Screen-Shot-2019-12-03-at-8.57.28-AM.png)

Copy the following code into main.go:

```
package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	// configure the songs directory name and port
	const songsDir = "songs"
	const port = 8080

	// add a handler for the song files
	http.Handle("/", addHeaders(http.FileServer(http.Dir(songsDir))))
	fmt.Printf("Starting server on %v\n", port)
	log.Printf("Serving %s on HTTP port: %v\n", songsDir, port)

	// serve and log errors
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%v", port), nil))
}

// addHeaders will act as middleware to give us CORS support
func addHeaders(h http.Handler) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		h.ServeHTTP(w, r)
	}
}
```

Now run your server:

```
go run main.go
```

Your server is live! Test your music play by using a media client. A free online client can be found here: [https://hls-js-latest.netlify.com/demo/](https://hls-js-latest.netlify.com/demo/)

Simply paste your song’s URI and listen:

```
http://localhost:8080/bachgavotteshort/outputlist.m3u8
```

## Thanks for reading! Good luck with your media project!

Lane Wagner on Twitter: [@wagslane](https://twitter.com/wagslane)

Lane on Dev.to: [wagslane](https://dev.to/wagslane)

Lane on Medium: [@wagslane](https://medium.com/@wagslane)

Download Qvault: [https://qvault.io](https://qvault.io/)

Star our Github: [https://github.com/q-vault/qvault](https://github.com/q-vault/qvault)

The post [Building a Music/Video Streaming Server in Go – Using HLS](https://qvault.io/2019/12/03/building-a-music-video-streaming-app-in-go-using-hls/) appeared first on [Qvault](https://qvault.io).