In a previous post I described setting up an RPi Zero and camera to stream video over the internet. This is obviously a very valuable thing to do, for example, if you have cats and love them so much that you just want to be able to see them all the time. However, the method that I used, which involved a home network-based server, port-forwarding, and dynamic DNS is one that I was never entirely comfortable with from a security POV.
After some thought and reading on the subject, I finally discovered a ready-made solution to the problem – YouTube!
YouTube allows users with a verified account (a process which, for some reason, takes all of 24 hours) to stream apparently unlimited video at absolutely no cost. There are obviously some limitations, which are tl;dr, but generally look pretty reasonable AFAICT.
First things first.
You’ll need an RPi (I used a 3B+ for this exercise, but I’m sure a Zero or anything else would be fine) an up-to-date version of Raspian (although I suspect this might work with other forms of RPi linux).
In the terminal, do this:
sudo -y dist-upgrade
Plug in your camera. This requires some care. Look closely at the ribbon and the sockets on the board and the camera. There is a small plastic retaining clip on each socket that you need to gently pull up/out to open the socket. Slide the ribbon cable into the socket and close the clip. Make sure the shiny contacts are facing in the right direction to make proper contact with the socket. Look at these images to get a better idea. (If your camera doesn't work, this is the first thing you need to check.) Note that there are two similar sockets on the RPi 3B+ board - one is labeled "display" (the one at the end), and the other is labeled "camera" (the one closer to the middle of the board).
Now make sure your camera is working. Turn it on. The easiest way to do that is to go to "Preferences" and "Interfaces" in the main pull-down menu on the GUI and activate the camera. (You may also need to enable I2C.)
Next run the following command:
raspistill -a 12 -vf -hf -t 0 -k -w 640 -h 480 -o pistill.jpg
-a 12 gives you a date stamp, -vf -hf flips the camera image vertically and horizontally, -t 0 -k allows you to take a picture by hitting the ENTER button, and then exit the raspistill program by hitting "x" followed by ENTER. -w 640 -h 480 sets the width and height of the image in pixels. You can experiment with all of these. An introduction to the two basic camera applications, raspistill and raspivid, and some of their command line options, can be found here.
After you execute the command, hit ENTER (to record an image), and the press "x" followed by ENTER (to exit the program), the file pistill.jpg should be in your /home/[yourusername]/ directory waiting for you to look at it. If it's not there, go through the steps above again, taking special care to be certain that the camera is correctly plugged in to the board. (If you plugged it in to the "display" connector, it definitely won't work.)
Once you're sure your camera is working, you'll need to have an active Google Account and a YouTube Channel. Google should be able to provide adequate instructions for this. After that's taken care of, go to YouTube Studio and follow the prompts to stream. This is not perfectly intuitive, but even I was able to figure it out, so you should be able to as well. Just take a look at my channel here to get an idea of how this works. The first screen you'll see when you go to the YouTube Studio with your own account is the main dashboard. Click on "Videos," then on "Live." You'll be prompted to verify your account, and you'll need to wait another 24 hours before you can start streaming. From here the steps are more or less intuitive if you follow the prompts.
At a certain point in the process you will be provided with a streaming URL and a "secret key." Save these in a file where you can easily access and copy-paste them. You'll need them for the next steps.
Note: if all of this looks confusing, take a look at these pages here and here to get a better understanding of the process of setting this up. However, I would suggest *not* using the streaming commands that these pages provide. I had a little trouble getting them to work, and so I will provide a slightly different one that worked for me below.
One you have your camera working and your YouTube Account set-up for streaming, go ahead and start the live stream reception in Youtube Studio. Then point your camera at something and execute the following command at the terminal prompt:
raspivid -o - -t 0 -fps 25 -g 50 -rot 180 -n -a 12 -b 6000000 | ffmpeg -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero -f h264 -thread_queue_size 256 -i - -vcodec copy -acodec aac -ab 128k -strict experimental -f flv rtmp://a.rtmp.youtube.com/live2/[yoursecretkey]
Note that you need to copy and paste your secret key after the last backslash. Leave out the square brackets; just paste the key. Also note that this command string is really long; if you want to you can try putting this in a bash script either with the secret key hard-coded in the script, or with a $arg variable that you supply to the script when you execute it. I won't go into all the details of that here, but if you'd like to learn about shell scripts, Norm Matloff's brief introduction to these is a great place to start. Just don't forget to put #!/bin/bash at the top of the script file. Also don't forget to make the file executable like this:
sudo chmod +x [yourshellscript].sh
And, when you execute the script, do it like this:
You'll need the dot-slash in front in order for the OS to recognize it as a command.
I should also point out that the critical difference between this command and the others provided in the links above is the option "-thread_queue_size 256" without which you will probably get an error (I did). So try the command string I provided first. The links are helpful, however, if you want to learn a little more about raspivid and some of the command options.
If everything works like it's supposed to, then in a few minutes you should be streaming.
Go here to see a recorded stream that I made (YouTube will supposedly record up to 12 hours of live streamed video, which is astonishing).
Now, if you want to get really fancy, you can actually embed your stream (either live or recorded or both) in a web page. Just don't put it in a web page that you're hosting in your own home network server. At least, not unless you are very knowledgeable about web security and know exactly what you are doing. The better option, IMHO, is to use a cloud server like Heroku. Eventually, that's exactly what I plan to do, but Heroku requires a little more familiarity with git than I have right now, so (ironically) I found it easier to use my already existing web page on GitHub. I won't explain the details of how to establish a GitHub (or Heroku) account here; it's pretty easy, and both services provide web site hosting and pretty straight-forward instructions for how to set up a web page. (They're also our favorite price.)
I'll just add that in order to create a web page it helps to know something about how to use and write html. I like Mozilla's tutorial on html basics. Note that with a GitHub page you can either use straight html or a simplified version called Markdown (or md). All this html and md stuff is probably going to require a little work on your part, but you really only need to get the basics in order to get started. You can take a look at the internals of my web page on GitHub to get some pointers. Note that there is a little file called "_config.yml" here that is not normally present in the directory for a typical html web page. This is a configuration file for Jekyll which GitHub uses to build your site. Don't worry too much about this; you can ignore it for now. The point is that if, like me, you use GitHub to host your site, GitHub and Jekyll will impose some limitations, and also require you to modify your use of html a little bit. It will also be a little quirky compared to a normal html page. For example, you can only build a static site (no PHP) , and you need to *not* use the normal
<DOCTYPE html> tag in the index file. (When you look at my code, you'll notice that it's there, for future use with Heroku, but it's commented out.)
So, if you've made it this far, let me show you the way I embed my Youtube live stream and recorded streams.
This for the live stream:
&tl;a title="Youtube Livestream" href="https://www.youtube.com/embed/live_stream?channel=[yourYouTubechannelcode]">&tl;img src="luxlivebutton.jpg" alt="Livestream" />&tl;/a>
You need your YouTube channel code for this (again, leave off the square brackets). You can find this right after "studio.youtube.com/channel/" in the url for the YouTube Studio Dashboard page.
For a previously recorded stream, use this code in your page:
&tl;a title="Youtube Video" href="[yourvideostreamURL]">&tl;img src="luxvideobutton.jpg" alt="Video" />&tl;/a>
In this case, you will need to use the URL for the previously recorded video stream. You can actually see a recorded stream here of a little polyhedral light sculpture; you can also access the same stream (and a live stream when it's active) through my GitHub web page.
Note that for the streams I have created little buttons to click on; this is pretty easy to do if you use Gimp or something like it to create graphics. These files are in the web page directory if you want to see them.
Just one more thing:
This entire description presupposes that you're doing this with a Pi connected to a keyboard and a monitor. But that's not how I did it. It's actually easier, I think, to SSH from a laptop to a Pi, and then work in both simultaneously. What I did was connect my laptop to the Pi via SSH and VNC (in order to have access to the Pi GUI) through an SSH tunnel. That's really a topic for another post. But it did facilitate the process a little for me because I could work on YouTube and GitHub with the laptop, and take care of the camera-related processes on the Pi. Note that if you want to do it this way, you need to make sure that SSH and VNC are also enabled (along with the camera and I2C) in the Pi configuration, accessible through "Preferences" and "Interfaces." You can do this through the command line as well, in which case you don't really need VNC or the GUI at all, although I find it more convenient to do some things that way.
So, there you have it. If you're interested in seeing the full html code for my page, you can easily view it in my my GitHub repository; embedding it here is a fairly laborious process, so I'll leave it up to you to find it.