Boot.dev
Published in

Boot.dev

Create a Golang Video Streaming Server Using HLS — A Tutorial

The post Create a Golang Video Streaming Server Using HLS — A Tutorial first appeared on Qvault.

In this tutorial, I’m going to walk you through building a Golang video streaming API (this works for other types of media as well!). Don’t worry, its surprisingly easy to build a robust media 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.

https://en.wikipedia.org/wiki/HTTP_Live_Streaming

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. This saves the user a lot of potential bandwidth and allows the song or video to start playback almost immediately.

Using FFmpeg, we can easily convert mp3 files to 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 and typically contain ~10 seconds of audio and are served one-at-a-time at the client’s request.

FFmpeg

Get Started — Format Some Media for your Server

Download a sample .mp3:

Install FFmpeg. 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 Streaming 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:

Screen Shot 2019 12 03 at 8.57.28 AM

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. You can find a free online client here: https://hls-js-latest.netlify.com/demo/

Simply paste your song’s URI and listen:

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

Thanks For Reading!

Follow us on Twitter @q_vault if you have any questions or comments

Take some coding courses on our new platform

Subscribe to our Newsletter for more programming articles

Related Articles

Building an HLS Streaming Server in NodeJS
Lint on Save With VS Code Official Golang Extension
Running Go in the Browser With Web Assembly (WASM)

--

--

--

New computer science and coding articles every week.

Recommended from Medium

Flutter vs React Native

CS 373: Blog #7

GitHub API With Python & PowerShell Scripting

Modern Day Web Development

6 Things to Avoid When Contributing to Open-Source Projects

CSS percentage unit, the evil parts

How to migrate to Box cloud storage

How to Make Your Product Likable

Someone designing a product.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Lane Wagner

Lane Wagner

I love Go and Rust, and I like JavaScript and Python. I’m indiehacking on https://boot.dev when I’m not with my wife and daughter.

More from Medium

A good summary of Go lang basic syntax

How to build a very simple CLI program to make HTTP requests with Go

GoFrame 101: Log management

Golang packages