Streaming To Youtube

Although I'm using Youtube in this tutorial, the concept should also work with other streaming services like Twitch.tv and FacebookLive. Most of these streaming services use a protocol called Real-Time Messaging Protocol (RTMP). So in order to stream to Youtube, we'll need the RTMP URL as well as a private key for our specific stream.

To get your key and URL, go to your Youtube Dashboard and select "Live Streaming" and select either "Stream now" or "Events" and create a new event. Following those steps will allow you to generate a new RTMP URL and private key.

With our URL and key, we can now turn back to the Raspberry Pi to make a streaming program using Python. When it comes to streaming from a Raspberry Pi, there are actually several different methods. One of the easier ways is by installing avconv (part of the libav-tools package) and using raspivid to pipe the stream to the RTMP URL. Here's a sample of how that would work from the command line:

sudo apt-get install libav-tools 
raspivid -o - -t 0 -vf -hf -fps 30 -b 6000000 | avconv -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero -f h264 -i - -vcodec copy -acodec aac -ab 128k -g 50 -strict experimental -f flv rtmp://a.rtmp.youtube.com/live2/[your-secret-key-here] 

This method might work alright through the command line, but whenever I tried to incorporate it into python code, it wouldn't work. There seems to be an issue with avconv and Youtube.

The program that worked the best for me was FFMpeg. Most of you may know that avconv is a 99% compatible replacement for FFMpeg, but Youtube streaming seems to fall within that 1%. Those of you that have worked with FFMpeg on the Raspberry Pi before know how difficult (and how long) it can be to install. I clocked it at just slightly over an hour from beginning to end using a Raspberry Pi 3 using the steps below (based on these steps https://github.com/tgogos/rpi_ffmpeg).

sudo sh -c 'echo "deb http://www.deb-multimedia.org jessie main non-free" >> /etc/apt/sources.list.d/deb-multimedia.list' 
sudo sh -c 'echo "deb-src http://www.deb-multimedia.org jessie main non-free" >> /etc/apt/sources.list.d/deb-multimedia.list' 
sudo apt-get update  
sudo apt-get install deb-multimedia-keyring 
sudo apt-get update  
sudo apt-get install build-essential libmp3lame-dev libvorbis-dev libtheora-dev libspeex-dev yasm libopenjpeg-dev libx264-dev libogg-dev
cd ~
sudo git clone git://git.videolan.org/x264 
cd x264/ 
sudo ./configure --host=arm-unknown-linux-gnueabi --enable-static --disable-opencl 
sudo make -j4
sudo make install 
cd ~
sudo git clone https://github.com/FFmpeg/FFmpeg.git 
cd FFmpeg/ 
sudo ./configure --arch=armel --target-os=linux --enable-gpl --enable-libx264 --enable-nonfree 
sudo make -j4 
sudo make install 

Now that you're back from a nice break after letting all this install, we can finally write a simple streaming script to test it out. Basically we can use the subprocess PIPE command to emulate entering the command in a terminal and then "pipe" the camera stream through FFMpeg to Youtube.

Getting the FFMpeg command just right is kinda tricky, but the one I used below seems to work well for me. The value that you might need to adjust is the itsoffset value. It's what helps sync the audio with the video. It basically "offsets" the video by a number in seconds. In my example, the offset is for 5.5 seconds. So if your audio and video or out of sync, you can try adjusting this number.

NOTE*** If you start getting a lot of "Alsa X Buffer" errors, then that means your itsoffest is probably too high. Adjusting it to lower will fix this issue.

Depending on the type of microphone your using, you may also need to change the hw value in the script. Mine is listed as card 1, so my hw value is 1,0 below. You can find what your audio device is listed as by typing the command:

arecord -l

This will list all of your recording devices and tell you what card number they're listed as.

Below is some sample code for streaming stream_test.py

#!/usr/bin/env python3 
import subprocess 
import picamera 
import time 
YOUTUBE="rtmp://a.rtmp.youtube.com/live2/" 
KEY= #ENTER PRIVATE KEY HERE# 
stream_cmd = 'ffmpeg -f h264 -r 25 -i - -itsoffset 5.5 -fflags nobuffer -f alsa -ac 1 -i hw:1,0 -vcodec copy -acodec aac -ac 1 -ar 8000 -ab 32k -map 0:0 -map 1:0 -strict experimental -f flv ' + YOUTUBE + KEY 
stream_pipe = subprocess.Popen(stream_cmd, shell=True, stdin=subprocess.PIPE) 
camera = picamera.PiCamera(resolution=(640, 480), framerate=25) 
try: 
  now = time.strftime("%Y-%m-%d-%H:%M:%S") 
  camera.framerate = 25 
  camera.vflip = True 
  camera.hflip = True 
  camera.start_recording(stream.stdin, format='h264', bitrate = 2000000) 
  while True: 
     camera.wait_recording(1) 
except KeyboardInterrupt: 
     camera.stop_recording() 
finally: 
  camera.close() 
  stream.stdin.close() 
  stream.wait() 
  print("Camera safely shut down") 
  print("Good bye") 
Last updated on Sep 15, 2017 Published on Sep 15, 2017