<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>User Guide on go-rtmp</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/</link><description>Recent content in User Guide on go-rtmp</description><generator>Hugo</generator><language>en</language><atom:link href="https://alxayo.github.io/rtmp-go/docs/user-guide/index.xml" rel="self" type="application/rss+xml"/><item><title>Recording</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/recording/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/recording/</guid><description>&lt;h1 id="recording"&gt;Recording&lt;a class="anchor" href="#recording"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;go-rtmp records published streams to disk automatically. The server selects the container format based on the video codec:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;H.264/AVC streams&lt;/strong&gt; → &lt;strong&gt;FLV&lt;/strong&gt; (Flash Video) container&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;H.265/HEVC streams&lt;/strong&gt; → &lt;strong&gt;MP4&lt;/strong&gt; (ISO BMFF) container&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Recording runs alongside live relay — subscribers see the stream in real-time while the server simultaneously writes to disk.&lt;/p&gt;
&lt;h2 id="enabling-recording"&gt;Enabling Recording&lt;a class="anchor" href="#enabling-recording"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Add the &lt;code&gt;-record-all&lt;/code&gt; and &lt;code&gt;-record-dir&lt;/code&gt; flags:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./rtmp-server -record-all true -record-dir ./recordings&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The directory is created automatically if it doesn&amp;rsquo;t exist. By default, &lt;code&gt;-record-dir&lt;/code&gt; points to &lt;code&gt;recordings&lt;/code&gt; in the working directory.&lt;/p&gt;</description></item><item><title>Live Relay</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/relay/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/relay/</guid><description>&lt;h1 id="live-relay"&gt;Live Relay&lt;a class="anchor" href="#live-relay"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Live relay is the core of go-rtmp. It enables real-time pub/sub streaming: one publisher sends media to a stream key, and any number of subscribers receive it simultaneously.&lt;/p&gt;
&lt;h2 id="how-pubsub-works"&gt;How Pub/Sub Works&lt;a class="anchor" href="#how-pubsub-works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The server maintains a &lt;strong&gt;stream registry&lt;/strong&gt; — a thread-safe map of active streams keyed by their full stream key (e.g., &lt;code&gt;live/test&lt;/code&gt;).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;publisher&lt;/strong&gt; connects and issues a &lt;code&gt;publish&lt;/code&gt; command for a stream key&lt;/li&gt;
&lt;li&gt;The server creates a stream entry in the registry&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Subscribers&lt;/strong&gt; connect and issue &lt;code&gt;play&lt;/code&gt; commands for the same stream key&lt;/li&gt;
&lt;li&gt;Each media message from the publisher is broadcast to all active subscribers&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Only one publisher is allowed per stream key. Attempting to publish to an occupied key results in an error. There is no limit on the number of subscribers.&lt;/p&gt;</description></item><item><title>Multi-Destination Relay</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/multi-relay/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/multi-relay/</guid><description>&lt;h1 id="multi-destination-relay"&gt;Multi-Destination Relay&lt;a class="anchor" href="#multi-destination-relay"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;go-rtmp can forward published streams to one or more external RTMP servers. This enables simulcasting, CDN distribution, and backup recording without any transcoding.&lt;/p&gt;
&lt;h2 id="enabling-relay"&gt;Enabling Relay&lt;a class="anchor" href="#enabling-relay"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;-relay-to&lt;/code&gt; flag, which can be specified multiple times:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./rtmp-server -listen :1935 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -relay-to rtmp://cdn1.example.com/live/key &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -relay-to rtmp://cdn2.example.com/live/key&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each destination must use the &lt;code&gt;rtmp://&lt;/code&gt; scheme and include a host. Destinations are validated at startup — invalid URLs cause the server to exit with an error.&lt;/p&gt;</description></item><item><title>Authentication</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/authentication/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/authentication/</guid><description>&lt;h1 id="authentication"&gt;Authentication&lt;a class="anchor" href="#authentication"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;go-rtmp supports pluggable token-based authentication to control who can publish and subscribe to streams.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Mode&lt;/th&gt;
 &lt;th&gt;Flag&lt;/th&gt;
 &lt;th&gt;Best For&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;none&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;-auth-mode none&lt;/code&gt; (default)&lt;/td&gt;
 &lt;td&gt;Open access, backward compatible&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;token&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;-auth-mode token&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Small setups, static configuration&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;file&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;-auth-mode file&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Medium deployments, live reload&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;callback&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;-auth-mode callback&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Full integration with existing auth systems&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Authentication is enforced at the &lt;strong&gt;publish/play command level&lt;/strong&gt; — not at connect or handshake. This means the RTMP connection is established first, then auth is checked when the client issues a publish or play command.&lt;/p&gt;</description></item><item><title>Event Hooks</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/hooks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/hooks/</guid><description>&lt;h1 id="event-hooks"&gt;Event Hooks&lt;a class="anchor" href="#event-hooks"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;go-rtmp fires hooks on RTMP lifecycle events, allowing external systems to react to stream activity in real-time. Hooks are &lt;strong&gt;asynchronous&lt;/strong&gt; — they never block RTMP message processing.&lt;/p&gt;
