> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/bluenviron/gortsplib/llms.txt
> Use this file to discover all available pages before exploring further.

# ServerStream

> Complete API reference for the ServerStream type.

`ServerStream` represents a media stream on the server side. It stores the stream description, manages SSRC allocation, distributes packets to all active reader sessions, and optionally manages multicast listeners.

A `ServerStream` is created by the application and shared between the publisher session and all reader sessions. The publisher writes packets into the stream via `WritePacketRTP` / `WritePacketRTCP`, and the stream fans the packets out to every active reader.

## Struct fields

<ParamField path="Server" type="*Server" required>
  The server instance this stream belongs to. Must be set before calling `Initialize()`.
</ParamField>

<ParamField path="Desc" type="*description.Session" required>
  The session description (SDP) that describes the media contained in this stream. Must be set before calling `Initialize()`.
</ParamField>

<ParamField path="MulticastParams" type="map[*description.Media]StreamMediaMulticastParams">
  Optional per-media multicast configuration. When set, the specified IP and ports are used instead of the server's auto-assigned multicast addresses.

  `StreamMediaMulticastParams` fields:

  | Field | Type | Description |
  | - | - | - |
  | `IP` | `net.IP` | Multicast group IP |
  | `RTPPort` | `int` | Multicast RTP port |
  | `RTCPPort` | `int` | Multicast RTCP port |
</ParamField>

***

## Methods

<AccordionGroup>
  <Accordion title="Lifecycle">
    ### `Initialize`

    ```go theme={null}
    func (st *ServerStream) Initialize() error
    ```

    Initializes the stream. Allocates local SSRCs for each media format, sets up SRTP contexts when the parent server uses TLS, and prepares internal data structures. Must be called after setting `Server` and `Desc`, and after the server has been started with `Server.Start()`.

    <ResponseField name="error" type="error">
      Non-nil if the server is not present or not yet initialized, or if SSRC/SRTP setup fails.
    </ResponseField>

    ***

    ### `Close`

    ```go theme={null}
    func (st *ServerStream) Close()
    ```

    Closes the stream. All reader sessions currently subscribed to this stream are closed immediately. After `Close()` is called, subsequent `WritePacketRTP` / `WritePacketRTCP` calls return `ErrServerStreamClosed`.
  </Accordion>

  <Accordion title="Packet writing">
    ### `WritePacketRTP`

    ```go theme={null}
    func (st *ServerStream) WritePacketRTP(medi *description.Media, pkt *rtp.Packet) error
    ```

    Writes an RTP packet to all active readers of the stream. Uses the current wall clock as the NTP timestamp for RTCP sender reports. Thread-safe.

    <ParamField path="medi" type="*description.Media" required>
      The media track the packet belongs to. Must be one of the medias in `Desc`.
    </ParamField>

    <ParamField path="pkt" type="*rtp.Packet" required>
      The RTP packet to distribute.
    </ParamField>

    <ResponseField name="error" type="error">
      `ErrServerStreamClosed` if the stream has been closed; otherwise a write error.
    </ResponseField>

    ***

    ### `WritePacketRTPWithNTP`

    ```go theme={null}
    func (st *ServerStream) WritePacketRTPWithNTP(
        medi *description.Media,
        pkt *rtp.Packet,
        ntp time.Time,
    ) error
    ```

    Like `WritePacketRTP` but accepts an explicit NTP timestamp. The NTP value is included in periodic RTCP sender reports sent to readers. Use this when you have an accurate external clock source.

    <ParamField path="medi" type="*description.Media" required>
      The media track the packet belongs to.
    </ParamField>

    <ParamField path="pkt" type="*rtp.Packet" required>
      The RTP packet to distribute.
    </ParamField>

    <ParamField path="ntp" type="time.Time" required>
      Absolute NTP timestamp of the packet.
    </ParamField>

    <ResponseField name="error" type="error">
      `ErrServerStreamClosed` if the stream has been closed; otherwise a write error.
    </ResponseField>

    ***

    ### `WritePacketRTCP`

    ```go theme={null}
    func (st *ServerStream) WritePacketRTCP(medi *description.Media, pkt rtcp.Packet) error
    ```

    Writes an RTCP packet to all active readers of the stream. Thread-safe.

    <ParamField path="medi" type="*description.Media" required>
      The media track the packet belongs to.
    </ParamField>

    <ParamField path="pkt" type="rtcp.Packet" required>
      The RTCP packet to distribute.
    </ParamField>

    <ResponseField name="error" type="error">
      `ErrServerStreamClosed` if the stream has been closed; otherwise a write error.
    </ResponseField>
  </Accordion>

  <Accordion title="Statistics">
    ### `Stats`

    ```go theme={null}
    func (st *ServerStream) Stats() *ServerStreamStats
    ```

    Returns a snapshot of stream statistics.

    **`ServerStreamStats` fields:**

    | Field | Type | Description |
    | - | - | - |
    | `OutboundBytes` | `uint64` | Total bytes written to readers |
    | `OutboundRTPPackets` | `uint64` | Total RTP packets distributed |
    | `OutboundRTCPPackets` | `uint64` | Total RTCP packets distributed |
    | `Medias` | `map[*description.Media]ServerStreamStatsMedia` | Per-media statistics |

    **`ServerStreamStatsMedia` fields:**

    | Field | Type | Description |
    | - | - | - |
    | `OutboundBytes` | `uint64` | Bytes written for this media |
    | `OutboundRTCPPackets` | `uint64` | RTCP packets distributed for this media |
    | `Formats` | `map[format.Format]ServerStreamStatsFormat` | Per-format statistics |

    **`ServerStreamStatsFormat` fields:**

    | Field | Type | Description |
    | - | - | - |
    | `OutboundRTPPackets` | `uint64` | RTP packets distributed for this format |
    | `LocalSSRC` | `uint32` | Locally assigned SSRC for this format |
  </Accordion>
</AccordionGroup>

***

## Usage example

```go theme={null}
// Create stream after server is started
stream := &gortsplib.ServerStream{
    Server: server,
    Desc:   sessionDesc, // *description.Session from SDP
}
err := stream.Initialize()
if err != nil {
    panic(err)
}
defer stream.Close()

// In OnDescribe and OnSetup handlers, return this stream.
// The server will add reader sessions to it automatically.

// Write packets from a publisher goroutine:
err = stream.WritePacketRTP(media, rtpPacket)
if err != nil {
    log.Println(err)
}
```

The `ServerStream` is **not** associated with any particular publisher connection. It is the application's responsibility to create the stream when a publisher arrives (e.g. in `OnAnnounce`) and close it when the publisher leaves (e.g. in `OnSessionClose`).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.