Build your own streaming service using Azure

24/12/2020

In true Christmas tradition I have to create a blog post on Christmas eve. This year I have special present prepared that I used a few weeks ago for our annual Christmas party. Of course it being 2020, nothing is how it usually it, so our Christmas party this year was a Microsoft Teams call, where we had fun for a good 8 hours with a bunch of different virtual activities.

My contribution to the activities was a virtual Music Video Quiz. I guess there are many ways to host such Quiz, but of course it is more fun to try out some tech in the process. My setup was:

  1. Around 50 old music videos in various formats, acquired before YouTube was a thing
  2. VLC Media Player, to play the videos
  3. OBS Studio, to stream the VLC window with an overlay blocking the music video titles (which was embedded in most of the videos, as the videos are recorded from TV)

The final piece of the setup was a streaming service where I could stream the videos to. The idea was then to have my colleagues all open the stream and do a quiz on who could guess which music video I was playing the quickest. The idea of using a 3rd party service was that we could still chat uninterrupted on Teams while seeing each others video feeds.

My intension was to use either Twitch or YouTube live that I have used before when streaming video games. But when I tested out my setup, I quickly discovered that YouTube wasn’t happy with streaming music, my stream got flagged within a couple of minutes for streaming copyrighted music. Rightfully my music videos did contain copyrighted music, but as my goal was to stream for 10 of co-workers I didn’t feel like YouTube should be the reason for cancelling what I thought was a fun idea.

Instead I set out to find a streaming solution that I could host myself in Azure for this specific event. I honestly didn’t give Twitch a chance, as I was running short on time, and giving all the latest DMCA take downs on Twitch I assumed that they had something similar implemented as YouTube.

Restreamer to the Rescue

The solution I found that fit my requirements was restreamer a pretty nice open source project that packages everything you need for streaming into a easy to deploy docker container. It uses open source tools such as ffmpeg and nginx to forward the rmtp stream under the covers, but the fact that you don’t have to fiddle with setting everything up yourself, makes it a great choice in my opinion. The real purpose of restreamer is in fact a bit different that just hosting your own streaming service, it is really intended to distribute a stream to several different streaming platforms, but it does come with is own html5 video player, that can be used to watch your stream which was ideal for my use case.

Hosting it on Azure was a breeze, and as you might now I love using the ACI (Azure Container Instances) service for hosting things like this that isn’t intended to be online 24×7. So I have prepared a simple ARM template that you can use to spin up your very own restreamer hosting service. (I must admit that a created the ARM template after our party, on the day of the party I just went with a Ubuntu VM with the container running on).

Here’s a quick guide to set everything up. 

  1. Deploy the template from https://github.com/sjkp/azure-arm-aci-restreamer
  2. Go the the deployment page for the resource group in Azure and find the input parameters
  3. Go to your OBS settings and set steam to custom and set server to: rtmp://<your-dns-name>.westeurope.azurecontainer.io/live and key: external.stream?token=<your-stream-password> to
  4. Log on to the admin interface of restreamer on http://<your-dns-name>.westeurope.azurecontainer.io:8080 using user admin and the admin password found on step 2. 
  5. Now change the video source to rtmp://localhost/live/external.stream?token=<your-stream-password> and click start
  6. Now click open player and you can see your stream, note there will be some seconds delay
  7. You can also open the stream by navigating to: http://<your-dns-name>.westeurope.azurecontainer.io:8080/player.html

 

Final Words

Although this setup is quick and easy, it also have a few limitations/challenges that you should consider before you plan to take on YouTube or Twitch. E.g. the bandwidth usage is going to be pretty insane, and as a result the costs. I had 10 people on the stream for a few hours, and it resulted in the following bandwidth usage. Note that I streamed at 1920×1080 @ 60 FPS with a 6000 Kbps limit set. Yes probably overkill for the use case, but I forgot to change it from the last time I streamed a video game. 

As you can see I racked up a total of 62 GB of out-bound data transfer, which is something you have to pay for. The bandwidth cost on my Azure subscription was 31 Danish kroner, that would be around 4 dollars. Not a lot, but you can imagine how much bandwidth will cost if you run a real streaming service. I’m sure the big streaming services have considerable discounts. I imagine even below the cheapest bandwidth in Azure, but even then the cost is not going to be insignificant.

Now you are probably wondering how much CPU is required to host the streaming service, and with my settings where I didn’t reencode the stream or did any processing other than forwarding what my computer had already encoded, the CPU usage was pretty limited. You can see it on the following graph. The VM I used while running the stream service was a Standard B2s (2 vcpus, 4 GiB memory), so a pretty modest configured machine.

Alternatives

As you might know Azure have a built-in service that can also be used for streaming, called Azure Media Services. If you don’t want to play around with docker containers, then you can read this article by David Sayed on how to configured Azure Media Services for streaming. I didn’t give this a try myself, and I feel that the service still have a way to go when Microsoft themselves often turns to YouTube for streaming their own events. But maybe it is worth exploring Azure Media Service in another blog post, to figure out, why it is not gaining traction.