Event Hooks#

go-rtmp fires hooks on RTMP lifecycle events, allowing external systems to react to stream activity in real-time. Hooks are asynchronous — they never block RTMP message processing.

Available Events#

EventTrigger
connection_acceptClient TCP connection accepted
connection_closeClient disconnected
handshake_completeRTMP handshake finished
stream_createStream first created in registry
stream_deleteStream removed (no publishers or subscribers)
publish_startPublisher begins streaming
publish_stopPublisher stops streaming
play_startSubscriber begins playback
play_stopSubscriber stops playback
codec_detectedAudio/video codec identified
subscriber_countSubscriber count changed
auth_failedAuthentication attempt failed

Event Payload#

Every event is delivered as a JSON object:

{
  "type": "publish_start",
  "timestamp": 1705312222,
  "conn_id": "conn-abc123",
  "stream_key": "live/test",
  "data": {}
}

Some events include additional fields in data:

EventData Fields
connection_acceptremote_addr
connection_closerole, duration_sec
publish_stopaudio_packets, video_packets, total_bytes, audio_codec, video_codec, duration_sec
play_stopduration_sec
subscriber_countcount
auth_failedaction (publish/play), error

Webhook Hook#

Send HTTP POST requests to external URLs on specific events:

./rtmp-server \
  -hook-webhook "publish_start=https://api.example.com/on-publish" \
  -hook-webhook "publish_stop=https://api.example.com/on-unpublish" \
  -hook-webhook "auth_failed=https://alerts.example.com/auth"

The -hook-webhook flag format is event_type=url. It can be repeated for multiple event/URL pairs.

HTTP request details:

PropertyValue
MethodPOST
Content-Typeapplication/json
BodyJSON event payload
SuccessAny 2xx status code
FailureLogged at ERROR level

Shell Hook#

Execute scripts on specific events:

./rtmp-server \
  -hook-script "connection_accept=/opt/scripts/on-connect.sh" \
  -hook-script "publish_start=/opt/scripts/on-publish.sh"

The script receives event data as environment variables:

VariableContent
RTMP_EVENT_TYPEEvent type string (e.g., publish_start)
RTMP_TIMESTAMPUnix timestamp
RTMP_CONN_IDConnection ID
RTMP_STREAM_KEYStream key (e.g., live/test)
RTMP_<KEY>Additional data fields (uppercased, prefixed)

Example script:

#!/bin/bash
echo "Event: $RTMP_EVENT_TYPE"
echo "Stream: $RTMP_STREAM_KEY"
echo "Time: $RTMP_TIMESTAMP"

if [ "$RTMP_EVENT_TYPE" = "publish_start" ]; then
  curl -s -X POST "https://dashboard.example.com/api/streams" \
    -d "{\"key\": \"$RTMP_STREAM_KEY\", \"status\": \"live\"}"
fi

Stdio Hook#

Print events to stderr for log pipeline ingestion:

# JSON format (one JSON object per line)
./rtmp-server -hook-stdio-format json

# Environment variable format
./rtmp-server -hook-stdio-format env

This is useful for piping to log aggregators:

./rtmp-server -hook-stdio-format json 2>&1 | jq --unbuffered '.type'

Combining Hooks#

All three hook types can be used simultaneously:

./rtmp-server -listen :1935 \
  -hook-stdio-format json \
  -hook-webhook "publish_start=https://api.example.com/on-publish" \
  -hook-webhook "auth_failed=https://alerts.example.com/auth" \
  -hook-script "connection_accept=/opt/scripts/on-connect.sh" \
  -hook-timeout 30s \
  -hook-concurrency 10

Each event fires all matching hooks in parallel.

Configuration#

FlagDefaultDescription
-hook-timeout30sMaximum execution time per hook
-hook-concurrency10Maximum number of hooks executing in parallel

The concurrency limit uses a bounded semaphore. When the pool is full, new hooks queue in goroutines until a slot opens. This prevents hook storms from consuming unlimited resources.

Execution Model#

  • Hooks execute asynchronously — they never block RTMP message processing
  • Each hook runs in its own goroutine with a timeout context
  • A bounded worker pool (semaphore channel) limits concurrency
  • Errors are logged at ERROR level; successes at DEBUG level
  • Execution duration is tracked and logged

Use Cases#

ScenarioEventAction
Trigger transcoding pipelinepublish_startWebhook to start FFmpeg workers
Update live dashboardsubscriber_countWebhook to push WebSocket update
Alert on unauthorized accessauth_failedWebhook to security monitoring
Log stream analyticspublish_stopShell script to record duration/bytes
Feed log pipelineAll eventsStdio JSON to Elasticsearch/Loki
Cleanup on disconnectconnection_closeShell script to release resources