A small, correct, hard-to-crash RTMP ingest server.
It accepts publishes from OBS, FFmpeg and other encoders, takes care of the handshake, chunk streams, protocol control messages, AMF0 commands and FLV tag parsing, and hands you timestamped audio and video frames through a behaviour you implement. What you do with them — HLS, recording, relaying, analysis — is up to you.
Getting started
defmodule MyApp.RTMPHandler do
use RTMP.Handler
@impl true
def handle_publish(_app, stream_key, state) do
if stream_key == "secret", do: {:ok, state}, else: {:reject, :bad_key, state}
end
@impl true
def handle_frame(frame, state) do
IO.inspect({frame.type, frame.codec, frame.dts})
{:ok, state}
end
end
# in your application's supervision tree
{RTMP.Listener, port: 1935, handler: MyApp.RTMPHandler}Then publish to it:
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://localhost:1935/live/secretWhere to look
RTMP.Handler— the callbacks and their lifecycleRTMP.Listener— starting the server and its optionsRTMP.Frame— what a frame containsRTMP.Limits— the hard limits and their defaultsRTMP.Telemetry— events for metrics and logging
Summary
Functions
Closes a connection from outside its handler — for example, when a stream key is revoked mid-stream.
Functions
Closes a connection from outside its handler — for example, when a stream key is revoked mid-stream.
connection is the connection process; inside any handler callback that's
self(), so a handler can register it somewhere to find it later. The
handler's RTMP.Handler.handle_disconnect/2 receives
{:disconnected, reason}.