> ## 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.

# Client

> Complete API reference for the Client struct.

`Client` is a RTSP client that can read streams from servers (playing) or publish streams to servers (recording). It manages connections, transport negotiation, authentication, and packet I/O.

## Struct fields

### Target

<ParamField path="Scheme" type="string">
  URL scheme. Must be `"rtsp"` or `"rtsps"` (TLS).
</ParamField>

<ParamField path="Host" type="string">
  Remote host and port (e.g. `"192.168.1.10:554"`).
</ParamField>

### RTSP parameters

<ParamField path="ReadTimeout" type="time.Duration" default="10s">
  Timeout for read operations.
</ParamField>

<ParamField path="WriteTimeout" type="time.Duration" default="10s">
  Timeout for write operations.
</ParamField>

<ParamField path="TLSConfig" type="*tls.Config" default="nil">
  TLS configuration used when connecting to RTSPS servers.
</ParamField>

<ParamField path="Tunnel" type="Tunnel" default="TunnelNone">
  Tunneling method. One of `TunnelNone`, `TunnelHTTP`, or `TunnelWebSocket`.
</ParamField>

<ParamField path="Protocol" type="*Protocol" default="nil">
  Transport protocol (`ProtocolUDP`, `ProtocolUDPMulticast`, or `ProtocolTCP`). When `nil` the client first tries UDP, then falls back to TCP automatically.
</ParamField>

<ParamField path="AnyPortEnable" type="bool" default="false">
  Enable communication with servers that do not provide UDP server ports or that use different server ports than announced. This can be a security risk.
</ParamField>

<ParamField path="InitialUDPReadTimeout" type="time.Duration" default="3s">
  When reading with UDP, if no packet is received within this timeout the client switches to TCP.
</ParamField>

<ParamField path="UDPReadBufferSize" type="int" default="OS default">
  Size of the UDP read buffer. Increase to reduce packet loss on high-bandwidth streams.
</ParamField>

<ParamField path="WriteQueueSize" type="int" default="256">
  Size of the outbound packet queue. Must be a power of two.
</ParamField>

<ParamField path="MaxPacketSize" type="int" default="1472">
  Maximum size of outbound RTP/RTCP packets in bytes. Must be less than the IPv4/UDP MTU (1472 bytes).
</ParamField>

<ParamField path="UserAgent" type="string" default="&#x22;gortsplib&#x22;">
  Value sent in the `User-Agent` RTSP header.
</ParamField>

<ParamField path="DisableRTCPSenderReports" type="bool" default="false">
  Disable automatic generation and sending of RTCP sender reports.
</ParamField>

<ParamField path="RequestBackChannels" type="bool" default="false">
  Explicitly request back channels from the server (ONVIF extension).
</ParamField>

<ParamField path="UDPSourcePortRange" type="[2]uint16" default="[10000, 65535]">
  Range of local source ports used for outbound UDP packets.
</ParamField>

### System functions

<ParamField path="DialContext" type="func(ctx context.Context, network, address string) (net.Conn, error)" default="(&net.Dialer{}).DialContext">
  Function used to open TCP connections. Override for custom networking.
</ParamField>

<ParamField path="ListenPacket" type="func(network, address string) (net.PacketConn, error)" default="net.ListenPacket">
  Function used to open UDP listeners.
</ParamField>

<ParamField path="ResolveIPAddr" type="func(network, address string) (*net.IPAddr, error)" default="net.ResolveIPAddr">
  Function used to resolve IP addresses from hostnames.
</ParamField>

### Callbacks

<ParamField path="OnRequest" type="ClientOnRequestFunc">
  Called each time the client sends a request to the server. Prototype: `func(*base.Request)`.
</ParamField>

<ParamField path="OnResponse" type="ClientOnResponseFunc">
  Called each time the client receives a response from the server. Prototype: `func(*base.Response)`.
</ParamField>

