Middleware for OvenMediaEngine to create a meeting or restream production experience
Find a file
Trysdyn Black c1aaac4923 Only sort frames when it's safe and pertinent
- Don't sort if a player is fullscreened. Fixes #12
- Force a sort when exiting fullscreen
- Only sort when the player list changes, not any resize
2025-03-18 23:24:45 -07:00
assets Only sort frames when it's safe and pertinent 2025-03-18 23:24:45 -07:00
example Add access key gating to incoming streams 2025-02-16 17:06:35 -08:00
template Report cached stream list in management 2025-03-07 22:10:42 -08:00
.gitignore Initial commit 2024-12-20 22:44:39 +00:00
admission.py Don't de-dupe additions to live stream list 2025-03-06 21:01:44 -08:00
config.py Add access key gating to incoming streams 2025-02-16 17:06:35 -08:00
LICENSE.md Add License 2024-12-20 17:31:43 -08:00
main.py Use the same API handle across the entire app 2025-03-06 20:26:11 -08:00
management.py Report cached stream list in management 2025-03-07 22:10:42 -08:00
ovenapi.py Use the same API handle across the entire app 2025-03-06 20:26:11 -08:00
pyproject.toml Reinitialize repo to remove private data 2024-12-20 14:45:49 -08:00
README.md Add an actual explanation of what this does 2025-02-23 16:55:06 -08:00
status.py Don't de-dupe additions to live stream list 2025-03-06 21:01:44 -08:00
viewer.py Use the same API handle across the entire app 2025-03-06 20:26:11 -08:00

ovenemprex

OvenMediaEngine management middleware

Screenshot

A sample two-stream view of OvenEmprex's default interface

What Is It?

OvenEmprex presents a set of web pages to allow convenient simple display of RTMP and WebRTC streams ingested in an OvenMediaEngine server in various forms. The most prominent display is a mode closely resembling screen share or meeting software, which automatically populates each stream into an arranged grid. If you've done multi-user screen or video shares with Discord, Webex, or similar, this view will feel pretty familiar.

Additional display modes allow for dedicated views of individual streams, easily populating and configuring Javascript WebRTC players to display streams on your OvenMediaEngine Server, without the need to know any code.

OvenEmprex's goal is to provide a dual purpose frontend for OvenMediaEngine for...

  • Communities that want to have their own video share system, so as not to rely on more centralized options like Discord, Webex, etc
  • Event production experts who want an easy to use pipeline for receiving live streams and mixing them into a video production project for remote podcasting, talk shows, online video game competitions, etc

OvenEmprex also handles additional authentication and management of an OvenMediaEngine server. Tooling provides a convenient management webpage to expose API-only features such as forced disconnections, and (eventually) recording to server disk. This management interface also exposes the ability to allow/disallow specific stream keys and IP addresses to allow a server admin to better moderate a video stream server.

Finally, management tools provides some limited introspection into stream quality and health to troubleshoot streaming software or network problems.

OvenEmprex and OvenMediaEngine are the software tools powering the Kusogrande video game tournament. They're used to collate and centralize player livestreams into one place for the host to capture, manipulate, and mix into a single view for broadcast to Twitch.

Requirements

This project tries to be pretty lean. Requirements should be roughly...

  • OvenMediaEngine 0.10.30 or greater
  • Python 3.8 or greater
  • python-cherrypy
  • python-requests
  • python-mako

Archlinux packages for the above should get you rolling immediately. Otherwise setting up a virtualenv is recommended.

Setup

This is a thousand mile up view to get you running quickly. You should review the rest of the README (including the security considerations below) before actually putting anything here to use.

  1. Install and configure Ovenmediaengine. Check the example/ dir for a Server.xml to start with. The following components are required:
    1. WebRTC publishing
    2. The API enabled with a user/password set
    3. Some number of applications
    4. Applications configured with a producer webhook of http://localhost:8080/admission
  2. Extract or clone this repository somewhere
  3. Configure your HTTP daemon/proxy/etc to proxy HTTPS to http://localhost:8080; check the Security section below for further guidance
  4. Set up environment variables to your liking. The OvenMediaEngine API key and password are mandatory; see Configuration below
  5. Start the management engine with either python3 main.py or a systemd unit as noted in examples/

