Live Stream Your Pets with Linux and YouTube!
Thu, 10/26/2017 – 06:53
Anyone who reads Linux Journal knows about my fascination with
birdwatching. I’ve created my own weatherproof video cameras with
a Raspberry Pi. I’ve posted instructions on how to create your own
learned CSS so I could make a mobile-friendly version of BirdCam that
filled the screen in landscape mode.
Recently, however, I’ve finally
been able to create an automated system that streams my BirdCam live
over YouTube. It starts when the sun comes up and stops when the sun
goes down. And thanks to some powerful open-source software, I never
have to touch the system!
Some of the tools I describe here have been
covered in other articles, but this is the first time I’ve been able to
create a stream that anyone can see utilizing bandwidth Google pays for!
Figure 1. Birds are always camera-shy. If you watch long enough, however,
they come and steal peanuts!
My List of Ingredients
First off, I want to be clear about what sort of hardware and software is
required in order to accomplish something similar to what I’m doing:
A Linux computer: if you plan to use USB cameras, this needs to
be a physical computer. If your video source is network-based, this
can be a virtual machine on your network. A Raspberry Pi isn’t really
powerful enough for the video work that has to be done, unless maybe
it’s low-resolution. I have an old i5 CPU running at 1.6GHz, and it’s
more than enough.
A video source: this can be pretty much any video source you have
at hand. If you plan to use a USB webcam, you’ll need to be sure you
are using a physical Linux computer as noted above. I’ve used USB,
MJPEG over http (see my old BirdCam articles), cheap wireless security
cameras that have an RTSP stream, and most recently, I started using
UniFi video cameras. In fact, if you are considering purchasing outdoor
video cameras for a project like this, I can’t recommend UniFi cameras
enough. They are PoE, HD and the free software handles recording and
provides RTSP streams that have both HD video and top-notch audio.
A YouTube account with Live Streaming enabled: you’ll need to verify
and then enable live
It’s not a
difficult process, but without following those steps, you won’t be able
to use the free service.
Open Broadcaster Software: I’ve tried multiple ways to use a CLI solution
to stream directly to YouTube with FFmpeg or mencoder, but I’ve never been
able to make it work consistently. I was hesitant to use OBS, because it’s a
GUI solution and doesn’t have a CLI interface, but I worked around that
problem, and I’m actually happy to have the GUI now.
A web server to host your embedded channel: you could just share the
URL to your YouTube channel, but embedding is much cooler, because you
can integrate it into your own site.
Enough upstream bandwidth to support 1.5–2mbps while streaming: since
YouTube is going to redistribute, the local bandwidth requirements
don’t change regardless of how many people are watching your stream. For
some folks (like me, unfortunately), sacrificing that much bandwidth is
difficult and sometimes causes issues. Just know that it takes a small,
but not insignificant amount of constant upstream bandwidth to stream
live video. That should be obvious, but it’s something to consider.
A few other utilities like crontab and sunwait: the latter is only if
you want to time your streams with sunrise and sunset. And, crontab is
needed only if you want to automate the starting and stopping. Those touches
really make a difference for me though, so I encourage you to consider it.
Gather Your Info
In order to live stream, you’ll need a few bits of information. As
I mentioned above, you’ll need to verify your account to turn on streaming. Then you’ll need to get your streaming key (Figure 2). It’s
important that you not share the streaming key, because it acts like
your authentication. If others get your key, they can stream to
your channel, even without your user name.
Figure 2. That’s not my real streaming key, just FYI.
The other bit of information you’ll need from YouTube is your
channel ID. It’s not easy to find the channel ID, but if you
want to embed your video, you’ll need it later. Head to
this page, and find the
looks like, «YouTube Channel ID: UCbUTB3bVg3cmeyJUtUC9DPA» (your channel
ID will be different from mine). The long string of text is your channel
ID, copy that somewhere easy to find.
Video Camera Feeds:
I can really give you only hints about what to look for here. You need
to find the streaming video feed coming from your camera. Make sure you
don’t use the web page that has the stream embedded (most cameras have
a rudimentary web server that embeds the stream). You need the raw feed
itself. Google or the user’s manual will be your best bet for figuring
out the raw stream URL.
I have an Onvif-compatible video camera that has an MJPEG stream URL
that looks like this:
One of my Foscam cameras requires a user name and password in the URL in
order to get the stream. It looks like this:
And my new UniFi cameras actually use an RTSP URL that comes from the
UniFi server instead of from the cameras directly. It looks like this:
The point I’m trying to make is that finding your video camera’s
streaming URL often is challenging. If you do it before you start, it
can save hours of frustration. An easy way to test if you’ve found the
correct URL is to try opening it in VLC. I haven’t found a video camera
that VLC can’t view, so if it complains about an invalid video source,
you probably don’t have the correct URL. Google, along with your camera’s
model number, is probably the best way to figure it out.
There are many scripts online claiming to stream from a camera source to
YouTube using FFmpeg. I’m sure they work for someone, but I’ve never
gotten them to work, no matter how many settings I tweak. In fact,
I gave up for quite a while because I didn’t want to rely on a GUI
interface to stream. I wanted my server to do the dirty work and do it
without my interaction. One day recently, however, I discovered that
Open Broadcaster Software (OBS) supports command-line flags for starting
streaming. That means I could have the server start streaming without
the need to «click» anything.
One problem I had to overcome was the lack of the X Window System on my BirdCam
server. There’s no monitor connected to the server, but in order
for OBS to work, it has to have a logged-in GUI desktop. I hooked up a
monitor long enough to get a GUI installed and then set the system
to log in automatically. I also disabled all power-saving features for
the monitor, because I wouldn’t have one logged in anyway. Once it was
set up, I installed TeamViewer so I could control the system
remotely if I needed to. There have been some issues with TeamViewer’s security
recently, so it might not be the software you choose for controlling the
server, but it’s what I have installed, and it works. Figure 3 shows my
«server» controlled remotely via TeamViewer.
Figure 3. I don’t normally have the security camera to my cat’s litter
cave on my live stream, but I wanted to show multiple cameras.
Installing OBS is simple. Head over to the OBS
and download the
latest version, or simply install their PPA if you’re using Ubuntu. The
software has matured since I last mentioned it, and I didn’t have any
problems with dependencies, even when connecting over a remote session.
OBS also has the great feature of saving your last-used session. That
means once you set up your cameras, you don’t have to worry about
readjusting them on the next launch. OBS just uses the same settings you
had before. If you look back at Figure 3, you’ll see there are multiple
cameras added to the preview window. Without the need to save a layout,
OBS just remembers from launch to launch how you had the cameras positioned.
In order to get the best results, you need to tweak a few OBS settings.
Click the settings button, and then head over to
the Video tab (Figure 4). This is a little confusing, but you have two
different resolutions to set. The «canvas» is how big you want OBS to
show on your preview window. The «output» resolution is what it scales
your video to for streaming and recording. I just set them both to 720p,
because I figure scaling takes CPU. You also set the frames per second
(FPS) for the output video. I use 10FPS with the 720p size. You can
adjust this if you want 1080p, or down if you don’t have bandwidth.
Figure 4. The resolutions are flexible, but I like to keep it simple.
Next, click on the «Output» tab (Figure 5). My settings are visible, and
I recommend keeping them close to mine, except for the bitrate of the
video and audio. If you want higher quality video (and you can afford
the bandwidth), this is where you set the average upload speed. You
also can change the audio quality if you want higher quality. Keep in
mind that the resolution you chose in the last step will work with the
bandwidth you selected here to give you the video quality users will
see. A video rate of 1500 (measured in kbps) works well with my 10FPS
and 720p resolution. But if you try to stream 1080p, 30FPS video with
1500kbps, it’s going to be really poor quality video. You’ll have to
experiment to find the sweet spot.
Figure 5. 1500 is the maximum my current internet connection can handle.
The «Stream» tab is where you configure the streaming service you want
OBS to use (Figure 6). You should be able to select YouTube and then paste
that stream key you got from YouTube earlier. (This is
not the channel
ID; it’s that hidden key from back in Figure 2.) Once entered, you shouldn’t
need to make any changes in settings. OBS will keep all the settings,
including streaming information.
Figure 6. It’s truly amazing how well OBS does with YouTube streaming.
All that’s left is to add the camera(s) to your preview screen. This is
the nicest feature of OBS, well apart from actually being able to stream
to YouTube. The setup is drag and drop, and you can resize cameras,
overlap cameras and arrange them however you want. Since OBS supports
so many types of inputs, you can get crazy with text overlays and so on. To
add a network camera, click the + at the bottom middle of the main
window, and select «media source» (Figure 7). Then uncheck
and enter the camera URL in the «input» field (Figure 8). Once you click OK,
your camera should appear on the preview window, and you can resize and
move it. The interface also allows you to crop the section of the video
you want to use. It’s very powerful and incredibly
as I mentioned earlier, OBS stores all your tweaks automatically,
so the next time you start it, you’ll get the same arrangement.
Figure 7. Media source isn’t obvious as the choice for network cameras.
Figure 8. Be sure to uncheck the «local file», or you won’t have an
Once you have your camera(s) set up, you can decide whether you want
to include audio if your camera supports it. The audio levels should
appear in the column next to the list of cameras. Then just click «Start
Streaming» to send your stream live to YouTube. It takes 30 seconds or
so to show up in the YouTube dashboard, but now is the time to make sure
I could just leave OBS running 24/7 and have it stream my bird feeders all
night. Honestly, I’m not sure how YouTube would handle a 24/7 stream, but
I don’t want to do that anyway. I not only want to automate the starting
and stopping of OBS, but I also want to make sure that if something crashes,
it starts back up the next day without me needing to fix it. Cron was
the obvious way to manage that, but since OBS is a GUI program, cron
proved to be challenging. In the end, I was able to include environment
variables in my crontab, and things worked smoothly. Here’s what my OBS
part of crontab looks like. Check it out, and I’ll explain it afterward:
DISPLAY=:0 @reboot sleep 10; obs --startstreaming 0 5 * * * /usr/local/bin/sunwait civ up 45.3733N 84.9553W; ↪obs --startstreaming 0 16 * * * /usr/local/bin/sunwait civ down 45.3733N ↪84.9553W; pkill obs
First off, setting the
DISPLAY environment variable
:0 means that
crontab can launch a GUI application on the current desktop. I was
embarrassed when I realized how easy it was to get cron to launch GUI
apps. It is important to note that the user must be logged in, however.
@reboot line starts OBS when the system boots. The simple
--startstreaming flag tells OBS to launch and immediately start
streaming. It’s awesome. Really, if I had to figure out a way to automate
actually clicking a button, we probably wouldn’t be doing this project
The next two lines are a little confusing. First off, I have the program
«sunwait» installed. It’s an old program, but it’s so
believe it’s not in every distribution by default. I’ve mentioned it
before in BirdCam articles, but basically, it’s a C program that determines
sunrise and sunset based on your longitude and latitude. The last version
was released in 2004 (seriously), but it still compiles. You can get
the source here.
Anyway, those two cron lines tell the server to start and stop OBS
at sunrise and sunset. At 5AM, I tell sunwait to «wait» until the sun
rises. It literally just waits until sunrise and then ends. Once it ends,
OBS is started up. Then at 4PM, I tell sunwait to wait until sunset, and
after the sunwait program ends,
kill stops OBS. Why 5AM and 4PM? Well,
in my part of the world, the sun never rises before 5AM and never sets
before 4PM. There is the potential problem that if I reboot my server
after 4PM, it will stream all night. But that potential problem doesn’t
concern me enough to make the logic more complicated.
Since my server doesn’t have a monitor or keyboard connected, a random
GUI application starting and stopping in the middle of the screen doesn’t
affect anything. Since I connect to my server’s desktop only when I
want to make a change to OBS, it’s actually convenient that it’s always
running front and center on my desktop! I couldn’t be happier with the
current live stream setup.
Embedding the Stream
Not long ago, YouTube made a change so that every time a live stream
starts, it gets its own embed code. That means if you simply use the
«share» button on the live stream to get the embed code, it will work
only for that current streaming session. For me, that means the next day it
would show a recording of the previous day, but not the live stream. I’ll
be honest, that quiet change was very frustrating! Thankfully, there is
a way to embed the actual live stream, so that any time you start live
streaming, it becomes active—that’s where the Channel ID you got earlier
Here is the embed code for my live stream at http://birds.brainofshawn.com»>:
Obviously, you’ll need to make the changes for your own channel, but
it should be clear what the various things mean. I stuck with the 720p
size even on my embedded page. Since this is embed code, you don’t have
to put it on its own page like I did; you could embed a tiny resolution
version on your blog, for instance.
Setting up the live stream through YouTube is nice for several
reasons. One, your bandwidth requirements don’t change even if you have
10,000 viewers. Also, since it’s YouTube, you can «cast» the video to
a television or Chromecast device and show off your channel to your
friends. I still hope to get more cameras and maybe set up camera
rotation on multiple bird feeders, but for right now, I couldn’t be