Pet project: Creating a fully automated Youtube fishtank livestream using a Raspberry Pi (Part II)
This is the second part of my series of blog posts around creating a fully automated Youtube livestreaming solution for my fishtank using a Raspberry Pi. For an introduction to the topic, my requirements for the project and the general direction I am heading to with my solution, read the first part of this series. In this part I wrote about the equipment we need for this pet project of mine and the overall (financial) costs of getting this to running.
In today's blog post I want to give a little background around the overall concepts that we will encounter once we start dealing with the YouTube live streaming application programming interfaces (APIs) as well as preparatory tasks that we need to perform in order to get an automated live stream running.
If you want to follow along in this blog post series, from now on you will need some basic knowledge about trust and it is also advantageous to have some understanding of unixish shell programming and python scripting, although everything can be learned on-the-fly, if you are just brave enough.
In order to reiterate some basics from the first blog post in this series: Our goal is to stream the video material that an endoscope attached via USB to a Raspberry Pi 4 produces to a YouTube channel as a livestream. The livestream is intended to run fully automated for 12 hours each day and should start at a specified time each morning without any manual intervention. So what you need first is a YouTube channel, in case you do not already have one. We are also running Raspbian on our Pi, which is a Linux distribution, and we have to find a match for the programming language that we can use on Linux with the ones that the YouTube livestreaming API offers. The most natural choice for this is Python, and it seems like everyone else dealing with live streaming is also using Python, so we stick with that. And still then: What program can we use to actually produce video from our endoscope camera? Plugging a USB device into a Pi does not yet produce a video in itself. That program that does all this is ffmpeg, the swiss army knife for all things video streaming, which is part of any decent Linux distribution and we have to install ffmpeg on our Pi. But then: Once we have our workhorse running and producing a video stream, how do we connect this piece of hardware and its satellite software to our YouTube channel, how do we authenticate against YouTube and upload the material to our channel? Do we ...gasp... authenticate with our YouTube credentials from within our python scripting or what?
There is simply no progress in science without decent literature, and it is none the different in our case. I was kidding, there is no specific literature on our topic and we have to resort to intensive googling. The most instructive article on how to get a YouTube livestream running is this one (Click here for a snapshot from archive.org in case this link is going to be dead some day). This article has a pretty good description of what you have to do in preparation prior to running the livestream in order to get all authentication information that is required for unattended operation of your livestream. Essentially it shows how to create a project/application in the Google API Console which is nothing else than getting authentication material, first in the form of obtaining a client secrets file which is then converted to a refresh token for daily use. The part to get the client secret and the initial refresh token is something that I did on my windows PC, not on the Pi, exactly as described in this article.
Having the refresh token (which is supposed to be refreshed - automatically - from time to time, hence its name) is an essential part of automated authentication against YouTube. What you essentially do using the steps described in this article within the Google API console is transferring trust from you, the owner of a YouTube channel, to an application via authentication data created from a one-time secret. From this point on it is your responsibility to protect this authentication data from misuse by others by keeping your application and associated authentication data secure and under your control. Anyone with access to this authentication data has the ability to upload or delete content from the YouTube channel where this authentication data originated from. In my case it is this refresh token that is kept as a file on the filesystem of my Pi where only root has read/write access. The Pi is physically located in my home and protected from physical theft the way all my property is protected in my home: with a locked entry door. None of my networked devices at home receive inbound connections from the internet as would be the case if I had set up my own streaming server behind a publicly accessible IP address. So my YouTube channel is as secure as my home is physically secure after creating the client secret and converting it to a refresh token, as described in great detail on this page.
This article also has an example on how to call the liveBroadcasts.insert API to create a new broadcast for your channel, but it falls short to describe the other moving parts behind the YouTube livestreaming API and how they interact with each other, namely the association between a broadcast and a stream. Using the python code from this article will create a broadcast for you which you can inspect and monitor using the YouTube dashboard, but as it is, this script will always create a broadcast that is bound to the default stream of your dashboard's livestream overview page. It took me a long time to figure this out, and its consequence is that you always have to start your livestream from within the YouTube dashboard by virtue of clicking on the "Go live" button. Doing this requires an interactive login into your YouTube dashboard using your favorite internet browser each time your otherwise fully automated livestream is sending data. Aarggghhh, this is not exactly fully automated and we are back at square one. At this time, it is the concept of streams that we are missing from the big picture. The next part of this blog post series will be my attempt to describe the relationship between broadcasts and streams they way I perceive it.