Usage

By default this provides a few things:

  • https://<domain>/<appname> will provide a "Discord like" interface to every stream live in the current app
  • https://<domain>/<appname>/<streamname> will display only that stream
  • https://<domain>/<management> will, if configured, display a management interface to allow basic stream management

Any stream is valid, but you must have a proper application configured in OvenMediaEngine to both receive streams and present them. As configured in the examples, the video server will push source videos back out, without re-encoding. This means it's extremely light, but your video pushing software must be configured a certain way. OvenMediaEngine recommends...

  • 0 bframes (or your video will slideshow)
  • 1s keyframe interval
  • zerolatency profile

You can use either RTMP or WHIP to push video from OBS Studio, or any other streaming software. Ingest URLs should be...

  • https://<domain>/<appname>/<streamname>?direction=whip for WHIP
  • rtmp://<domain>:1935/<appname>/<streamname> for RTMP

Configuration

All configuration is done with environment variables. If using systemd you can configure systemd unit overrides. If you're using your own management script you can set your environment variables any way you wish.

Check out the config files in the examples/ dir to see available configuration arguments.

The one configuration that is mandatory is the population of the OVENMONITOR_API_USER and OVENMONITOR_API_PASSWORD variables. These must match an API user configured in OvenMediaEngine's Server.xml.

The OVENMONITOR_WEBHOOK_* variables are optional and setting them all enables OvenEmprex's Discord webhook functionality, which will inform the given Discord Webhook (or possibly any webhook if the format matches) when someone is live on the server or not.

Customization

There's only a couple supported methods of customization at this time:

  1. assets/webhook_avatars can provide for a way to assign stream keys an avatar that the webhook will use when announcing that key has gone live
  2. assets/errorlogo.gif can be replaced to replace the throbber on any interface waiting for a stream to start
  3. Anything in templates/ can be edited as desired but will likely be reverted in a future update

Security

For the moment, security is the responsibility of the HTTP proxy. The CherryPy app does not do any kind of authentication (and you want to do authentication). You should not simply proxy all HTTPS traffic to the app and call it a day. You should add basic authentication for your /management* endpoints, and also add authentication to the endpoint named after your OvenMediaEngine applications if you want to secure them. You also need /status* and /assets* proxied without auth to the CherryPy app.

Even still, someone who knows an exact stream key can currently get the Websocket for your WebRTC sessions and the RTMP URL to push. This is an inherited weakness from OvenMediaEngine and would be a 2.0 goal to add viewer authentication and passphrases to the Admission Webhook.

You can make it harder for someone to stream to your server by adding an access key. See the OVENMONITOR_ACCESS_KEY variable on the example configs. If this is set, any streamer must also include a GET parameter matching the key to start a stream by appending ?access_key=KEY_HERE to their stream URL.

In addition, OvenMediaEngine has been known to have a recurring bug where its API endpoint will listen on all IP addresses even if configured not to do so. It is recommended you use a firewall to block all ports except the video ingest ports and use your HTTP proxy for most traffic. The recommended setup:

  • OvenMediaEngine API port on localhost:8081 and firewalled
  • OvenMediaEngine TCP Relay at :3478 and open
  • ICE Candidates set to UDP 10000-10004 and open
  • WHIP Signaling at :3333 and firewalled
  • OvenEmprex at :8080 and firewalled
  • HTTP proxy set to listen on :443 and proxy all HTTP traffic to localhost:8080
  • HTTP proxy also listening on :3334 and proxying all HTTP traffic to localhost:3333
  • HTTP proxy applying basic auth of some form to /management*

tl;dr: This is no more or less secure than an RTMP server sitting on the open internet if you firewall stuff but OvenMediaEngine has some quirks to be aware of and CherryPy assumes security is being performed by the proxy.

This all fits my use-case but is a 2.0 item to fix.