gortsplib

repository·main·Indexed 21 days ago

https://github.com/bluenviron/gortsplib

A comprehensive RTSP client and server library for Go, used as a core component in MediaMTX. It supports RTSP 1.0 and 2.0, ONVIF streaming specifications, and secure protocols including RTSPS, SRTP, and SRTCP. The library provides tunneling via HTTP and WebSockets, and includes built-in encoders and decoders for a wide range of RTP payload formats across video (AV1, H264, H265, VP8, VP9), audio (Opus, AAC, MP3, G711), and other formats like MPEG-TS and KLV.

Tokens
18.2K
Snippets
44
Records
76
Agent score
75%

What's inside gortsplib

  1. Overview of gortsplib features

    main

    gortsplib is an RTSP client and server library for the Go programming language. It is designed for high-performance media streaming and is used by projects like MediaMTX.

    Client Capabilities

    • Security: Supports RTSPS, SRTP, and SRTCP.
    • Tunneling: Supports RTSP-over-HTTP and RTSP-over-WebSocket.
    • Stream Management: Query available media, read streams ("play") using UDP, UDP-multicast, or TCP, and write streams ("record") using UDP or TCP. It features automatic transport protocol switching.
    • Control: Supports pausing, seeking, and writing to ONVIF back channels without disconnecting.
    • Metadata: Provides access to PTS (presentation timestamp) and NTP (absolute timestamp) for inbound packets.

    Server Capabilities

    • Security: Supports RTSPS, SRTP, and SRTCP.
    • Tunneling: Supports RTSP-over-HTTP and RTSP-over-WebSocket.
    • Client Handling: Validates credentials and handles requests from clients.
    • Media Handling: Can read streams from clients ("record") and serve streams to clients ("play"). It can compute SSRC and RTP-Info and read ONVIF back channels.

    Utilities

    • Parses RTSP elements.
    • Encodes/decodes RTP packets into/from codec-specific frames.
  2. Implement custom RTSP handlers for GetParameter and SetParameter

    main

    The ServerSession can delegate GET_PARAMETER and SET_PARAMETER requests to a custom handler if the server's handler implements the corresponding interfaces:

    • ServerHandlerOnGetParameter: Implement OnGetParameter(ctx *ServerHandlerOnGetParameterCtx) to handle parameter queries.
    • ServerHandlerOnSetParameter: Implement OnSetParameter(ctx *ServerHandlerOnSetParameterCtx) to handle parameter updates.

    If the handler does not implement these, the server returns 405 Not Implemented (except for GET_PARAMETER which may return 200 OK with an empty body as a fallback/ping).

  3. Handle RTP and RTCP decoding errors

    main

    When decoding errors occur during RTP or RTCP packet processing, gortsplib attempts to notify the server handler. If your server implementation satisfies the ServerHandlerOnDecodeError interface, you can intercept these errors to perform custom logging or monitoring.

    To implement this, include the OnDecodeError method in your handler:

    type MyHandler struct{}
    
    func (h *MyHandler) OnDecodeError(ctx *liberrors.ServerHandlerOnDecodeErrorCtx) {
    	fmt.Printf("Error in session %v: %v\n", ctx.Session, ctx.Error)
    }
    type MyHandler struct{}
    
    func (h *MyHandler) OnDecodeError(ctx *liberrors.ServerHandlerOnDecodeErrorCtx) {
    	fmt.Printf("Error in session %v: %v\n", ctx.Session, ctx.Error)
    }
  4. Implement a custom ServerHandler

    main

    To customize the behavior of a gortsplib server, you can implement one or more of the ServerHandler interfaces. The library uses a modular interface approach where you only need to implement the specific lifecycle or request methods you are interested in.

    Commonly used interfaces include:

    • ServerHandlerOnConnOpen / ServerHandlerOnConnClose: Handle connection-level events.
    • ServerHandlerOnSessionOpen / ServerHandlerOnSessionClose: Handle RTSP session lifecycle.
    • ServerHandlerOnDescribe: Handle DESCRIBE requests (must return a *base.Response and *ServerStream).
    • ServerHandlerOnSetup: Handle SETUP requests (must return a *base.Response and *ServerStream).
    • ServerHandlerOnPlay / ServerHandlerOnPause / ServerHandlerOnRecord: Handle media control requests.
    • ServerHandlerOnPacketsLost: Handle notifications when the server detects lost packets.
    • ServerHandlerOnDecodeError: Handle non-fatal decoding errors.

    Each method receives a specific context struct (e.g., ServerHandlerOnDescribeCtx) containing the relevant metadata like the Conn, Session, Request, Path, and Query.

    type myHandler struct{}
    
    // Handle DESCRIBE requests
    func (h *myHandler) OnDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx) (*base.Response, *gortsplib.ServerStream, error) {
    	// Return your response and the stream for the client
    	return &base.Response{StatusCode: base.StatusOK}, nil, nil
    }
    
    // Handle PLAY requests
    func (h *myHandler) OnPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base.Response, error) {
    	// Logic for starting playback
    	return &base.Response{StatusCode: base.StatusOK}, nil
    }
  5. Implement RTSP over HTTP tunneling using clientTunnelHTTP

    main

    The clientTunnelHTTP type implements the net.Conn interface to facilitate RTSP communication over an HTTP tunnel. It uses a dual-connection approach: one connection for reading (via a GET request) and another for writing (via a POST request).

    Note: clientTunnelHTTP is an internal implementation detail and is initialized via the newClientTunnelHTTP function. It handles the necessary HTTP headers such as X-Sessioncookie (using a unique UUID), Accept: application/x-rtsp-tunnelled, and Content-Type: application/x-rtsp-tunnelled to establish the tunnel.

    Key behaviors:

    • Reading: Data is read from the connection established by the GET request.
    • Writing: Data written to the connection is automatically Base64 encoded before being sent over the POST request.
    • Security: Supports TLS/SSL configuration if secure is set to true.
  6. Understand ServerSessionState lifecycle

    main

    A ServerSession transitions through several states during its lifecycle. Understanding these states is crucial for implementing custom handlers that respond to RTSP methods like SETUP, PLAY, RECORD, and PAUSE.

    The available states are:

    • ServerSessionStateInitial: The starting state.
    • ServerSessionStatePrePlay: After SETUP for a play session, but before PLAY is called.
    • ServerSessionStatePlay: The session is actively playing media.
    • ServerSessionStatePreRecord: After SETUP for a record session, but before RECORD is called.
    • ServerSessionStateRecord: The session is actively recording media.
  7. Implement WebSocket tunneling for RTSP servers

    main

    The gortsplib package provides internal types to facilitate tunneling RTSP traffic over WebSockets. This is typically used when an RTSP server needs to be accessible through a WebSocket proxy or when bypassing restrictive firewalls that only allow HTTP/WebSocket traffic.

    While the specific implementation details like wsNetConn, wsResponseWriter, wsReader, and wsWriter are internal to the package's tunneling logic, they allow an RTSP server to treat a WebSocket connection as a standard net.Conn or http.ResponseWriter via the Hijack() method.

  8. Handle client-side errors in gortsplib

    main

    The liberrors package defines a set of specific error types that can be returned by a client during RTSP operations. Developers can use type assertions or errors.As to identify specific failure scenarios such as transport issues, protocol violations, or server-requested protocol switches.

    Common error categories include:

    • State & Protocol Errors: ErrClientInvalidState, ErrClientUnhandledMethod, ErrClientSDPInvalid.
    • Transport Errors: ErrClientUDPTimeout, ErrClientTCPTimeout, ErrClientRequestTimedOut, ErrClientSwitchToTCPDueToNoUDP.
    • Header & Content Errors: ErrClientSessionHeaderInvalid, ErrClientContentTypeUnsupported, ErrClientTransportHeaderInvalid.
    • Payload & Packet Errors: ErrClientRTPPacketUnknownPayloadType, ErrClientRTCPPacketTooBig, ErrClientH264PacketizationMode0.
  9. Manage media streams with ServerStream

    main

    The ServerStream type is responsible for managing a media stream within a RTSP server. It handles:

    • Storing the stream description (*description.Session) and statistics.
    • Distributing media to multiple readers (clients).
    • Allocating and managing multicast listeners.

    To use a ServerStream, you typically interact with it through the Server instance, but you can manually call Initialize() to set up the internal media structures and SSRC generation.

    var st *gortsplib.ServerStream
    // ... st is initialized via the Server ...
  10. Understand RTP packet handling in server sessions

    main

    The serverSessionFormat manages the lifecycle of RTP packets for a specific media format during a RTSP session. It handles two primary directions:

    Inbound RTP (Receiving)

    When packets are received via readPacketRTP:

    1. SSRC Validation: The first packet received sets the expected remoteSSRC. Subsequent packets are checked against this SSRC. If encryption (SRTP) is enabled, a mismatch triggers a decode error.
    2. Decoding: The payload is decoded using the session's media decoder.
    3. Receiver Processing: Packets are passed to an rtpreceiver.Receiver to track sequence numbers, jitter, and packet loss.
    4. Loss Notification: If packet loss is detected, the server triggers the OnPacketsLost handler if the session handler implements ServerHandlerOnPacketsLost.
    5. Callback: Validated packets are passed to the onPacketRTP callback.

    Outbound RTP (Sending)

    When packets are sent via writePacketRTP:

    1. SSRC Assignment: The packet's SSRC is set to the localSSRC.
    2. Encryption: If SRTP is configured (srtpOutCtx is present), the packet is encrypted.
    3. Sender Processing: The packet is passed to an rtpsender.Sender to manage sequence numbers and timing.
    4. Queueing: The payload is pushed to the session's writer queue. If the queue is full, it returns liberrors.ErrServerWriteQueueFull.
    5. Transport: Depending on the session protocol, packets are written via UDP (writePacketRTPInQueueUDP) or interleaved TCP (writePacketRTPInQueueTCP).
  11. Configure and start a gortsplib Server

    main

    The Server struct is the main entrypoint for an RTSP server. You must provide at least the RTSPAddress. You can optionally configure UDP transport (RTP/RTCP), multicast support, TLS, and authentication methods.

    Key Configuration Options

    • RTSPAddress: The address to accept TCP connections (e.g., ":8554").
    • UDPRTPAddress & UDPRTCPAddress: Required together to enable UDP transport. The RTP port must be even, and the RTCP port must be the consecutive odd port (e.g., RTP: ":8000", RTCP: ":8001").
    • MulticastIPRange, MulticastRTPPort, & MulticastRTCPPort: Required together to enable UDP-multicast. The RTP port must be even and RTCP must be consecutive.
    • TLSConfig: Provide a *tls.Config to enable RTSPS (TLS).
    • AuthMethods: A slice of auth.VerifyMethod. Defaults to auth.VerifyMethodBasic and auth.VerifyMethodDigestMD5 if not specified.
    • Handler: An optional ServerHandler to react to server events.

    Lifecycle Methods

    • Start(): Initializes listeners and starts the server loop in a background goroutine.
    • StartAndWait(): Starts the server and blocks until a fatal error occurs or the server is closed.
    • Close(): Gracefully shuts down the server and waits for all resources to exit.
    • Wait(): Blocks until the server has finished shutting down (either via Close() or a fatal error).
    server := &gortsplib.Server{
    	RTSPAddress:    ":8554",
    	UDPRTPAddress:  ":8000",
    	UDPRTCPAddress: ":8001",
    }
    
    // Start and block until error
    err := server.StartAndWait()
    if err != nil {
    	panic(err)
    }