├── Dockerfile ├── Dockerfile-stunnel ├── LICENSE ├── README.md ├── conf ├── nginx.conf └── stunnel.conf └── docker-compose.yml /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | RUN apt update && apt dist-upgrade -y && DEBIAN_FRONTEND=noninteractive apt install -y build-essential git ffmpeg libpcre3 libpcre3-dev libssl-dev zlib1g-dev perl libperl-dev libgd3 libgd-dev libgeoip1 libgeoip-dev geoip-bin libxml2 libxml2-dev libxslt1.1 libxslt1-dev ffmpeg 4 | 5 | WORKDIR /app 6 | RUN git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git 7 | 8 | ADD https://nginx.org/download/nginx-1.19.0.tar.gz /app/ 9 | RUN tar -zxvf nginx-1.19.0.tar.gz && rm nginx-1.19.0.tar.gz 10 | RUN cd nginx-1.19.0 && \ 11 | ./configure --add-module=../nginx-rtmp-module \ 12 | --prefix=/etc/nginx \ 13 | --sbin-path=/usr/sbin/nginx \ 14 | --modules-path=/usr/lib/nginx/modules \ 15 | --conf-path=/etc/nginx/nginx.conf \ 16 | --error-log-path=/var/log/nginx/error.log \ 17 | --pid-path=/var/run/nginx.pid \ 18 | --lock-path=/var/run/nginx.lock \ 19 | --user=www-data \ 20 | --group=www-data \ 21 | --build=Ubuntu \ 22 | --with-select_module \ 23 | --with-poll_module \ 24 | --with-threads \ 25 | --with-file-aio \ 26 | --with-http_ssl_module \ 27 | --with-http_v2_module \ 28 | --with-http_realip_module \ 29 | --with-http_addition_module \ 30 | --with-http_xslt_module=dynamic \ 31 | --with-http_image_filter_module=dynamic \ 32 | --with-http_geoip_module=dynamic \ 33 | --with-http_sub_module \ 34 | --with-http_dav_module \ 35 | --with-http_flv_module \ 36 | --with-http_mp4_module \ 37 | --with-http_gunzip_module \ 38 | --with-http_gzip_static_module \ 39 | --with-http_auth_request_module \ 40 | --with-http_random_index_module \ 41 | --with-http_secure_link_module \ 42 | --with-http_degradation_module \ 43 | --with-http_slice_module \ 44 | --with-http_stub_status_module \ 45 | --with-http_perl_module=dynamic \ 46 | --with-perl_modules_path=/usr/share/perl/5.26.1 \ 47 | --with-perl=/usr/bin/perl \ 48 | --http-log-path=/var/log/nginx/access.log \ 49 | --http-client-body-temp-path=/var/cache/nginx/client_temp \ 50 | --http-proxy-temp-path=/var/cache/nginx/proxy_temp \ 51 | --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \ 52 | --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \ 53 | --http-scgi-temp-path=/var/cache/nginx/scgi_temp \ 54 | --with-mail=dynamic \ 55 | --with-mail_ssl_module \ 56 | --with-stream=dynamic \ 57 | --with-stream_ssl_module \ 58 | --with-stream_realip_module \ 59 | --with-stream_geoip_module=dynamic \ 60 | --with-stream_ssl_preread_module \ 61 | --with-compat \ 62 | --with-pcre-jit \ 63 | --with-openssl-opt=no-nextprotoneg \ 64 | && \ 65 | make -j $(nproc) && \ 66 | make install && mkdir /var/cache/nginx 67 | 68 | CMD ["nginx", "-g", "daemon off;"] 69 | -------------------------------------------------------------------------------- /Dockerfile-stunnel: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN apt-get update -y 4 | RUN apt-get upgrade -y 5 | RUN apt-get install stunnel4 -y 6 | 7 | COPY ./conf/stunnel.conf /etc/stunnel 8 | 9 | WORKDIR /etc/stunnel 10 | 11 | CMD ["/usr/bin/stunnel"] 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Pieter Maes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nginx rtmp multistream 2 | 3 | ## TL;DR 4 | Edit conf/nginx.conf 5 | Then run the following commands: 6 | ```sh 7 | docker-compose build 8 | docker-compose up -d 9 | ``` 10 | RTMP server now available push to rtmp://server-hostname/live 11 | 12 | ## About 13 | This Docker image is for having a central point to stream to multiple streaming providers at once. 14 | Providers included in this config are: Twitch, Youtube, Facebook 15 | Instagram is not properly supported due to multiple reasons, one is they don't official support this.. 16 | 17 | This Dockerfile will let you run nginx with the compiled rtmp module from https://github.com/sergey-dryabzhinsky/nginx-rtmp-module 18 | 19 | This rtmp module doesn't properly support pushing to rtmps however, so we so a little magic: 20 | with docker-compose we also spin up a [stunnel](https://www.stunnel.org/) 21 | this stunnel makes it possible to translate traffic to rtmps for the module. 22 | 23 | ## Prerequisites 24 | You will need to have both [docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/install/) installed on your machine. 25 | Have at least 4 cores so transcoding doesn't take your entire machine, so a Raspberry pi is __not__ recommended. 26 | 27 | ## Config 28 | You will need to edit the nginx.conf file in the conf directory. 29 | 30 | update the following things: 31 | * ALLOWED_BROADCAST_IP : The IP address from where the stream will be pushed to this instance. 32 | * TWITCH_KEY : The twitch stream key 33 | * FACEBOOK_KEY : The Facebook stream key 34 | * INSTAGRAM_KEY : The instagram stream key (optional, this is disabled by default for now in the 'live' app) 35 | * YOUTUBE_KEY : The yourube stream key 36 | 37 | You can disable any of these by commenting out either their 'push' or 'exec' in the live application. 38 | 39 | ## Usage 40 | First we build the docker image 41 | ```sh 42 | docker-compose build 43 | ``` 44 | Then make sure you have updated the conf/nginx.conf 45 | ```sh 46 | docker-compose up -d 47 | ``` 48 | 49 | ## Notes 50 | Check to make sure the streaming push links are still up to date with what the platform gives you.. 51 | it usually doesn't change, but do verify 52 | for facebook/instagram also check the conf/stunnel.conf 53 | 54 | If you want to experiment with instagram, be free to figure out the right encoder settings and a way to get the rtmp key 55 | if you find a clean solution and want to share back, I'll accept it. 56 | 57 | License 58 | ---- 59 | 60 | MIT 61 | -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | 3 | 4 | events { 5 | worker_connections 1024; 6 | } 7 | 8 | rtmp { 9 | server { 10 | listen 1935; 11 | chunk_size 4096; 12 | 13 | application live { 14 | live on; 15 | record off; 16 | 17 | allow publish {{ALLOWED_BROADCAST_IP}}; 18 | deny publish all; 19 | allow play all; 20 | 21 | push rtmp://127.0.0.1:1935/twitch; 22 | push rtmp://127.0.0.1:1935/youtube; 23 | exec ffmpeg -i rtmp://127.0.0.1:1935/live/$name -threads 4 -vcodec h264 -pix_fmt yuv420p -preset medium -r 30 -g 60 -b:v 3500k -bufsize 400000 -nal-hrd cbr -acodec copy -s 1280x720 -f flv rtmp://127.0.0.1:1935/transcoded; 24 | # Instagram needs different transcoding.. 25 | #push rtmp://127.0.0.1:1935/instagram; 26 | } 27 | 28 | application twitch { 29 | live on; 30 | record off; 31 | allow publish 127.0.0.1; 32 | deny publish all; 33 | 34 | push rtmp://live-cdg.twitch.tv/app/{{TWITCH_KEY}}; 35 | } 36 | 37 | application transcoded { 38 | live on; 39 | record off; 40 | allow publish 127.0.0.1; 41 | deny publish all; 42 | push rtmp://127.0.0.1:1935/facebook; 43 | } 44 | 45 | application facebook { 46 | live on; 47 | record off; 48 | allow publish 127.0.0.1; 49 | deny publish all; 50 | push rtmp://stunnel:19350/rtmp/{{FACEBOOK_KEY}}; 51 | } 52 | 53 | application instagram { 54 | live on; 55 | record off; 56 | allow publish 127.0.0.1; 57 | deny publish all; 58 | 59 | push rtmp://stunnel:19351/rtmp/{{INSTAGRAM_KEY}}; 60 | } 61 | 62 | application youtube { 63 | live on; 64 | record off; 65 | allow publish 127.0.0.1; 66 | deny publish all; 67 | push rtmp://a.rtmp.youtube.com/live2/{{YOUTUBE_KEY}}; 68 | } 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /conf/stunnel.conf: -------------------------------------------------------------------------------- 1 | setuid = stunnel4 2 | setgid = stunnel4 3 | pid=/tmp/stunnel.pid 4 | output = /var/log/stunnel4/stunnel.log 5 | ;include = /etc/stunnel/conf.d 6 | foreground=yes 7 | 8 | [fb-live] 9 | client = yes 10 | accept = 0.0.0.0:19350 11 | connect = live-api-s.facebook.com:443 12 | verifyChain = no 13 | [insta-live] 14 | client = yes 15 | accept = 0.0.0.0:19351 16 | connect = live-upload.instagram.com:443 17 | verifyChain = no 18 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | 3 | services: 4 | nginx-rtmp: 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | volumes: 9 | - ./conf/nginx.conf:/etc/nginx/nginx.conf 10 | ports: 11 | - 1935:1935 12 | depends_on: 13 | - stunnel 14 | stunnel: 15 | build: 16 | context: . 17 | dockerfile: Dockerfile-stunnel 18 | --------------------------------------------------------------------------------