theshoregroup / digital-signage

A powerful, extensible digital signage solution by The Shore Group, written in ReactJS, wrapped in Electron for some system-level integration not possible with a PWA, and styled with TailwindCSS.
digital-signage-smoky.vercel.app
MIT License
11 stars 3 forks source link

Add HLS video stream #43

Open limegorilla opened 2 years ago

limegorilla commented 2 years ago

This would allow a local HLS video stream to be displayed on Digital signage. Used to display a fire stick/other HDMI source.

Source is plugged into a HDMI > USB adapter and sent out over OBS > NGINX reverse proxy as a DASH stream.

Why?

Digital signage is great and all, but our company is pretty happy for people to have various TV channels/shows on over the day. We explored embedding a YouTube stream inside the app, but the only consistently streaming news source would be standard Sky News - slightly too depressing for our tastes.

Instead, we're going to be exposing a physical HDMI port to a local HLS stream, allowing any local client (with the proper auth) to grab the stream.

This current setup is a bit convoluted (TODO: simplify the reverse proxy) but once in place its pretty plug-n'-play

limegorilla commented 2 years ago

Overview

So I have the firestick working inside OBS so it's now time to get this working over the network.

My Box's network details are

192.168.50.105
b0:a4:60:**:**:**
hove-media

This same box will be currently also serving as the reverse proxy.

This system is somewhat decent - it's a SFF mini PC with a mobile RDNA CPU (I refuse to use APU) however this is possibly at its limit as even just locally streaming this is causing some frame drops. It's possible that this could be solved with dual-channel ram or newer, faster storage, but this works for one office.

limegorilla commented 2 years ago

I'll be following this guide: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-video-streaming-server-using-nginx-rtmp-on-ubuntu-20-04

limegorilla commented 2 years ago

I'll be using a version of NGINX with RTMP support to make this happen. It's installable via

sudo apt update
sudo apt install libnginx-mod-rtmp
limegorilla commented 2 years ago

Setting up the server

My /etc/nginx/nginx.conf file looks like this after the tutorial

rtmp {
        server {
                listen 1935;
                chunk_size 4096;
                allow publish 127.0.0.1;
                deny publish all;

                application live {
                        live on;
                        record off;

                        hls on;
                        hls_path /var/www/html/stream/hls;
                        hls_fragment 3;

                        dash on;
                        dash_path /var/www/html/stream/dash;
                }
        }
}

To enable my firewall, I've allowed the following through ufw

sudo ufw allow 1935/tcp
limegorilla commented 2 years ago

Setting up OBS

This is issue is less concerned with OBS as it's more about getting the server in place, but a quick overview.

My OBS Source is actually the same device that is running nginx - in future I may actually run the server inside our private cloud on a VM - I have visions of each office having it's own source, but that is beyond the scope of this issue. See #44

Essentially, you grab your sources together as you wish, and then set up a custom stream inside OBS' settings.

Streaming Service: Custom Server: rtmp://<domain>/live Stream Key: <streamId>

So for example:

Server: rtmp://hove-media-server.local/live StreamKey: hoveMediaStream

To explain these:

limegorilla commented 2 years ago

Monitoring

I also used the built in monitoring file included with the nginx package - the guide will tell you it needs unzipping - you don't

Instead, you'll just need to copy it (which will need to be run as root) sudo cp /usr/share/doc/libnginx-mod-rtmp/examples/stat.xsl /var/www/html/rtmp/stat.xsl

You'll then need to configure this site - create a new document at /etc/nginx/sites-available/rtmp Note: If this is a dedicated media server, I would reccomend changing the server entry below to 80 rather than 8080 - this is done this way to minimise risk of affecting other services running on your server, but means that you will need to type in the port each time you need to access the server (http://<domain>/stat instead of http://<domain>:8080/stat)

server {
    listen 8080;
    server_name  localhost;

    # rtmp stat
    location /stat {
        rtmp_stat all;
        rtmp_stat_stylesheet stat.xsl;
    }
    location /stat.xsl {
        root /var/www/html/rtmp;
    }

    # rtmp control
    location /control {
        rtmp_control all;
    }
}