Hand tools and fabrication machines
Originally this project spawned from the idea of recording output from a Canon EOS camera to a Raspberry Pi. The hurtle to overcome was finding out how to decently input video into the Raspberry Pi. So after roaming the halls of Google for a few hours, I stumbled across this amazing HDMI to CSI-2 adapter by Auvidea. Since HD video requires too much bandwidth to transfer through the Raspberry PI's USB 2.0 offerings, it uses the CSI-2 camera interface instead to capture any video from an HDMI source. I though this was such a nifty little device, that I immediately thought of dozens of other use cases than capturing video from a camera. One of those ideas was to use it for easily streaming game consoles to Twitch, which is what this project is about.
For this project, I'm using a Raspberry Pi Zero W. Mine is one with headers, but headers are not required. As with every Pi project, the first step is setting it up. I'm sure most of you have done it so many times, but for propriety sake, here are the steps again.
Start with an 8gb or higher SD card, load it into your computer and download the newest Raspbian OS. Then use Etcher to burn it to your SD card. When it's done, you can remove it from your computer and insert it into the SD card slot on the Pi. Then plug in a monitor, keyboard, mouse, and finally a power cable.
When you see the Desktop, the first thing you want to do is connect to your Wifi, so click on the Wifi icon in the upper right corner and select your Wireless Name and enter the password if there is one. Then right click on the same Wifi icon and select "Wired and Wireless Network setting" and enter in an unused static IP address for your Pi so that we can connect to it later.
Finally, you want to click on the main menu icon and select "Preferences > Raspberry Pi Configuration". Click on the "Interfaces" tab and make sure both Camera and SSH are enabled. Then save and reboot.
The Auvidea website offers several different HDMI to CSI-2 bridges, but there are only two that you'd be interested in if you're wanting to do what this project does:
- B101 - Intended for Raspberry Pi 3 series - $86
- B102 - Intended for Raspberry Pi Zero series -$98
And here's a link to their technical reference manual. Are they expensive? yes. But HD streaming video capture cards are more expensive. All you have to do is connect it to the CSI-2 camera port on the Raspberry Pi. If you've used a Raspberry Pi Camera board, you already know how to do this.
Both versions support HDMI audio, but the audio is split out to the GPIO pins. Here's a good post on how to get it set up, and you can find the pinouts on the HDMI bridge using the technical reference manual I linked to above. However, I ended up abandoning the audio input for now, primarily because I may end up using a USB microphone for audio output instead.
To connect the adapter, you basically just use it like you would a Raspberry Pi Camera board. The simplest way to test it out is by connecting an HDMI source and then using Raspivid to capture 10 seconds of video.
raspivid -o video.h264 -t 1000
At this point, you could even stream the HDMI source to Twitch! Assuming you have a Twitch account, and have copied your Twitch stream key, just install AVconv (or FFMpeg, but it it takes 10x longer) and use the code below to stream to Twitch!
sudo apt-get update sudo apt-get install libav-tools raspivid -t 0 -fps 25 -hf -b 2000000 -o - | avconv -i - -vcodec copy -an -r 30 -g 30 -bufsize 2000000 -pix_fmt yuv420p -f flv rtmp://live.justin.tv/app/ENTER_YOUR_STREAM_KEY_HERE
If all goes well, you should see the stream on your Twitch page!Adding Buttons and Lights
If all you wanted to have was the basics of streaming to Twitch using a Raspberry Pi, then you could probably stop here, but I wanted to take it further and turn this concept into a Twitch streaming box! I mean, Raspberry Pi's are capable of so much more, so why not?
The idea is to have a box with a button on top that when you press it, it immediately starts streaming to Twitch. I decided to go with a 16mm light up latching switch from Adafruit.
Then I also thought it'd be cool to have a backlit Twitch logo that activates when video is streaming. So I got two LED backlight panels from Adafruit as well.
So now let's connect it all up to the Raspberry Pi. As you can see in the image above, since the light panels are LED's, I soldered a 330ohm resistor to each of them.
Then I grabbed a breadboard, some jumper wires and started connecting everything up. Here's a diagram of what I ended up with
Without a program to tell it what to do, the buttons and lights will just sit there and not do anything. So let's make a program called "twitch_stream.py" (also available on Github) that enables a Twitch stream whenever we press the button, and then turns on the LED backlights. Then when the button is pressed again, everything turns off.
#!/usr/bin/env python3 import subprocess import picamera import time import RPi.GPIO as GPIO #SETUP GPIO CONTROLS GPIO.setmode(GPIO.BCM) #BUTTON GPIO GPIO.setup(14, GPIO.IN, pull_up_down=GPIO.PUD_UP) #BUTTON LED GPIO GPIO.setup(17, GPIO.OUT) #LIGHT PANEL 1 GPIO.setup(23, GPIO.OUT) #LIGHT PANEL 2 GPIO.setup(25, GPIO.OUT) #SETUP STREAMING COMMAND VARIABLES TWITCH = "rtmp://live.justin.tv/app/" KEY= "ENTER YOUR PRIVATE KEY HERE" #todo: clean up command to make stream faster stream_cmd = '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 ' + TWITCH + KEY stream_pipe = subprocess.Popen(stream_cmd, shell=True, stdin=subprocess.PIPE) #SETUP CAMERA VARIABLES camera = picamera.PiCamera(resolution=(1080, 720), framerate=25) #CREATE VARIABLE TO SIGNIFY WHEN STREAMING start_stream = 0 try: #MAKE SURE ALL LED'S ARE OFF GPIO.output(17, False) GPIO.output(23, False) GPIO.output(25, False) while True: #SET VARIABLE FOR BUTTON input_state = GPIO.input(14) #IF BUTTON IS TRIGGERED AND NOT STREAMING, THEN START STREAM if input_state == False and start_stream == 0: start_stream = 1 camera.start_recording(stream_pipe.stdin, format='h264', bitrate = 2000000) GPIO.output(17, True) GPIO.output(23, True) GPIO.output(25, True) print('recording started') time.sleep(0.2) #IF BUTTON IS TREGGERED AND STREAMING, CONTINUE STREAM elif input_state == False and start_stream == 1: camera.wait_recording(1) #IF BUTTON IS NOT TRIGGERED AND STREAMING, STOP STREAM elif input_state == True and start_stream ==1: start_stream = 0 camera.stop_recording() print("stopped recording") time.sleep(0.2) #IF BUTTON IS NOT TRIGGERED AND NOT STREAMING, TURN LED'S OFF elif input_state == True and start_stream == 0: GPIO.output(17, False) GPIO.output(23, False) GPIO.output(25, False) time.sleep(0.2) print('awaiting input') #ON KEYBOARD INTERRUPT, CLOSE CAMERA, STREAM AND CLEAN UP GPIO except KeyboardInterrupt: camera.close() print("keyboard interrupt") finally: stream_pipe.stdin.close() stream_pipe.wait() GPIO.cleanup() print("Camera safely shut down") print("Good bye")
Where it says "Enter your private key here", that is where you want to enter your Twitch streaming key. Once that's done, save it, plug in an HDMI source (like a gaming console) into the HDMI port and run it with this command:
sudo python3 twitch_stream.py
If everything went as it should, you should be able to press the button and see the button and LED panels light up. And, you should be able to visit your Twitch dashboard and see the video input streaming.
Then if you press the button again, the stream stops and the lights turn off! Assuming everything functioned accordingly, the next step for the program is to make it executable and it to the Pi's rc.local file so it autostarts.
Putting It All Together
sudo chmod +x twitch_stream.py sudo nano etc/rc.local #add this to the end of the file sudo python3 /home/pi/twitch_stream.py &
With all the components working, all that's left to do is to put it all together in a nice neat little package. I ended up taking measurements of all the different components and importing them into Tinkercad where I designed a case to house them all.
After printing the design out on a 3D printer, I began hot-gluing everything into place. I glued the backlight panels on the lid behind the Twitch logo, and I hot glued a micro-usb extension cable from the Pi to an outlet on the side of the casing.
In order to connect the HDMI output to the Twitch-O-Matic and a TV, you'll need an HDMI splitter. These are nomrally less than $20 on Amazon. With everything powered up and connected, whenever you want to start streaming your game to Twitch, just push the button!