• This repository has been archived on 20/Jan/2021
  • Stars
    star
    319
  • Rank 131,491 (Top 3 %)
  • Language
    Lua
  • License
    MIT License
  • Created almost 8 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

[discontinued] A webapp for publishing video to multiple streaming services at once.

Archived

Hi all. I don't enjoy working on this anymore. I'm archiving this repo, you're free to fork it.

Stop emailing me directly.

multistreamer

This is a tool for simulcasting RTMP streams to multiple services:

It allows users to add accounts for their favorite streaming services, and gives an endpoint for them to push video to. Their video stream will be relayed to multiple accounts.

It also allows for updating their stream's metadata (stream title, description, etc) from a single page, instead of logging into multiple services.

It supports integration with Discord via webhooks - it can push your stream's incoming comments/chat messages to a Discord channel, as well as updates when you've started/stopped streaming. There's also a "raw" webhook, if you want to develop your own application that responds to events. See the wiki for details.

Additionally, it provides an IRC interface, where users can read/write comments and messages in a single location. There's also a web interface for viewing and replying to comments, and a chat widget you can embed into OBS (or anything else supporting web-based sources).

Not all services support writing comments/messages from the web or IRC interfaces - please see the wiki for details on which services support which features.

Fun, unintentional side effect: you can use this to push video to your personal Facebook profile, instead of using the phone app. This isn't available via the regular Facebook web interface, as far as I know. :)

Please note: you're responsible for ensuring you're not violating each service's Terms of Service via simulcasting.

Here's some guides on installing/using:

Table of Contents

Requirements

  • OpenResty 1.13.6.1 or greater, with some extra modules:
  • ffmpeg
  • lua 5.1
  • luarocks
  • luajit (included with OpenResty)
  • redis
  • postgresql
  • a POSIX shell (bash, ash, dash, etc)

Note you specifically need OpenResty for this. I no longer support or recommend compiling a custom Nginx with the Lua module, you'll need the OpenResty distribution, which includes Lua modules like lua-resty-websocket, lua-resty-redis, lua-resty-lock, and so on.

Installation

Install with Docker

I have a Docker image available, along with a docker-compose file for quickly getting up and running. Instructions are available here: https://github.com/jprjr/docker-multistreamer

Install OpenResty with setup-openresty

I've written a script for setting up OpenResty and LuaRocks: https://github.com/jprjr/setup-openresty

This is now my preferred way for setting up OpenResty. It automatically installs build pre-requisites for a good number of distros, and installs Lua 5.1.5 in addition to LuaJIT. This allows LuaRocks to build C modules that no longer build against LuaJIT (like cjson).

To install, simply:

git clone https://github.com/jprjr/setup-openresty
cd setup-openresty
sudo ./setup-openresty
  --prefix=/opt/openresty-rtmp \
  --with-rtmp

Alternative: Install OpenResty with RTMP Manually

You'll want to install Lua 5.1.5 as well, so that LuaRocks can build older C modules. I have a patch in this repo for building liblua as a dynamic library, just in case some C module tries to link against liblua for some reason.

sudo apt-get -y install \
  libreadline-dev \
  libncurses5-dev \
  libpcre3-dev \
  libssl-dev \
  perl \
  make \
  build-essential \
  unzip \
  curl \
  git
mkdir openresty-build && cd openresty-build
curl -R -L https://openresty.org/download/openresty-1.13.6.1.tar.gz | tar xz
curl -R -L https://github.com/arut/nginx-rtmp-module/archive/v1.2.1.tar.gz | tar xz
curl -R -L http://luarocks.github.io/luarocks/releases/luarocks-2.4.3.tar.gz | tar xz
curl -R -L https://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz

cd openresty-1.13.6.1
./configure \
  --prefix=/opt/openresty-rtmp \
  --with-pcre-jit \
  --with-ipv6 \
  --add-module=../nginx-rtmp-module-1.2.1
make
sudo make install

cd ../lua-5.1.5
patch -p1 < /path/to/lua-5.1.5.patch # in this repo under misc
sed -e 's,/usr/local,/opt/openresty-rtmp,g' -i src/luaconf.h
make CFLAGS="-fPIC -O2 -Wall -DLUA_USE_LINUX" linux
sudo make INSTALL_TOP="/opt/openresty-rtmp/luajit" TO_LIB="liblua.a liblua.so" install

cd ../luarocks-2.4.3
./configure \
  --prefix=/opt/openresty-rtmp/luajit \
  --with-lua=/opt/openresty-rtmp/luajit
make build
sudo make bootstrap
sudo ln -s /opt/openresty-rtmp/luajit/bin/luarocks /opt/openresty-rtmp/bin/luarocks

Setup database and user in Postgres

Change your user/password/database names to whatever you want.

Editing pg_hba.conf for network access is outside the scope of this README file.

