Streaming from OBS to RTMP server for recording

February 2020 ยท 3 minute read

At $DAYJOB, I wanted to be able to share a recording of my workflow. My ISP is pretty awful, though, so uploading a recording with decent quality can take an enormous amount of time. My idea was to stream this somewhere that would save it for me - if it uploads as it goes, it’s much less effort to share than uploading a 500MB file.

I know that services like Twitch can save a copy of your stream for later viewing, but I don’t want to stream to the public. I’m sure that there’s some option to make a video private, but I don’t really want to have to get an account somewhere only to find that I can’t control the content.

I’ve used OBS before and decided to use it again. A quick search for “OBS custom server” let me know that what I was doing was possible and that I needed an rtmp server that would receive the stream.

In OBS’ Settings > Stream, you can select Custom and fill in your own server. I filled it with rtmp://ip-of-one-of-my-servers.

Server Options

There’s a few different RTMP servers on offer, but only two that are open source:

I couldn’t find much about crtmpserver, though, and it was not in any base package sets or the AUR, so I went with nginx.

Making it needlessly complex

I don’t typically run bare services when I can avoid it, so of course I stuck this setup in a container.

FROM debian:buster

RUN apt-get update && \
	apt-get -y install nginx libnginx-mod-rtmp ffmpeg

EXPOSE 1935
CMD ["nginx", "-g", "daemon off;"]

My nginx.conf is pretty simple:

load_module modules/ngx_rtmp_module.so;
worker_processes auto;
rtmp_auto_push on;
events {}

rtmp {
    server {
        listen 1935;
	ping 30s;

        chunk_size 4096;

        application live {
            live on;

            record all;
            record_path /opt/save;
            record_suffix -%d-%b-%y-%T.flv;

            exec_record_done ffmpeg -y -i $path -acodec libmp3lame -ar 44100 -ac 1 -vcodec libx264 $dirname/$basename.mp4;
        }
    }
}

According to the documentation for nginx-rtmp, you can set up authentication for this. Since this is private, I just have it firewalled to my network.

Just so I can be slightly lazy, I made a docker-compose.yml file:

version: '3'

services:
  nginx-rtmp:
    build: .
    ports:
      - 1935:1935
    volumes:
      - /srv/video:/opt/save
      - ./nginx.conf:/etc/nginx/nginx.conf

Run podman-compose up -d and it’s alive.

Head back to OBS Settings > Stream and use rtmp://ip:1935/live. Set the stream key to anything - nginx-rtmp will use that key as part of the filename for the saved flv and mp4.

Fin

Once a stream has completed, exec_record_done executes ffmpeg and converts the flv to mp4. I push that to my storage server and call it a day.