<ParamField path="OnServerRequest" type="ClientOnRequestFunc">
  Called each time the client receives a request from the server (e.g. server-initiated OPTIONS). Prototype: `func(*base.Request)`.
</ParamField>

<ParamField path="OnServerResponse" type="ClientOnResponseFunc">
  Called each time the client sends a response to the server. Prototype: `func(*base.Response)`.
</ParamField>

<ParamField path="OnTransportSwitch" type="ClientOnTransportSwitchFunc">
  Called when the transport protocol is switched (e.g. UDP to TCP fallback). Prototype: `func(err error)`. Defaults to logging the error.
</ParamField>

<ParamField path="OnPacketsLost" type="ClientOnPacketsLostFunc">
  Called when the client detects lost RTP packets. Prototype: `func(lost uint64)`. Defaults to logging the count.
</ParamField>

<ParamField path="OnDecodeError" type="ClientOnDecodeErrorFunc">
  Called when a non-fatal decode error occurs. Prototype: `func(err error)`. Defaults to logging the error.
</ParamField>

***

## Methods

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

    ```go theme={null}
    func (c *Client) Start() error
    ```

    Initializes the connection to the server using the `Scheme` and `Host` fields. Must be called before any RTSP method calls. Starts the internal event loop in a goroutine.

    <ResponseField name="error" type="error">
      Non-nil if initialization fails (e.g. invalid `WriteQueueSize`, invalid `MaxPacketSize`).
    </ResponseField>

    ***

    ### `StartRecording`

    ```go theme={null}
    func (c *Client) StartRecording(address string, desc *description.Session) error
    ```

    Convenience method that parses `address` as a URL, calls `Start()`, `Announce()`, `SetupAll()`, and `Record()` in sequence. The client is closed automatically on any error.

    <ParamField path="address" type="string" required>
      Full RTSP URL string of the server to publish to.
    </ParamField>

    <ParamField path="desc" type="*description.Session" required>
      Session description (SDP) of the media to be published.
    </ParamField>

    <ResponseField name="error" type="error">
      Non-nil if any step in the connection/publish sequence fails.
    </ResponseField>

    ***

    ### `Close`

    ```go theme={null}
    func (c *Client) Close()
    ```

    Closes all client resources (connections, UDP listeners, goroutines) and waits for them to exit. Sends a TEARDOWN request before closing. Safe to call from any goroutine.

    ***

    ### `Wait`

    ```go theme={null}
    func (c *Client) Wait() error
    ```

    Blocks until all client resources have exited. This occurs either when `Close()` is called or when a fatal error occurs (e.g. network timeout).

    <ResponseField name="error" type="error">
      The close error, or `nil` if closed cleanly via `Close()`.
    </ResponseField>
  </Accordion>

  <Accordion title="Stream negotiation">
    ### `Describe`

    ```go theme={null}
    func (c *Client) Describe(u *base.URL) (*description.Session, *base.Response, error)
    ```

    Sends a DESCRIBE request to the server and returns the parsed session description. Handles redirects automatically.

    <ParamField path="u" type="*base.URL" required>
      The RTSP URL to describe.
    </ParamField>

    <ResponseField name="*description.Session" type="*description.Session">
      Parsed session description containing media tracks and their formats.
    </ResponseField>

    <ResponseField name="*base.Response" type="*base.Response">
      The raw RTSP response.
    </ResponseField>

    <ResponseField name="error" type="error">
      Non-nil on failure.
    </ResponseField>

    ***

    ### `Announce`

    ```go theme={null}
    func (c *Client) Announce(u *base.URL, desc *description.Session) (*base.Response, error)
    ```

    Sends an ANNOUNCE request to the server with the given session description. Call before `Setup()` and `Record()` when publishing.

    <ParamField path="u" type="*base.URL" required>
      The RTSP URL to announce to.
    </ParamField>

    <ParamField path="desc" type="*description.Session" required>
      Session description of the media to publish.
    </ParamField>

    <ResponseField name="*base.Response" type="*base.Response">
      The raw RTSP response.
    </ResponseField>

    <ResponseField name="error" type="error">
      Non-nil on failure.
    </ResponseField>

    ***

    ### `SetupAll`

    ```go theme={null}
    func (c *Client) SetupAll(baseURL *base.URL, medias []*description.Media) error
    ```

    Calls `Setup()` for every media in `medias`. Uses port `0` for both RTP and RTCP (auto-assigned). Stops and returns on the first error.

    <ParamField path="baseURL" type="*base.URL" required>
      The base URL returned from `Describe()` (available as `desc.BaseURL`).
    </ParamField>

    <ParamField path="medias" type="[]*description.Media" required>
      Slice of media descriptions to set up.
    </ParamField>

    <ResponseField name="error" type="error">
      Non-nil if any SETUP request fails.
    </ResponseField>

    ***

    ### `Setup`

    ```go theme={null}
    func (c *Client) Setup(
        baseURL *base.URL,
        media *description.Media,
        rtpPort int,
        rtcpPort int,
    ) (*base.Response, error)
    ```

    Sends a SETUP request for a single media track. `rtpPort` and `rtcpPort` are only used with UDP transport; pass `0` for both to let the OS choose ports.

    <ParamField path="baseURL" type="*base.URL" required>
      The base URL of the stream (from `Describe()`).
    </ParamField>

    <ParamField path="media" type="*description.Media" required>
      The specific media track to set up.
    </ParamField>

    <ParamField path="rtpPort" type="int">
      Local UDP port for RTP. `0` means auto-assign. Must be even.
    </ParamField>

    <ParamField path="rtcpPort" type="int">
      Local UDP port for RTCP. `0` means auto-assign. Must equal `rtpPort + 1`.
    </ParamField>

    <ResponseField name="*base.Response" type="*base.Response">
      The raw RTSP response.
    </ResponseField>

    <ResponseField name="error" type="error">
      Non-nil on failure.
    </ResponseField>

    ***

    ### `Options`

    ```go theme={null}
    func (c *Client) Options(u *base.URL) (*base.Response, error)
    ```

    Sends an OPTIONS request. Normally called automatically; can be used to probe server capabilities.

    <ParamField path="u" type="*base.URL" required>
      The URL to send the OPTIONS request to.
    </ParamField>

    <ResponseField name="*base.Response" type="*base.Response">
      The raw RTSP response containing a `Public` header with supported methods.
    </ResponseField>

    <ResponseField name="error" type="error">
      Non-nil on failure.
    </ResponseField>
  </Accordion>

  <Accordion title="Stream control">
    ### `Play`

    ```go theme={null}
    func (c *Client) Play(ra *headers.Range) (*base.Response, error)
    ```

    Sends a PLAY request. Must be called after `Setup()`. Starts receiving packets.

    <ParamField path="ra" type="*headers.Range">
      Playback range. Pass `nil` to start from the beginning (NPT 0).
    </ParamField>

    <ResponseField name="*base.Response" type="*base.Response">
      The raw RTSP response.
    </ResponseField>

    <ResponseField name="error" type="error">
      Non-nil on failure.
    </ResponseField>

    ***

    ### `Record`

    ```go theme={null}
    func (c *Client) Record() (*base.Response, error)
    ```

    Sends a RECORD request. Must be called after `Announce()` and `Setup()`. Starts sending packets.

    <ResponseField name="*base.Response" type="*base.Response">
      The raw RTSP response.
    </ResponseField>

    <ResponseField name="error" type="error">
      Non-nil on failure.
    </ResponseField>

    ***

    ### `Pause`

    ```go theme={null}
    func (c *Client) Pause() (*base.Response, error)
    ```

    Sends a PAUSE request. Can only be called after `Play()` or `Record()`. Suspends the stream without tearing it down.

    <ResponseField name="*base.Response" type="*base.Response">
      The raw RTSP response.
    </ResponseField>

    <ResponseField name="error" type="error">
      Non-nil on failure.
    </ResponseField>
  </Accordion>

  <Accordion title="Packet I/O">
    ### `WritePacketRTP`

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

    Sends an RTP packet to the server. Uses the current wall clock as the NTP timestamp. Only valid in the recording state after `Record()`.

    <ParamField path="medi" type="*description.Media" required>
      The media track to send on.
    </ParamField>

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

    <ResponseField name="error" type="error">
      Non-nil on write failure.
    </ResponseField>

    ***

    ### `WritePacketRTPWithNTP`

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

    Like `WritePacketRTP` but accepts an explicit NTP timestamp. This NTP value is used in periodic RTCP sender reports.

    <ParamField path="medi" type="*description.Media" required>
      The media track to send on.
    </ParamField>

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

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

    <ResponseField name="error" type="error">
      Non-nil on write failure.
    </ResponseField>

    ***

    ### `WritePacketRTCP`

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

    Sends an RTCP packet to the server.

    <ParamField path="medi" type="*description.Media" required>
      The media track to send on.
    </ParamField>

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

    <ResponseField name="error" type="error">
      Non-nil on write failure.
    </ResponseField>

    ***

    ### `OnPacketRTP`

    ```go theme={null}
    func (c *Client) OnPacketRTP(medi *description.Media, forma format.Format, cb OnPacketRTPFunc)
    ```

    Registers a callback for incoming RTP packets on a specific media format. `OnPacketRTPFunc` has signature `func(*rtp.Packet)`. Must be called after `Setup()` and before `Play()`.

    <ParamField path="medi" type="*description.Media" required>
      The media track to listen on.
    </ParamField>

    <ParamField path="forma" type="format.Format" required>
      The specific codec format to receive packets for.
    </ParamField>

    <ParamField path="cb" type="OnPacketRTPFunc" required>
      Callback invoked for each received RTP packet: `func(*rtp.Packet)`.
    </ParamField>

    ***

    ### `OnPacketRTPAny`

    ```go theme={null}
    func (c *Client) OnPacketRTPAny(cb OnPacketRTPAnyFunc)
    ```

    Registers a callback for incoming RTP packets on **all** set-up media tracks and formats. `OnPacketRTPAnyFunc` has signature `func(*description.Media, format.Format, *rtp.Packet)`.

    <ParamField path="cb" type="OnPacketRTPAnyFunc" required>
      Callback invoked for each received RTP packet with media and format context.
    </ParamField>

    ***

    ### `OnPacketRTCP`

    ```go theme={null}
    func (c *Client) OnPacketRTCP(medi *description.Media, cb OnPacketRTCPFunc)
    ```

    Registers a callback for incoming RTCP packets on a specific media track. `OnPacketRTCPFunc` has signature `func(rtcp.Packet)`.

    <ParamField path="medi" type="*description.Media" required>
      The media track to listen on.
    </ParamField>

    <ParamField path="cb" type="OnPacketRTCPFunc" required>
      Callback invoked for each received RTCP packet.
    </ParamField>

    ***

    ### `OnPacketRTCPAny`

    ```go theme={null}
    func (c *Client) OnPacketRTCPAny(cb OnPacketRTCPAnyFunc)
    ```

    Registers a callback for incoming RTCP packets on **all** set-up media tracks. `OnPacketRTCPAnyFunc` has signature `func(*description.Media, rtcp.Packet)`.

    <ParamField path="cb" type="OnPacketRTCPAnyFunc" required>
      Callback invoked for each received RTCP packet with media context.
    </ParamField>
  </Accordion>

  <Accordion title="Timestamps">
    ### `PacketPTS`

    ```go theme={null}
    func (c *Client) PacketPTS(medi *description.Media, pkt *rtp.Packet) (int64, bool)
    ```

    Returns the presentation timestamp (PTS) of an inbound RTP packet. The PTS is computed by decoding the RTP timestamp and synchronizing it with other tracks via `rtptime.GlobalDecoder`.

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

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

    <ResponseField name="int64" type="int64">
      The PTS in media clock units.
    </ResponseField>

    <ResponseField name="bool" type="bool">
      `true` if the PTS could be computed, `false` if not enough information is available yet.
    </ResponseField>

    ***

    ### `PacketNTP`

    ```go theme={null}
    func (c *Client) PacketNTP(medi *description.Media, pkt *rtp.Packet) (time.Time, bool)
    ```

    Returns the absolute NTP timestamp of an inbound RTP packet, derived from RTCP sender reports.

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

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

    <ResponseField name="time.Time" type="time.Time">
      The absolute NTP timestamp.
    </ResponseField>

    <ResponseField name="bool" type="bool">
      `true` if the NTP could be derived from RTCP sender reports, `false` otherwise.
    </ResponseField>
  </Accordion>

  <Accordion title="Introspection">
    ### `Transport`

    ```go theme={null}
    func (c *Client) Transport() *ClientTransport
    ```

    Returns details about the active transport. The returned `ClientTransport` contains:

    * `Conn ConnTransport` — connection transport, with `Tunnel` field (`TunnelNone`, `TunnelHTTP`, `TunnelWebSocket`).
    * `Session *SessionTransport` — session transport (non-nil after `Setup()`), with `Protocol` (`ProtocolUDP`, `ProtocolUDPMulticast`, `ProtocolTCP`) and `Profile` fields.

    ***

    ### `Stats`

    ```go theme={null}
    func (c *Client) Stats() *ClientStats
    ```

    Returns a snapshot of client statistics. The returned `*ClientStats` struct contains:

    | Field | Type | Description |
    | - | - | - |
    | `Conn.InboundBytes` | `uint64` | Total bytes received on the TCP connection |
    | `Conn.OutboundBytes` | `uint64` | Total bytes sent on the TCP connection |
    | `Session.InboundBytes` | `uint64` | Total inbound media bytes |
    | `Session.InboundRTPPackets` | `uint64` | RTP packets received and processed |
    | `Session.InboundRTPPacketsLost` | `uint64` | Lost inbound RTP packets |
    | `Session.InboundRTPPacketsInError` | `uint64` | Inbound RTP packets that could not be processed |
    | `Session.InboundRTPPacketsJitter` | `float64` | Mean jitter of inbound RTP packets |
    | `Session.InboundRTCPPackets` | `uint64` | RTCP packets received and processed |
    | `Session.OutboundBytes` | `uint64` | Total outbound media bytes |
    | `Session.OutboundRTPPackets` | `uint64` | RTP packets sent |
    | `Session.OutboundRTPPacketsReportedLost` | `uint64` | RTP packets reported lost by the remote |
    | `Session.OutboundRTCPPackets` | `uint64` | RTCP packets sent |
    | `Session.Medias` | `map[*description.Media]SessionStatsMedia` | Per-media statistics |
  </Accordion>
</AccordionGroup>

## Callback type aliases

| Type | Signature | Used by |
| - | - | - |
| `ClientOnRequestFunc` | `func(*base.Request)` | `OnRequest`, `OnServerRequest` |
| `ClientOnResponseFunc` | `func(*base.Response)` | `OnResponse`, `OnServerResponse` |
| `ClientOnTransportSwitchFunc` | `func(err error)` | `OnTransportSwitch` |
| `ClientOnPacketsLostFunc` | `func(lost uint64)` | `OnPacketsLost` |
| `ClientOnDecodeErrorFunc` | `func(err error)` | `OnDecodeError` |
| `OnPacketRTPFunc` | `func(*rtp.Packet)` | `OnPacketRTP` |
| `OnPacketRTPAnyFunc` | `func(*description.Media, format.Format, *rtp.Packet)` | `OnPacketRTPAny` |
| `OnPacketRTCPFunc` | `func(rtcp.Packet)` | `OnPacketRTCP` |
| `OnPacketRTCPAnyFunc` | `func(*description.Media, rtcp.Packet)` | `OnPacketRTCPAny` |


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