&lt;h2 id="available-events"&gt;Available Events&lt;a class="anchor" href="#available-events"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Event&lt;/th&gt;
 &lt;th&gt;Trigger&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;connection_accept&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Client TCP connection accepted&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;connection_close&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Client disconnected&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;handshake_complete&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;RTMP handshake finished&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;stream_create&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Stream first created in registry&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;stream_delete&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Stream removed (no publishers or subscribers)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;publish_start&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Publisher begins streaming&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;publish_stop&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Publisher stops streaming&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;play_start&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Subscriber begins playback&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;play_stop&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Subscriber stops playback&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;codec_detected&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Audio/video codec identified&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;subscriber_count&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Subscriber count changed&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;auth_failed&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Authentication attempt failed&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="event-payload"&gt;Event Payload&lt;a class="anchor" href="#event-payload"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Every event is delivered as a JSON object:&lt;/p&gt;</description></item><item><title>RTMPS (TLS)</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/rtmps/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/rtmps/</guid><description>&lt;h1 id="rtmps-tls-encryption"&gt;RTMPS (TLS Encryption)&lt;a class="anchor" href="#rtmps-tls-encryption"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;RTMPS adds TLS encryption to RTMP connections, protecting stream data in transit. go-rtmp implements RTMPS via &lt;strong&gt;TLS termination at the transport layer&lt;/strong&gt; — the TLS handshake wraps the TCP connection before the RTMP protocol begins, so all protocol layers (handshake, chunks, AMF, commands, media) work identically over both plain and encrypted connections.&lt;/p&gt;
