Skip to main content

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.

The Protocol field on Client controls how RTP and RTCP packets are carried between the client and the server. Set it before calling Start() or StartRecording().
type Protocol int

const (
    ProtocolUDP          Protocol = iota // 0
    ProtocolUDPMulticast                 // 1
    ProtocolTCP                          // 2
)
The field is a pointer to Protocol. Setting it to nil (the default) enables automatic selection.

Transport comparison

ValueWire protocolWhen to use
nil (auto)UDP first, then TCPGeneral purpose. Recommended for most scenarios.
ProtocolUDPUDP unicastLow-latency LAN environments where packet loss is acceptable.
ProtocolTCPTCP (interleaved)NAT traversal, firewalls, or any network where UDP is blocked.
ProtocolUDPMulticastUDP multicastOne server sending to many clients simultaneously on a local network.

Automatic selection (default)

When Protocol is nil, the client first attempts UDP. If no packet arrives within InitialUDPReadTimeout (default 3s), it switches to TCP and calls OnTransportSwitch to notify you of the change.
c := gortsplib.Client{
    Scheme: u.Scheme,
    Host:   u.Host,
    // Protocol is nil — the library tries UDP then falls back to TCP
}

Forcing a specific transport

To lock in a transport without any fallback, point Protocol at a value:
proto := gortsplib.ProtocolUDP
c := gortsplib.Client{
    Scheme:   u.Scheme,
    Host:     u.Host,
    Protocol: &proto,
}
UDP has the lowest overhead and is preferred on reliable local networks.

Full options example

The example below sets the transport to automatic along with explicit timeout values:
client-play-options/main.go
// Package main contains an example.
package main

import (
	"log"
	"time"

	"github.com/bluenviron/gortsplib/v5"
	"github.com/bluenviron/gortsplib/v5/pkg/base"
	"github.com/bluenviron/gortsplib/v5/pkg/description"
	"github.com/bluenviron/gortsplib/v5/pkg/format"
	"github.com/pion/rtcp"
	"github.com/pion/rtp"
)

// This example shows how to:
// 1. set additional client options.
// 2. connect to a RTSP server and read all medias on a path.

func main() {
	// parse URL
	u, err := base.ParseURL("rtsp://myuser:mypass@localhost:8554/mystream")
	if err != nil {
		panic(err)
	}

	// Client allows to set additional client options
	c := gortsplib.Client{
		Scheme: u.Scheme,
		Host:   u.Host,
		// tunneling method.
		Tunnel: gortsplib.TunnelNone,
		// transport protocol (UDP, Multicast or TCP). If nil, it is chosen automatically
		Protocol: nil,
		// timeout of read operations
		ReadTimeout: 10 * time.Second,
		// timeout of write operations
		WriteTimeout: 10 * time.Second,
	}

	// connect to the server
	err = c.Start()
	if err != nil {
		panic(err)
	}
	defer c.Close()

	// find available medias
	desc, _, err := c.Describe(u)
	if err != nil {
		panic(err)
	}

	// setup all medias
	err = c.SetupAll(desc.BaseURL, desc.Medias)
	if err != nil {
		panic(err)
	}

	// called when a RTP packet arrives
	c.OnPacketRTPAny(func(medi *description.Media, _ format.Format, _ *rtp.Packet) {
		log.Printf("RTP packet from media %v\n", medi)
	})

	// called when a RTCP packet arrives
	c.OnPacketRTCPAny(func(medi *description.Media, pkt rtcp.Packet) {
		log.Printf("RTCP packet from media %v, type %T\n", medi, pkt)
	})

	// start playing
	_, err = c.Play(nil)
	if err != nil {
		panic(err)
	}

	// wait until a fatal error
	panic(c.Wait())
}

Tunneling

In addition to the transport protocol, the Tunnel field controls whether RTSP is wrapped inside another protocol:
ValueDescription
TunnelNonePlain RTSP (default).
TunnelHTTPRTSP-over-HTTP. Useful when only HTTP port 80 or 443 is open.
TunnelWebSocketRTSP-over-WebSocket. Useful for browser-based environments or proxies.
Tunneling via HTTP or WebSocket adds latency and reduces throughput compared to plain RTSP. Use it only when the network requires it.

Firewall considerations

UDP unicast requires the server to reach the client’s UDP ports for RTP and RTCP. If your client is behind a NAT or firewall that blocks inbound UDP, packets will never arrive and the library will fall back to TCP after InitialUDPReadTimeout. Use TCP directly if you know UDP is blocked.
UDP-multicast requires network infrastructure that supports IGMP snooping and multicast routing. It is generally only available on managed local-area networks.

Build docs developers (and LLMs) love