The rtmp library deliberately stops at delivering frames — no recording, HLS or relaying built in. This example shows what "the rest" looks like for the simplest possible case: write every published stream to an FLV file.

It's about 70 lines (lib/flv_saver.ex), and almost all of it is the FLV container format. RTMP message payloads are already FLV tag bodies, so each frame is written as-is with a small header in front.

Run it

cd examples/flv_saver
mix deps.get
RTMP_PORT=1935 OUTPUT_DIR=recordings mix run --no-halt

Publish to it from another terminal:

ffmpeg -re -f lavfi -i testsrc=size=640x360:rate=30 \
       -f lavfi -i sine=frequency=440 -t 10 \
       -c:v libx264 -c:a aac -f flv rtmp://localhost:1935/live/mystream

or from OBS: server rtmp://localhost:1935/live, stream key mystream.

You'll get recordings/mystream-<unix time>.flv, playable in VLC or ffplay, and inspectable with ffprobe.

Things to notice

  • The stream key is validated before it touches a path. It comes from the network; ../../etc/passwd must not become a filename. Keys that aren't [A-Za-z0-9_-]{1,64} are rejected in handle_publish/3.
  • No auth. Any valid-looking key is accepted. A real server checks keys against something in handle_publish/3.
  • Writes are synchronous. If the disk is slow, the publisher is slowed down by TCP flow control — that's the library's backpressure working, not a bug.