&lt;h2 id="how-it-works"&gt;How It Works&lt;a class="anchor" href="#how-it-works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Publisher (OBS/FFmpeg)
 │
 │ TLS handshake (rtmps://server:1936)
 ▼
go-rtmp server
 │ tls.NewListener() wraps net.Listener
 │ Returns tls.Conn (implements net.Conn)
 ▼
RTMP protocol (identical to plain RTMP)
 │
 ▼
Subscribers, Recording, Relay, Hooks&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The server uses Go&amp;rsquo;s &lt;code&gt;crypto/tls&lt;/code&gt; package with &lt;code&gt;tls.NewListener()&lt;/code&gt; to wrap the standard TCP listener. The resulting &lt;code&gt;tls.Conn&lt;/code&gt; implements &lt;code&gt;net.Conn&lt;/code&gt;, so the entire RTMP stack — handshake, chunk parsing, AMF encoding, command dispatch, and media relay — requires zero changes. TLS is purely a transport concern.&lt;/p&gt;</description></item><item><title>Metrics &amp; Monitoring</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/metrics/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/metrics/</guid><description>&lt;h1 id="metrics--monitoring"&gt;Metrics &amp;amp; Monitoring&lt;a class="anchor" href="#metrics--monitoring"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;go-rtmp exposes live server statistics via an HTTP endpoint using Go&amp;rsquo;s built-in &lt;code&gt;expvar&lt;/code&gt; package. Metrics are thread-safe, have zero overhead when disabled, and require no external dependencies.&lt;/p&gt;
&lt;h2 id="enabling-metrics"&gt;Enabling Metrics&lt;a class="anchor" href="#enabling-metrics"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./rtmp-server -metrics-addr :8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When &lt;code&gt;-metrics-addr&lt;/code&gt; is not specified, no HTTP listener is started and there is zero performance overhead.&lt;/p&gt;
&lt;h2 id="querying-metrics"&gt;Querying Metrics&lt;a class="anchor" href="#querying-metrics"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl http://localhost:8080/debug/vars&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The response is a JSON object containing all &lt;code&gt;rtmp_*&lt;/code&gt; and &lt;code&gt;srt_*&lt;/code&gt; keys, dynamic endpoints, and Go&amp;rsquo;s built-in &lt;code&gt;memstats&lt;/code&gt; and &lt;code&gt;cmdline&lt;/code&gt; variables:&lt;/p&gt;</description></item><item><title>HLS Streaming</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/hls-streaming/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/hls-streaming/</guid><description>&lt;h1 id="hls-streaming"&gt;HLS Streaming&lt;a class="anchor" href="#hls-streaming"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;go-rtmp outputs RTMP natively. To deliver streams to web browsers, convert to HLS (HTTP Live Streaming) using FFmpeg as a sidecar process.&lt;/p&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;a class="anchor" href="#architecture"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Publisher (OBS/FFmpeg)
 │
 ▼
go-rtmp server (RTMP on :1935)
 │
 ▼
FFmpeg (subscribes via RTMP, outputs HLS segments)
 │
 ▼
HTTP server (serves .m3u8 + .ts files)
 │
 ▼
Browser (hls.js / native HLS player)&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="basic-setup"&gt;Basic Setup&lt;a class="anchor" href="#basic-setup"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="step-1-start-go-rtmp"&gt;Step 1: Start go-rtmp&lt;a class="anchor" href="#step-1-start-go-rtmp"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./rtmp-server -listen :1935&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="step-2-publish-a-stream"&gt;Step 2: Publish a stream&lt;a class="anchor" href="#step-2-publish-a-stream"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;From OBS, FFmpeg, or any RTMP client:&lt;/p&gt;</description></item><item><title>SRT Ingest</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/srt-ingest/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/srt-ingest/</guid><description>&lt;h1 id="srt-ingest"&gt;SRT Ingest&lt;a class="anchor" href="#srt-ingest"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;go-rtmp accepts &lt;a href="https://github.com/Haivision/srt"&gt;SRT (Secure Reliable Transport)&lt;/a&gt; streams over UDP alongside RTMP. SRT publishers are transparently converted to RTMP format — existing RTMP subscribers can watch SRT sources without any changes.&lt;/p&gt;
&lt;h2 id="enabling-srt"&gt;Enabling SRT&lt;a class="anchor" href="#enabling-srt"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Add the &lt;code&gt;-srt-listen&lt;/code&gt; flag to start the UDP listener:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./rtmp-server -listen :1935 -srt-listen :4200 -log-level info&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The server now accepts RTMP on TCP port 1935 and SRT on UDP port 4200 simultaneously.&lt;/p&gt;
&lt;h2 id="publishing-via-srt"&gt;Publishing via SRT&lt;a class="anchor" href="#publishing-via-srt"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="ffmpeg"&gt;FFmpeg&lt;a class="anchor" href="#ffmpeg"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ffmpeg -re -i test.mp4 -c copy -f mpegts &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;srt://localhost:4200?streamid=live/test&amp;amp;pkt_size=1316&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="obs-studio"&gt;OBS Studio&lt;a class="anchor" href="#obs-studio"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Settings → Stream → Service: &lt;strong&gt;Custom&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Server: &lt;code&gt;srt://your-server:4200&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Stream Key: &lt;code&gt;live/test&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="ip-cameras"&gt;IP Cameras&lt;a class="anchor" href="#ip-cameras"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Most IP cameras with SRT support can publish directly. Set the SRT destination to:&lt;/p&gt;</description></item><item><title>Multi-Stream</title><link>https://alxayo.github.io/rtmp-go/docs/user-guide/multi-stream/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://alxayo.github.io/rtmp-go/docs/user-guide/multi-stream/</guid><description>&lt;h1 id="multi-stream"&gt;Multi-Stream&lt;a class="anchor" href="#multi-stream"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;go-rtmp handles multiple simultaneous streams out of the box. Each stream is identified by a unique &lt;strong&gt;stream key&lt;/strong&gt; and operates independently — with its own publisher, subscribers, recording, and authentication. Both RTMP and SRT publishers can run side by side on the same server.&lt;/p&gt;
&lt;h2 id="how-it-works"&gt;How It Works&lt;a class="anchor" href="#how-it-works"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Every stream lives in a central &lt;strong&gt;stream registry&lt;/strong&gt; keyed by stream key (e.g. &lt;code&gt;live/cam1&lt;/code&gt;, &lt;code&gt;live/cam2&lt;/code&gt;). The rules are simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;One publisher per key&lt;/strong&gt; — a stream key can have exactly one active publisher at a time. A second publish attempt to the same key is rejected with an error.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unlimited subscribers per key&lt;/strong&gt; — any number of viewers can watch any active stream.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Full isolation&lt;/strong&gt; — streams do not interact. Publishing to &lt;code&gt;live/cam1&lt;/code&gt; has no effect on &lt;code&gt;live/cam2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mixed protocols&lt;/strong&gt; — RTMP and SRT publishers register in the same registry. Subscribers see no difference.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; Publisher A (RTMP) Publisher B (SRT)
 live/cam1 live/cam2
 │ │
 ▼ ▼
 ┌──────────────────────────────────────┐
 │ Stream Registry │
 │ ┌────────────┐ ┌────────────┐ │
 │ │ live/cam1 │ │ live/cam2 │ │
 │ │ pub + subs │ │ pub + subs │ │
 │ └────────────┘ └────────────┘ │
 └──────────────────────────────────────┘
 │ │ │
 ▼ ▼ ▼
 Viewer 1 Viewer 2 Viewer 3
 (cam1) (cam1) (cam2)&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="publishing-multiple-streams"&gt;Publishing Multiple Streams&lt;a class="anchor" href="#publishing-multiple-streams"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Each publisher targets a different stream key. You can mix RTMP and SRT freely — just use different keys.&lt;/p&gt;</description></item></channel></rss>