sudo su - postgres
psql
postgres=# create user multistreamer with password 'multistreamer';
postgres=# create database multistreamer with owner multistreamer;
postgres=# \q

Setup Redis

I'm not going to write up instructions for setting up Redis - this is more of a checklist item.

Setup Sockexec

multistreamer uses the lua-resty-exec module for managing ffmpeg processes, which requires a running instance of sockexec. The sockexec repo has instructions for installation - you can either compile from source, or just download a static binary.

Make sure you change sockexec's default timeout value. The default is pretty conservative (60 seconds). I'd recommend making it infinite (ie, sockexec -t0 /tmp/exec.sock).

Setup Authentication Server

multistreamer doesn't handle its own authentication - instead, it will make an authenticated HTTP/HTTPS request to some server and allow/deny user logins based on that.

You can make a really simple htpasswd-based server with nginx:

worker_processes 1;
error_log stderr notice;
pid logs/nginx.pid;
daemon off;

events {
  worker_connections 1024;
}

http {
  access_log off;
  server {
    listen 127.0.0.1:8080;
    root /dev/null;
    location / {
      auth_basic "default";
      auth_basic_user_file "/path/to/htpasswd/file";
      try_files $uri @auth;
    }
    location @auth {
      return 204;
    }
  }
}

I have some some projects for quickly setting up authentication servers:

Clone and setup

Clone this repo somewhere, copy the example config file, and edit it as-needed

git clone https://github.com/jprjr/multistreamer.git
cd multistreamer
cp etc/config.yaml.example /etc/multistreamer/config.yaml
# edit /etc/multistreamer/config.yaml

I've tried to comment config.yaml.example and describe what each setting does as best as I can.

One of the more important items in the config file is the networks section, right now the supported networks are:

  • rtmp - just push video to an RTMP URL
  • facebook
  • mixer
  • twitch
  • youtube

Each module has more details in the wiki.

Install Multistreamer

For either a global install or self-contained install, you'll need libyaml and its development headers installed. On Ubuntu, this is libyaml-dev:

apt-get install libyaml-dev

Global install

/opt/openresty/bin/luarocks install multistreamer

If you used the setup-openresty script from above, you'll find multistreamer at /opt/openresty/bin/multistreamer, else it depends on your particular setup.

Self-contained install

If you install modules to a folder named lua_modules, the bash script (./bin/multistreamer) setup nginx/Lua to only use that folder. So, assuming you're still in the multistreamer folder:

/opt/openresty-rtmp/bin/luarocks install --tree=lua_modules --only-deps multistreamer
# or /opt/openresty-rtmp/bin/luarocks install --tree=lua_modules --only-deps rockspecs/multistreamer-dev-1.rockspec

Using Mac OS? lapis will probably fail to install because luacrypto will fail to build. If you're using Homebrew, you can install luacrypto with:

luarocks --tree=lua_modules install luacrypto OPENSSL_DIR=/usr/local/opt/openssl
luarocks --tree=lua_modules install --only-deps multistreamer

Initialize the database

Multistreamer will automatically create tables.

Customization

Starting with Multistreamer 6.0.0, you can override CSS and images.

Just copy the static folder to local, then edit/replace files as needed.

Usage

Start the server

Once it's been setup, you can start the server with ./bin/multistreamer run

Alternative: run as systemd service

First, create a local user to run multistreamer as:

sudo useradd \
  -d /var/lib/multistreamer -m \
  -r \
  -s /usr/sbin/nologin \
  multistreamer

Then copy misc/multistreamer.service to /etc/systemd/system/multistreamer.service, and edit it as-needed - you'll probably need to change the ExecStart and ExecStartPre lines to point to wherever you cloned the git repo.

Web Usage

The web interface has two fundamental concepts: "Accounts" and "Streams."

A user is able to add Accounts to their profile (like a Twitch account or Facebook Account). The user is also able to create Streams, which generates a stream key for the user.

Once a stream is created and an account added, the user can start associating accounts with streams. An account can be used on as many different streams as the user would like.

Each stream has its own set of metadata, like a title for the broadcast, the game being played, and so on. From one page, the user can setup multiple account's metadata. Each account has their own set of fields, so the user can customize the title, description, and so-on for each service.

It's important to note that updating the web interface does not immediately change anything on the user's streaming services - it's saved for later, when the user starts pushing video.

The user can setup a stream to either start pushing video to their streaming services as soon as an incoming video stream is detected, or to wait until they've had a chance to preview the stream. Either way, multistreamer will update each account as needed just before it starts pushing video out - things like updating the Twitch's broadcast title and game, or make a new Live Video for Facebook.

Once the user stops pushing video, multistreamer will take any needed shutdown/stop actions - like ending the Facebook Live Video.

I highly recommend that users browse the Wiki - I tried to detail each section of the web interface, all the different metadata fields of the different network modules, etc.

