I love doing things the hard way, and I wanted a solution for streaming my PoE RTMP Reolink cameras remotely which I have set up as a security solution. It had to be self-contained and low power, and require minimal configuration.
The Hardware
For my Hardware I chose a Banana Pi R2 with 1GB RAM and SATA + PCIe slots, running OpenWRT. I chose this over a more standard Linux box because of the following reasons:
- It is low power (I intend to run the setup on solar)
- It can accept an LTE modem for remote access
- I can plug in an SSD or HDD for recording video to
- It has a built-in ethernet switch and WiFi capability
For my cameras I am using the Reolink (TBD) as these are low-cost and don’t require any kind of cloud subscription nonsense.
The Software
I chose OpenWRT over Linux as it provides a great networking / firewalling solution, which means I can easily wall off the cameras from the internet so they can’t communicate out and join the Internet of Shit.
With the Banana Pi, it is able to run docker and handle quite a bit of throughput.
To configure everything I am using Ansible, as it provides me with a repeatable script to set everything up again if I was to lose my hardware, and it serves as valuable documentation as to what I even did on the device. I won’t be covering the Ansible script here, but I can highly recommend it despite the high learning curve!
To actually stream the video, I’m using a little-known plugin to Nginx (nginx-rtmp) that adds native RTMP support and translates it to HLS/MPEG-TS (the same tech used for Twitch and other real-time streaming platforms!)
Unfortunately this plugin has to be compiled from source, which is where Docker comes into play - Docker provides a repeatable and self-contained environment for building things from scratch.
Architecture
TODO.
Cameras -> PoE Switch -> Banana Pi -> Internal LAN -> Docker -> NGINX-RTMP
NGINX-RTMP -> Docker -> WAN -> My Phone
Compiling Nginx-RTMP
- name: Copy docker script
become: yes
copy:
src: docker/nginx-rtmp.dockerfile
dest: ~/nginx-rtmp/Dockerfile
mode: 'u=rw,g=rw,o=r'
when: not result.images
- name: Build docker image
become: yes
docker_image:
name: nginx-rtmp
source: build
build:
path: ~/nginx-rtmp
dockerfile: Dockerfile
#dockerfile: nginx-rtmp.dockerfile
args:
ENABLED_MODULES: 'rtmp'
state: present