OvenMediaEngine
Overview
OvenMediaEngine v0.20.5 is an open source, sub-second-latency live streaming server from AirenSoft. It ingests live video over RTMP, SRT, WebRTC and MPEG-TS and delivers it to viewers over WebRTC and Low-Latency HLS (LLHLS), with end-to-end latency measured in fractions of a second rather than the many seconds of conventional HLS.
This SecureAnyCloud image runs OvenMediaEngine on Ubuntu 24.04 LTS with a per-VM REST API token, an nginx front end and a ready-to-use demo player. A REST API drives stream management and statistics for automation.
What you get:
- The official, unmodified upstream release, the container airensoft/ovenmediaengine:v0.20.5 pulled from Docker Hub and driven entirely by external configuration
- The
ovenmediaenginesystemd service (adocker runof the pinned upstream image), configured by a mounted/etc/ovenmediaengine/Server.xml - nginx on port 80 serving a static
/healthzendpoint for load balancer probes, reverse proxying the LLHLS server and hosting a small self-contained demo player - Pass-through packaging by default: the ingested H.264/AAC is repackaged into LLHLS and WebRTC without CPU-heavy transcoding, so it runs comfortably on the 4 GiB
Standard_B2ssize - A REST API access token generated on the first boot of every VM by
ovenmediaengine-firstboot.service, written to a root-only file with mode0600before the streaming service starts - A REST API bound to localhost only, with no fixed token in the image and no token shared between VMs
- 24/7 SecureAnyCloud support
Transcoding and adaptive bitrate are CPU-intensive, so size the VM up if you enable them.
OvenMediaEngine is free software under the GNU Affero General Public License v3.0 (AGPL-3.0). The AGPL source is never rebuilt or patched. In accordance with AGPL section 13, the exact Corresponding Source for the running version is the upstream tag it was built from: AirenSoft/OvenMediaEngine at v0.20.5. SecureAnyCloud is not affiliated with the OvenMediaEngine project.
Step 1 - Launch the VM
Launch the VM from the Azure Marketplace listing or from the Azure CLI. Standard_B2s is the recommended size for evaluation and pass-through streaming. Choose a larger size for transcoding or many concurrent streams.
az group create --name ovenmediaengine-rg --location eastus
az vm image terms accept --urn sac1647283583153:ovenmediaengine-ubuntu-24-04:default:latest
az vm create \
--resource-group ovenmediaengine-rg \
--name ovenmediaengine-vm \
--image sac1647283583153:ovenmediaengine-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
# Open port 80 (health + demo player). The streaming/media ports are opened in Step 6.
az vm open-port --resource-group ovenmediaengine-rg --name ovenmediaengine-vm --port 80 --priority 900Note the public IP that az vm create prints. This guide refers to it as <vm-ip>.
Step 2 - Confirm the services are running
SSH in as azureuser and confirm that the units are active. ovenmediaengine-firstboot is a oneshot unit, so active means it ran to completion and generated this VM's API token.
systemctl is-active ovenmediaengine nginx ovenmediaengine-firstbootExpected output:
active active activeThen confirm that the ingest, delivery and API ports are listening. RTMP uses 1935, and LLHLS and WebRTC signalling share 3333. The REST API on 8081 is bound to 127.0.0.1 only.
sudo ss -tlnp | grep -E ':1935 |:3333 |:8081 |:80 'Step 3 - Retrieve this VM's REST API token
The API token was generated on this VM's first boot and written to a root-only file with mode 0600. Check the file permissions, then read the file as root:
sudo ls -l /root/ovenmediaengine-credentials.txtsudo cat /root/ovenmediaengine-credentials.txtThe file contains the manager API URL, the OME_API_TOKEN, and ready-to-use RTMP ingest, LLHLS playback, WebRTC playback and demo player URLs for this VM.
Store the token in your password manager. It is unique to this VM.
Step 4 - Verify the REST API and its token
The REST API on 8081 is protected by HTTP Basic authentication with the per-VM token. Read the token from the credentials file. Confirm that a request without a token is rejected with 401 and that a request with the token succeeds with 200:
TOKEN=$(sudo awk -F= '/^OME_API_TOKEN=/{print $2}' /root/ovenmediaengine-credentials.txt) AUTH="Basic $(printf '%s' "$TOKEN" | base64)"
# No token — rejected curl -s -o /dev/null -w 'no token: HTTP %{http_code}\n' http://127.0.0.1:8081/v1/vhosts
# Per-VM token — accepted curl -s -o /dev/null -w 'with token: HTTP %{http_code}\n' -H "Authorization: $AUTH" http://127.0.0.1:8081/v1/vhostsnginx also serves a static health endpoint for load balancer probes. Query it with:
curl -s http://127.0.0.1/healthzStep 5 - Publish a live stream and play it back
Publish a source to the default application, app, under any stream key you choose. Any RTMP encoder works, including OBS Studio, a hardware encoder or ffmpeg.
This example generates a test pattern with ffmpeg (installed on the image) and publishes it to the stream key mystream. It runs for 60 seconds in the background so that you can play it back below. To stream continuously from your own source, drop the -t 60 and the trailing & and run it in the foreground:
nohup ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 -f lavfi -i sine=frequency=440 \
-c:v libx264 -preset veryfast -tune zerolatency -profile:v baseline -pix_fmt yuv420p -g 30 \
-c:a aac -ar 44100 -b:a 128k \
-t 60 -f flv rtmp://127.0.0.1:1935/app/mystream >/tmp/ome-publish.log 2>&1 & sleep 6
# give OvenMediaEngine a moment to start packaging the streamWhile the source is publishing, OvenMediaEngine repackages it in real time. Fetch the Low-Latency HLS master playlist, which lists the video and audio renditions and their codecs:
curl -s http://127.0.0.1:3333/app/mystream/llhls.m3u8Once the media ports are open (Step 6), play the stream from a browser in any of three ways:
- Low-Latency HLS: open
http://<vm-ip>:3333/app/mystream/llhls.m3u8in any LLHLS-capable player. - WebRTC (lowest latency): open the signalling URL
ws://<vm-ip>:3333/app/mystreamin a WebRTC player such as OvenPlayer. - Built-in demo player: open
http://<vm-ip>/player/?stream=mystream, a small OvenPlayer page served by this image.
Step 6 - Open the streaming ports
The launch in Step 1 opened only port 80. Live streaming also needs the ingest and media ports open on the VM's network security group. Open RTMP ingest, the LLHLS and WebRTC signalling port, the WebRTC TURN port, the SRT ingest port and the WebRTC ICE media range:
az network nsg rule create --resource-group ovenmediaengine-rg --nsg-name ovenmediaengine-vmNSG \
--name ome-tcp --priority 1001 --access Allow --protocol Tcp --direction Inbound \
--destination-port-ranges 1935 3333 3478
az network nsg rule create --resource-group ovenmediaengine-rg --nsg-name ovenmediaengine-vmNSG \
--name ome-udp --priority 1002 --access Allow --protocol Udp --direction Inbound \
--destination-port-ranges 3478 9999 10000-10004For external WebRTC playback, OvenMediaEngine advertises this VM's public IP as its ICE candidate. It resolves the address automatically through a STUN server on startup. No manual configuration is needed as long as the ICE UDP range 10000-10004 is open.
Step 7 - Inspect and manage streams over the REST API
The REST API reports every active stream and its ingested tracks, and lets you manage the server programmatically. List the active streams in the default application, then inspect the tracks of one stream:
TOKEN=$(sudo awk -F= '/^OME_API_TOKEN=/{print $2}' /root/ovenmediaengine-credentials.txt) AUTH="Basic $(printf '%s' "$TOKEN" | base64)"
# Active streams in vhost "default", application "app" curl -s -H "Authorization: $AUTH" http://127.0.0.1:8081/v1/vhosts/default/apps/app/streams
# Tracks (video + audio) for one stream curl -s -H "Authorization: $AUTH" http://127.0.0.1:8081/v1/vhosts/default/apps/app/streams/mystreamThe full REST API reference is in the OvenMediaEngine documentation.
Step 8 - Secure and tune streaming
By default, any encoder that can reach port 1935 may publish. This is the upstream default and is convenient on a trusted network.
For a public deployment, restrict who can publish and play. Enable SignedPolicy (signed, expiring URLs) or AdmissionWebhooks (defer the decision to your own auth server) in /etc/ovenmediaengine/Server.xml, then restart the service:
sudo systemctl restart ovenmediaengineBoth mechanisms are documented in the OvenMediaEngine access control guide.
To serve LLHLS and WebRTC signalling over TLS, add your certificate to the <Host><TLS> block in Server.xml and enable the 3334/3335 TLS ports.
Transcoding and adaptive bitrate output are configured per application under <OutputProfiles>. They are CPU-intensive, so move to a compute-optimised VM size before you enable them.
Troubleshooting
A published RTMP stream never appears. Either port 1935/tcp is not open, or the encoder's server URL is not rtmp://<vm-ip>:1935/app with the stream key as the path. Confirm that the rule from Step 6 exists, then check sudo journalctl -u ovenmediaengine -n 50.
The LLHLS playlist returns 404. No stream is currently publishing to that key. The playlist exists only while a source is live. Start the encoder, then fetch llhls.m3u8 again.
A WebRTC stream connects but shows no video. The ICE UDP range 10000-10004 (and 3478 for TURN) is not open on the network security group. WebRTC signalling uses port 3333, but the media itself is UDP and needs the rules from Step 6.
The service will not start. Run sudo systemctl status ovenmediaengine and sudo docker logs ovenmediaengine. The service is intentionally held back until first boot writes the API token. On a brand-new VM, allow a few seconds for ovenmediaengine-firstboot.service to complete.
The API returns 401 with my token. Re-read the token exactly from /root/ovenmediaengine-credentials.txt. It must be Base64-encoded into the Authorization: Basic header, as shown in Step 4.
What is installed
- OvenMediaEngine: v0.20.5, AGPL-3.0, official image airensoft/ovenmediaengine:v0.20.5
- Runtime: Docker Engine, ovenmediaengine.service (systemd)
- Configuration: /etc/ovenmediaengine/Server.xml (mounted into the stock container)
- Web server: nginx on port 80, serving /healthz, the LLHLS reverse proxy and the /player/ demo page
- REST API: port 8081, bound to 127.0.0.1, with a per-VM Basic auth token
- Ingest: RTMP 1935/tcp, SRT 9999/udp, MPEG-TS 4000/udp, WebRTC (WHIP)
- Delivery: LLHLS and WebRTC on 3333/tcp, WebRTC ICE 10000-10004/udp, TURN 3478
- Packaging: pass-through (no transcoding), tuned for Standard_B2s
- Credentials: /root/ovenmediaengine-credentials.txt, mode 0600 root:root
- First boot: ovenmediaengine-firstboot.service, which generates the per-VM API token
Support
This image is packaged and maintained by SecureAnyCloud. OvenMediaEngine is free software under the GNU Affero General Public License v3.0, developed by AirenSoft and its contributors. SecureAnyCloud is not affiliated with the OvenMediaEngine project.
In accordance with AGPL section 13, the Corresponding Source for the version in this image is the upstream release it is built from: AirenSoft/OvenMediaEngine at v0.20.5.
For image-specific questions, contact SecureAnyCloud support through the Azure Marketplace listing. For questions about OvenMediaEngine itself, see the OvenMediaEngine documentation.
Deploy on Azure
Launch OvenMediaEngine on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com