IRC Usage

Users can connect to Multistreamer with an IRC client, and view their stream's comments and messages.

The IRC interface supports logging in with SASL PLAIN authentication, as well as by specifying a server password. Both of these methods transmit the password in plain-text, so you should place some kind of SSL terminator in front of Multistreamer, like stunnel or haproxy.

Once a user has logged into the IRC interface, they'll see a list of rooms representing all user's streams on the system. The room names use the format (username)-(streamname)

Whenever a stream goes live, an IRC bot will join the room - this bot represents an actual account being streamed to. It's username will use the format (network-name)-(account-name).

Whenever a new comment/chat/etc comes in, the bot will relay it to the room, with the format (username)-(network-name) (message)

I can post messages/comments to my streams by addressing the bots.

When the stream ends, the bots will leave the room.

Attached is a screenshot of Adium. I'm the user john, and my stream is named Awesome, so I'm in the room #john-awesome

screenshot

Reference

bin/multistreamer usage:

Here's the full list of options for multistreamer:

multistreamer [-l /path/to/lua] [-c /path/to/config.yaml] [-v] <action>
  • -l /path/to/lua - explicitly provide a path to the lua/luajit binary
  • -c /path/to/config.yaml - specify a config file, defaults to /etc/multistreamer/config.yaml
  • -v - prints the current version of multistreamer
  • <action> - can be one of
    • run - launches nginx
    • initdb - initializes the database
    • check - checks the config file, postgres, redis, etc

Migrating from Multistreamer 10 -> 11

In Multistreamer 11, I made changes to (hopefully) make Multistreamer easier to deploy.

  • You can install Multistreamer using LuaRocks
    • You can also do a self-contained install with a single luarocks call
  • config.lua is removed in favor of a YAML config-file
    • You can no longer store multiple environments in a single file, use one file per environment.
    • You can specify a config file with -c /path/to/config.yaml
    • /etc/multistreamer/config.yaml is read in by default
  • Database migrations are automatic

Version 10.2.7 can dump an existing environment's config to YAML, so to migrate:

git checkout 10.2.7
./bin/multistreamer -e (environment) initdb # prep db for auto-migrations
./bin/multistreamer -e (environment) dump_yaml > config.yaml
# checkout config.yaml, make sure everything makes sense
mkdir /etc/multistreamer
cp config.yaml /etc/multistreamer/config.yaml
luarocks --tree=lua_modules install --only-deps rockspecs/multistreamer-dev-1.rockspec
# or use luarocks --tree=lua_modules install --only-deps multistreamer to pull from luarocks

Roadmap

New features I'd like to work on:

  • More networks!

Versioning

This project uses semantic versioning: MAJOR.MINOR.PATCH

A change to the major release number means the user must make a configuration change, running a database migration, etc. Upgrading to a new major release without taking action will result in a failure.

A change to the minor release number means some new feature is available, but the user doesn't necessarily need to take action (though the new feature might be disabled until they make a config change etc).

A change to the patch number means I've made some small bug fix.

All releases will include notes with details on migrating databases, updating the config, and so on.

Licensing

This project is licensed under the MIT license, see the file LICENSE for more details. This license applies to all files, except the following exceptions:

This project includes a copy of Pure.css (static/css/pure-min.css), which is licensed under a BSD-style license. Pure.css license is available as LICENSE-purecss.

This project includes a copy of commonmark.js (static/js/commonmark.min.js), which is licensed under a BSD-style license. The commonmark.js license is available as LICENSE-commonmark-js.

This project includes a copy of clipboard.js (static/js/clipboard.min.js), which is licensed under an MIT-style license. The clipboard.js license is available as LICENSE-clipboard-js.

This project includes a copy of Pixabay's "JavaScript-autoComplete" library (static/css/auto-complete.css and static/js/auto-complete.min.js), which is licensed under an MIT-style license. The license is available as LICENSE-autocomplete-js.

This project includes a copy of balloon.css (static/css/balloon.css), which is licensed under an MIT-style license. The balloon.css licence is available as LICENSE-balloon-css.

This project includes a copy of zenscroll (static/js/zenscroll-min.js), which is public-domain code. The license for zenscroll is availble as LICENSE-zenscroll.

The network modules for Facebook, Twitch, and YouTube include embedded SVG icons from simpleicons.org. These icons are in the public domain see https://github.com/danleech/simple-icons/blob/gh-pages/LICENSE.md. I'll be honest, I'm not sure how trademark law applies here (but I'm sure it does), so I feel obligated to mention that all trademarked images are property of their respective companies.

The network module for Mixer uses an embedded SVG icon from mixer-branding-kit, it is property of Mixer.

More Repositories

1

docker-multistreamer

Dockerized multistreamer
Shell
92
star
2

internet-radio-streams

A listing of free internet radio streams, for use in music-oriented projects
PLSQL
70
star
3

lua-resty-exec

Run external programs in OpenResty without spawning a shell or blocking
Lua
59
star
4

docker-ubuntu-stack

My hip lil' Ubuntu stack of Docker images, w/ s6 init and logstash-forwarder installed.
Shell
52
star
5

docker-rainloop

A docker image with the Rainloop mail client installed
Nginx
45
star
6

asioconfig

A small program for pulling up ASIO device control panels
C++
29
star
7

docker-tinynode

A small buildroot-based image for Docker, with NodeJS installed. Clocks in around 30MB.
Shell
27
star
8

sockexec

A small daemon for running programs via UNIX socket
C
27
star
9

luasodium

Lua bindings to libsodium, includes regular and FFI variants
Lua
25
star
10

miniflac

Single-file FLAC decoder with a push-style API
C
21
star
11

docker-misc

A repo for various things I'm trying out in Docker
Shell
21
star
12

lua-crypt

A crypt(3)-style module for Lua. Brings its own implementations, entirely independent of your local libc
C
16
star
13

docker-archlinux

Shell
12
star
14

multistreamer-installer

A script for installing Multistreamer
Shell
9
star
15

snes_spc

blargg's snes_spc library
C++
7
star
16

setup-openresty

A script for installing OpenResty + LuaRocks
Shell
7
star
17

spc2wav

Converts SPC to WAV using Blargg's snes_spc library
C
6
star
18

lua-resty-mpd

A client library for the Music Player Daemon, compatible with OpenResty, cqueues, and Luasocket
Lua
6
star
19

docker-arch-php

Shell
5
star
20

mpd-visualizer

A tool to generate video from Music Player Daemon
C
5
star
21

ldap-auth-server

An LDAP backend for nginx's auth_request module
Lua
5
star
22

icecast-hls

A tool to take Icecast streams and re-encode into HLS
C
5
star
23

docker-debian-nginx

Shell
4
star
24

minifmp4

A single-header library for muxing fragmented mp4 files
C
4
star
25

lua-music-visualizer

C
4
star
26

luaflac

Lua bindings to libflac
C
4
star
27

postgres-auth-server

A postgres based auth server for nginx auth_request
Lua
4
star
28

base16-connectbot

4
star
29

iup-build

A makefile for cross-compiling the IUP/CD/IM toolkits
Makefile
4
star
30

netstring.lua

An implementation of DJB's netstring encoding format for Lua/LuaJIT.
Lua
4
star
31

technicallyflac

A single-file FLAC encoding library
C
3
star
32

luaogg

Lua bindings to libogg
C
3
star
33

luawav

Lua library for reading and writing wav files with dr_wav
C
3
star
34

mkscript

Perl
2
star
35

mailadmin

Perl
2
star
36

luadbi-async

LuaDBI + async
C
2
star
37

lualame

Bindings to libmp3lame from lua
C
2
star
38

docker-opensmtpd

Shell
2
star
39

libid666

C
2
star
40

libnezplug

C
2
star
41

lua-lecho

A small lua/luajit module for enabling/disabling terminal echo
C
2
star
42

lua-whereami

Lua module for finding your executable's path.
C
2
star
43

srt-janus

A tool for relaying SRT video streams into Janus videorooms
Go
2
star
44

docker-seafile

Shell
1
star
45

lua-demo-module

A dummy C module that works with FFI and the traditional C api
Lua
1
star
46

luaminiflac

C
1
star
47

mpd-with-chiptunes-like-foobar2000

Perl
1
star
48

docker-osxcross

Dockerfile
1
star
49

file_extractor

C
1
star
50

docker-arch-pydio

Shell
1
star
51

miniogg

C
1
star
52

bigint

Single-header C library for big integer arithmetic
C
1
star
53

docker-metronome

Shell
1
star
54

ldapjs-sql-old

JavaScript
1
star
55

ldapjs-sql

JavaScript
1
star
56

luaopus

C
1
star
57

redis-auth-server

Lua
1
star
58

pidgin

Pidgin with some patches applied
C
1
star
59

idgaf

When you wanna run a background process and just don't care
Shell
1
star
60

docker-tinyfs

A small buildroot-based image for Docker
Shell
1
star
61

proc

A small cross-platform library for spawning processes
C
1
star
62

glibc-cross-make

Build glibc-based relocatable cross-compilers
Makefile
1
star
63

nsfe-editor

A small tool for changing the tags in an NSFE file.
Lua
1
star
64

docker-sabotagelinux-stage0

A repo for building sabotage linux as a docker image
Shell
1
star
65

dotfiles

Shell
1
star
66

docker-dbmail

Shell
1
star
67

gsf2wav

CLI application for converting GSF files to WAV
C
1
star
68

gbs2wav

Converts a GBS into a series of WAV files with ID3 tags
C
1
star