media

package
v0.42.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2026 License: MPL-2.0 Imports: 36 Imported by: 6

README

media

Implemented:

Everything is io.Reader and io.Writer

We follow GO std lib and providing interface for Reader/Writer when it comes reading and writing media.
This optimized and made easier usage of RTP framework, by providing end user standard library io.Reader io.Writer to pass his media.

In other words chaining reader or writer allows to build interceptors, encoders, decoders without introducing overhead of contention or many memory allocations

Features:

  • Simple SDP build with formats alaw,ulaw,dtmf
  • RTP/RTCP receiving and logging
  • Extendable MediaSession handling for RTP/RTCP handling (ex microphone,speaker)
  • DTMF encoder, decoder via RFC4733
  • Minimal SDP package for audio
  • Media Session, RTP Session handling
  • RTCP monitoring
  • SDP codec fields manipulating
  • ... who knows

Concepts

  • Media Session represents mapping between SDP media description and creates session based on local/remote addr
  • RTP Session is creating RTP/RTCP session. It is using media session underneath to add networking layer.
  • RTP Packet Reader is depackatizing RTP packets and providing payload as io.Reader. Normally it should be chained to RTP Session
  • RTP Packet Writer is packatizing payload to RTP packets as io.Writer. Normally it should be chained to RTP Session

IO flow

Reader: AudioDecoder<->RTPPacketReader<->RTPSession<->MediaSession

Writer: AudioEncoder<->RTPPackerWriter<->RTPSession<->MediaSession

more docs...

Documentation

Overview

Example (Audio2RTPGenerator)

Example on how to generate RTP packets from audio bytes

package main

import (
	"bytes"
	"fmt"
	"os"

	"github.com/pion/rtp"
)

type rtpBuffer struct {
	buf []rtp.Packet
}

func (b *rtpBuffer) WriteRTP(p *rtp.Packet) error {
	b.buf = append(b.buf, *p)
	return nil
}

// Example on how to generate RTP packets from audio bytes
func main() {
	// Create some audio
	audioAlawBuf := make([]byte, 4*160)
	copy(audioAlawBuf, bytes.Repeat([]byte("0123456789"), CodecAudioAlaw.Samples16()*2/10))

	// Create Packet writer and pass RTP buff
	rtpBuf := &rtpBuffer{}
	rtpGenerator := NewRTPPacketWriter(rtpBuf, CodecAudioAlaw)
	WriteAll(rtpGenerator, audioAlawBuf, 160)

	// Now we have RTP packets ready to use from audio
	for _, p := range rtpBuf.buf {
		fmt.Fprint(os.Stderr, p.String())
	}
	fmt.Println(len(rtpBuf.buf))
}
Output:
4

Index

Examples

Constants

View Source
const (
	ServerClientAuthNoCert      = int(dtls.NoClientCert)
	ServerClientAuthRequireCert = int(dtls.RequestClientCert)

	EllipticCurveP256   uint16 = uint16(elliptic.P256)
	EllipticCurveP384   uint16 = uint16(elliptic.P384)
	EllipticCurveX25519 uint16 = uint16(elliptic.X25519)
)
View Source
const (
	DefaultICEDisconnectedTimeout = 5 * time.Second
	DefaultICEFailedTimeout       = 25 * time.Second
	DefaultICEKeepaliveInterval   = 2 * time.Second
)
View Source
const (
	SRTPProfileAes128CmHmacSha1_80 uint16 = uint16(srtp.ProtectionProfileAes128CmHmacSha1_80)
	SRTPProfileAes256CmHmacSha1_80 uint16 = uint16(srtp.ProtectionProfileAes256CmHmacSha1_80)
	SRTPProfileAeadAes128Gcm       uint16 = uint16(srtp.ProtectionProfileAeadAes128Gcm)
	SRTPProfileAeadAes256Gcm       uint16 = uint16(srtp.ProtectionProfileAeadAes256Gcm)
	SRTPProfileNullHmacSha1_80     uint16 = uint16(srtp.ProtectionProfileNullHmacSha1_80)
)

Variables

View Source
var (
	// Here are some codec constants that can be reused
	CodecAudioUlaw          = Codec{PayloadType: 0, SampleRate: 8000, SampleDur: 20 * time.Millisecond, NumChannels: 1, Name: "pcmu"}
	CodecAudioAlaw          = Codec{PayloadType: 8, SampleRate: 8000, SampleDur: 20 * time.Millisecond, NumChannels: 1, Name: "pcma"}
	CodecAudioOpus          = Codec{PayloadType: 96, SampleRate: 48000, SampleDur: 20 * time.Millisecond, NumChannels: 2, Name: "opus"}
	CodecTelephoneEvent8000 = Codec{PayloadType: 101, SampleRate: 8000, SampleDur: 20 * time.Millisecond, NumChannels: 1, Name: "telephone-event"}
	// CodecComfortNoise8000 describes the static RFC 3389 comfort-noise payload.
	// It is an auxiliary RTP format and is not included in default SDP offers.
	CodecComfortNoise8000 = Codec{PayloadType: 13, SampleRate: 8000, NumChannels: 1, Name: "cn"}
)
View Source
var (
	// RTPPortStart and RTPPortEnd allows defining rtp port range for media
	RTPPortStart = 0
	RTPPortEnd   = 0

	// When reading RTP use at least MTU size. Increase this
	RTPBufSize = 1500

	RTPDebug  = false
	RTCPDebug = false

	// RTPProfileSAVPDisable disables offering RTP/SAVP and keeps standard RTP/AVP for backward compatibilit needs
	//
	// Experimental
	RTPProfileSAVPDisable = false

	// RTPNAT options
	RTPNATDisabled = 0
	RTPNATSymetric = 1

	// SDP codec exchanges
	// 0 (Default) - answerer prefers offerer order recomended by rfc
	// 1 - answerer prefers local order
	SDPCodecPreferLocalOrder int = 0
)
View Source
var (
	ErrICEGathering  = errors.New("ICE candidate gathering failed")
	ErrICEConnection = errors.New("ICE connection failed")
)
View Source
var (
	ErrRTPSequenceOutOfOrder = errors.New("out of order")
	ErrRTPSequenceBad        = errors.New("bad sequence")
	ErrRTPSequnceDuplicate   = errors.New("sequence duplicate")
)
View Source
var (
	DefaultOnReadRTCP  func(pkt rtcp.Packet, rtpStats RTPReadStats)  = nil
	DefaultOnWriteRTCP func(pkt rtcp.Packet, rtpStats RTPWriteStats) = nil

	// RTPSourceLock enables source locking after IP changes
	RTPSourceLock bool
)
View Source
var (
	DTLSDebug bool
)
View Source
var ErrWebRTCICERestart = errors.New("remote WebRTC SDP starts a new ICE generation")

ErrWebRTCICERestart reports that a subsequent SDP changed both remote ICE credentials and therefore needs a replacement MediaSessionWebrtc transport.

Functions

func CodecsFromSDPRead added in v0.14.0

func CodecsFromSDPRead(formats []string, attrs []string, codecsAudio []Codec) (int, error)

CodecsFromSDP will try to parse as much as possible, but it will return also error in case some properties could not be read You can take what is parsed or return error

func Copy added in v0.4.0

func Copy(reader io.Reader, writer io.Writer) (int64, error)

Copy is like io.Copy but it uses buffer size needed for RTP

func CopyWithBuf added in v0.1.1

func CopyWithBuf(reader io.Reader, writer io.Writer, payloadBuf []byte) (int64, error)

CopyWithBuf is simple and strict compared to io.CopyBuffer. ReadFrom and WriteTo is not considered and due to RTP buf requirement it can lead to different buffer size passing

func DTMFDecode

func DTMFDecode(payload []byte, d *DTMFEvent) error

DecodeRTPPayload decodes an RTP payload into a DTMF event

func DTMFEncode

func DTMFEncode(d DTMFEvent) []byte

func DTMFToRune added in v0.1.1

func DTMFToRune(dtmf uint8) rune

func DefaultLogger added in v0.19.0

func DefaultLogger() *slog.Logger

func ErrorIsTimeout added in v0.1.1

func ErrorIsTimeout(err error) bool

func FractionLostFloat

func FractionLostFloat(f uint8) float64

func GetCurrentNTPTimestamp

func GetCurrentNTPTimestamp() uint64

func NTPTimestamp

func NTPTimestamp(t time.Time) uint64

func NTPToTime

func NTPToTime(ntpTimestamp uint64) time.Time

func RTCPUnmarshal

func RTCPUnmarshal(data []byte, packets []rtcp.Packet) (n int, err error)

RTCPUnmarshal is improved version based on pion/rtcp where we allow caller to define and control buffer of rtcp packets. This also reduces one allocation NOTE: data is still referenced in packet buffer

func RTPDebugTracer added in v0.32.0

func RTPDebugTracer(t RTPTracer)

RTPDebugTracer sets the tracer used when RTPDebug is enabled. Passing nil restores the default RTP debug logging. It must be called before RTP traffic starts.

func RTPUnmarshal

func RTPUnmarshal(buf []byte, p *rtp.Packet) error

RTPUnmarshal wrapper for now used for optimizing unmarshal NOTE: payload is referencing on packet buffer

func ReadAll added in v0.13.0

func ReadAll(reader io.Reader, sampleSize int) ([]byte, error)

func SetDefaultLogger added in v0.19.0

func SetDefaultLogger(l *slog.Logger)

SetDefaultLogger sets default logger that will be used withing sip package Must be called before any usage of library

func StringRTCP added in v0.2.0

func StringRTCP(p rtcp.Packet) string

func WriteAll added in v0.13.0

func WriteAll(w io.Writer, data []byte, sampleSize int) (int64, error)

Types

type Codec

type Codec struct {
	Name        string
	PayloadType uint8
	SampleRate  uint32
	SampleDur   time.Duration
	NumChannels int // 1 or 2
	// contains filtered or unexported fields
}

func CodecAudioFromList added in v0.18.0

func CodecAudioFromList(codecs []Codec) (Codec, bool)

func CodecAudioFromPayloadType added in v0.12.0

func CodecAudioFromPayloadType(payloadType uint8) (Codec, error)

func CodecAudioFromSession added in v0.18.0

func CodecAudioFromSession(s *MediaSession) Codec

func CodecFromPayloadType deprecated

func CodecFromPayloadType(payloadType uint8) Codec

Deprecated: Use CodecAudioFromPayloadType

func CodecFromSession deprecated

func CodecFromSession(s *MediaSession) Codec

Deprecated: Use CodecAudioFromSession

func (Codec) IsAuxiliary added in v0.41.0

func (c Codec) IsAuxiliary() bool

IsAuxiliary reports whether c is an auxiliary RTP format (RFC 4733 events, RFC 3389 comfort noise) carried beside the audio rather than decoded as it.

func (Codec) Matches added in v0.42.0

func (c Codec) Matches(other Codec) bool

Matches compares codec identity independently of payload type and packet duration.

func (Codec) PayloadTypeRecv added in v0.42.0

func (c Codec) PayloadTypeRecv() uint8

PayloadTypeRecv returns the receive payload type of a negotiated codec. It equals PayloadType unless the peer answered with a different mapping.

func (*Codec) SampleTimestamp

func (c *Codec) SampleTimestamp() uint32

SampleTimestamp returns number of samples as RTP Timestamp measure

func (*Codec) Samples16 added in v0.12.0

func (c *Codec) Samples16() int

Samples16 returns PCM 16 bit samples size

func (*Codec) SamplesPCM added in v0.12.0

func (c *Codec) SamplesPCM(bitSize int) int

Samples is samples in pcm

func (*Codec) String added in v0.2.0

func (c *Codec) String() string

type DTLSConfig added in v0.26.0

type DTLSConfig struct {
	Certificates []tls.Certificate
	// If used as client this would verify server certificate
	ServerName string

	// ServerClientAuth determines the server's policy for
	// TLS Client Authentication. The default is ServerClientAuthNoCert.
	// Check ServerClientAuth
	ServerClientAuth int

	// SRTPProfiles to use in exchange. Check constant vars with media.SRTPProfile...
	SRTPProfiles []uint16

	// SDP Setup Role force value.
	// Values: active,passive,actpass
	// Default: offer->active answer->passive
	SDPSetupRole func(offer bool) string `json:"-"`

	// List of Elliptic Curves to use
	//
	// If an ECC ciphersuite is configured and EllipticCurves is empty
	// it will default to X25519, P-256, P-384 in this specific order.
	// Check values with media.Eliptic<name>
	EllipticCurves []uint16
}

func (*DTLSConfig) ToLibConf added in v0.27.0

func (conf *DTLSConfig) ToLibConf(fingerprints []DTLSFingerprint) *dtls.Config

type DTLSFingerprint added in v0.40.0

type DTLSFingerprint struct {
	Value     string
	Algorithm string
}

DTLSFingerprint identifies a peer certificate fingerprint advertised in SDP.

type DTMFEvent

type DTMFEvent struct {
	Event      uint8
	EndOfEvent bool
	Volume     uint8
	Duration   uint16
}

DTMFEvent represents a DTMF event

func RTPDTMFEncode8000 added in v0.18.0

func RTPDTMFEncode8000(char rune) []DTMFEvent

RTPDTMFEncode8000 creates series of DTMF redudant events which should be encoded as payload It is currently only 8000 sample rate considered for telophone event

func (*DTMFEvent) String

func (ev *DTMFEvent) String() string

type ICECandidateType added in v0.40.0

type ICECandidateType uint8

ICECandidateType selects which kinds of UDP ICE candidates are gathered.

const (
	ICECandidateHost ICECandidateType = iota + 1
	ICECandidateServerReflexive
	ICECandidateRelay
)

type ICEError added in v0.40.0

type ICEError struct {
	Phase ICEPhase
	Err   error
}

ICEError reports an ICE failure with enough information for callers to distinguish configuration/gathering, initial connection and later liveness failures. errors.Is works with ErrICEGathering and ErrICEConnection; errors.As exposes the phase and underlying error.

func (*ICEError) Error added in v0.40.0

func (e *ICEError) Error() string

func (*ICEError) Is added in v0.40.0

func (e *ICEError) Is(target error) bool

func (*ICEError) Unwrap added in v0.40.0

func (e *ICEError) Unwrap() error

type ICEIPFamily added in v0.40.0

type ICEIPFamily uint8

ICEIPFamily selects the IP families used to gather UDP ICE candidates.

const (
	ICEIPFamilyIPv4 ICEIPFamily = iota + 1
	ICEIPFamilyIPv6
)

type ICEPhase added in v0.40.0

type ICEPhase uint8

ICEPhase identifies the part of ICE that produced an ICEError.

const (
	ICEPhaseGathering ICEPhase = iota + 1
	ICEPhaseConnection
)

func (ICEPhase) String added in v0.40.0

func (p ICEPhase) String() string

type ICETimeouts added in v0.40.0

type ICETimeouts struct {
	Disconnected time.Duration
	Failed       time.Duration
	Keepalive    time.Duration
}

ICETimeouts controls ICE connection establishment and liveness detection. Zero values use the defaults below.

type MediaSession

type MediaSession struct {

	// Codecs are the configured local capabilities used to negotiate SDP.
	// Negotiation leaves this list unchanged; CommonCodecs returns the result.
	Codecs []Codec

	// Mode is sdp mode. Check consts sdp.ModeRecvOnly etc...
	Mode string
	// Laddr our local address which has full IP and port after media session creation
	Laddr net.UDPAddr
	// Raddr is our target remote address. Normally it is resolved by SDP parsing.
	Raddr net.UDPAddr
	// ExternalIP that should be used for building SDP
	ExternalIP net.IP

	SecureRTP int // 0 none, 1 - SDES, 2 - DTLS
	// TODO support multile for offering
	SRTPAlg uint16

	// DTLSConf used for DTLS
	DTLSConf DTLSConfig

	// RTP NAT enables handling RTP behind NAT. Checkout also RTPSourceLock
	RTPNAT int // 0 - disabled, 1 - Learn source change (RTP Symetric)

	// ReadRTPFromAddr is set after Read operation. NOT THREAD SAFE and should be only used together with Read
	// It can be used to validate source of RTP packet
	ReadRTPFromAddr net.Addr
	// contains filtered or unexported fields
}

func NewMediaSession

func NewMediaSession(ip net.IP, port int) (s *MediaSession, e error)

func (*MediaSession) Close

func (s *MediaSession) Close() error

func (*MediaSession) CommonCodecs added in v0.18.0

func (s *MediaSession) CommonCodecs() []Codec

CommonCodecs returns common codecs if negotiation is finished, that is Local and Remote SDP are exchanged NOTE: Not thread safe, should be called after negotiation Only!

func (*MediaSession) Finalize added in v0.26.0

func (s *MediaSession) Finalize() error

Finalize finalizes negotiation and does verification Should be called only after exchage of SDP is done

func (*MediaSession) Fork

func (s *MediaSession) Fork() *MediaSession

Fork is special call to be used in case when there is session update It preserves connections and negotiated SDES contexts for media updates.

func (*MediaSession) Init added in v0.7.0

func (s *MediaSession) Init() error

Init should be called if session is created manually Use NewMediaSession for default building

func (*MediaSession) InitWithListeners added in v0.13.0

func (s *MediaSession) InitWithListeners(lRTP net.PacketConn, lRTCP net.PacketConn, raddr *net.UDPAddr)

func (*MediaSession) InitWithSDP added in v0.20.0

func (s *MediaSession) InitWithSDP(localSDP []byte) error

InitWithSDP allows creating media session with own SDP and bypassing other needs

func (*MediaSession) LocalSDP

func (s *MediaSession) LocalSDP(answered bool) []byte

LocalSDP generates an offer when answered is false, or an answer when true. It should never be called in parallel to RemoteSDP, as it is expected serial process

func (*MediaSession) ReadRTCP

func (m *MediaSession) ReadRTCP(buf []byte, pkts []rtcp.Packet) (n int, err error)

ReadRTCP is optimized reads and unmarshals RTCP packets. Buffers is only used for unmarshaling. Caller needs to be aware of size this buffer and allign with MTU

func (*MediaSession) ReadRTCPRaw

func (m *MediaSession) ReadRTCPRaw(buf []byte) (int, net.Addr, error)

func (*MediaSession) ReadRTCPRawDeadline

func (m *MediaSession) ReadRTCPRawDeadline(buf []byte, t time.Time) (int, error)

func (*MediaSession) ReadRTP

func (m *MediaSession) ReadRTP(buf []byte, pkt *rtp.Packet) (int, error)

ReadRTP reads data from network and parses to pkt buffer is passed in order to avoid extra allocs

func (*MediaSession) ReadRTPRaw

func (m *MediaSession) ReadRTPRaw(buf []byte) (int, error)

func (*MediaSession) ReadRTPRawDeadline

func (m *MediaSession) ReadRTPRawDeadline(buf []byte, t time.Time) (int, error)

func (*MediaSession) RemoteSDP

func (s *MediaSession) RemoteSDP(sdpReceived []byte, offered bool) error

RemoteSDP applies an answer when offered is true, or an offer when false. NOTE: It must called ONCE or single thread while negotiation happening. For multi negotiation Fork Must be called before

func (*MediaSession) SetRemoteAddr

func (s *MediaSession) SetRemoteAddr(raddr *net.UDPAddr)

SetRemoteAddr is helper to set Raddr and rtcp address. It is not thread safe

func (*MediaSession) StartRTP added in v0.1.1

func (s *MediaSession) StartRTP(rw int8) error

func (*MediaSession) StopRTP added in v0.1.1

func (s *MediaSession) StopRTP(rw int8, dur time.Duration) error

func (*MediaSession) String added in v0.27.0

func (s *MediaSession) String() string

func (*MediaSession) WriteRTCP

func (m *MediaSession) WriteRTCP(p rtcp.Packet) error

func (*MediaSession) WriteRTCPDeadline

func (m *MediaSession) WriteRTCPDeadline(p rtcp.Packet, deadline time.Time) error

func (*MediaSession) WriteRTCPRaw

func (m *MediaSession) WriteRTCPRaw(data []byte) (int, error)

func (*MediaSession) WriteRTCPs

func (m *MediaSession) WriteRTCPs(pkts []rtcp.Packet) error

Use this to write Multi RTCP packets if they can fit in MTU=1500

func (*MediaSession) WriteRTP

func (m *MediaSession) WriteRTP(p *rtp.Packet) error

func (*MediaSession) WriteRTPRaw

func (m *MediaSession) WriteRTPRaw(data []byte) (n int, err error)

type MediaSessionWebrtc added in v0.40.0

type MediaSessionWebrtc struct {
	Laddr  string
	Raddr  string
	Codecs []Codec
	Mode   string

	Config MediaSessionWebrtcConfig
	// contains filtered or unexported fields
}

MediaSessionWebrtc is the direct ICE + DTLS-SRTP media stack. It intentionally does not embed MediaSession: legacy RTP uses two known UDP destinations, whereas WebRTC must send every DTLS/SRTP/SRTCP packet through the candidate pair selected and consent-checked by ICE.

Signalling lifecycle:

  • Init gathers local candidates (non-trickle ICE).
  • LocalSDP(false) creates an offer, or RemoteSDP(..., false) consumes one.
  • RemoteSDP starts ICE as controlling for a local offer and controlled for a local answer. It returns before connectivity checks finish.
  • Finalize waits for ICE, performs DTLS, verifies the SDP fingerprint and derives the SRTP keys. RTP must not be used before Finalize succeeds.

func (*MediaSessionWebrtc) Close added in v0.40.0

func (m *MediaSessionWebrtc) Close() error

func (*MediaSessionWebrtc) Codec added in v0.40.0

func (m *MediaSessionWebrtc) Codec() Codec

func (*MediaSessionWebrtc) CommonCodecs added in v0.40.0

func (m *MediaSessionWebrtc) CommonCodecs() []Codec

func (*MediaSessionWebrtc) Finalize added in v0.40.0

func (m *MediaSessionWebrtc) Finalize(ctx context.Context) error

Finalize completes ICE first and DTLS second. This order is the central WebRTC layering rule: ICE selects and maintains the network path; DTLS and all encrypted media then travel only over that path.

func (*MediaSessionWebrtc) Fork added in v0.40.0

Fork creates a fresh WebRTC transport for a locally initiated ICE restart. Codec and configuration slices are copied because SDP negotiation mutates the session's codec list, while certificates and filters remain immutable config.

func (*MediaSessionWebrtc) Init added in v0.40.0

func (m *MediaSessionWebrtc) Init(
	ctx context.Context,
	conf MediaSessionWebrtcConfig,
	onICEStateChange ...func(ice.ConnectionState),
) error

Init creates the ICE agent and waits for candidate gathering to finish. SIP offer/answer has no standard trickle-ICE exchange, so the SDP returned later contains a complete candidate set and a=end-of-candidates.

func (*MediaSessionWebrtc) LocalSDP added in v0.40.0

func (m *MediaSessionWebrtc) LocalSDP(_ context.Context, answered bool) ([]byte, error)

LocalSDP returns a complete, non-trickle WebRTC SDP. answered controls the DTLS setup attribute: an offer is actpass; an answer uses the role selected while parsing the remote offer.

func (*MediaSessionWebrtc) ReadRTCP added in v0.40.0

func (m *MediaSessionWebrtc) ReadRTCP(buf []byte, pkts []rtcp.Packet) (int, error)

func (*MediaSessionWebrtc) ReadRTP added in v0.40.0

func (m *MediaSessionWebrtc) ReadRTP(buf []byte, pkt *rtp.Packet) (int, error)

func (*MediaSessionWebrtc) ReadRTPRaw added in v0.40.0

func (m *MediaSessionWebrtc) ReadRTPRaw(buf []byte) (int, error)

func (*MediaSessionWebrtc) RemoteSDP added in v0.40.0

func (m *MediaSessionWebrtc) RemoteSDP(_ context.Context, body []byte, offered bool) error

RemoteSDP parses an answer when offered is true, otherwise it parses an offer. Starting ICE here is non-blocking so a SIP answer can be sent before the browser is required to complete connectivity checks.

func (*MediaSessionWebrtc) Rollback added in v0.40.0

func (m *MediaSessionWebrtc) Rollback()

Rollback drops a staged same-ICE-generation media update. It does not touch the active ICE, DTLS, SRTP or SRTCP transports.

func (*MediaSessionWebrtc) StartRTP added in v0.40.0

func (m *MediaSessionWebrtc) StartRTP(rw int8) error

func (*MediaSessionWebrtc) StopRTP added in v0.40.0

func (m *MediaSessionWebrtc) StopRTP(rw int8, duration time.Duration) error

func (*MediaSessionWebrtc) WriteRTCP added in v0.40.0

func (m *MediaSessionWebrtc) WriteRTCP(pkt rtcp.Packet) error

func (*MediaSessionWebrtc) WriteRTP added in v0.40.0

func (m *MediaSessionWebrtc) WriteRTP(pkt *rtp.Packet) error

type MediaSessionWebrtcConfig added in v0.40.0

type MediaSessionWebrtcConfig struct {
	ICEURLs        []string
	IPFamilies     []ICEIPFamily
	CandidateTypes []ICECandidateType
	PortMin        uint16
	PortMax        uint16
	Timeouts       ICETimeouts

	IncludeLoopback bool
	InterfaceFilter func(interfaceName string) bool
	// IPFilter controls which local addresses may become ICE candidates.
	IPFilter func(ip netip.Addr) bool
	// RemoteIPFilter controls which addresses from remote SDP are accepted.
	RemoteIPFilter func(ip netip.Addr) bool

	// NetworkTypes is kept for source compatibility. Only UDP4 and UDP6 are
	// accepted. New code should use IPFamilies so configuration is not tied to
	// the current ICE implementation.
	//
	// Deprecated: use IPFamilies.
	NetworkTypes []ice.NetworkType

	DTLS DTLSConfig
}

MediaSessionWebrtcConfig contains transport settings which do not belong to the codec-level media API. ICEURLs accepts STUN and TURN URLs understood by Pion (for example stun:stun.example.org:3478).

type MediaStreamer

type MediaStreamer interface {
	MediaStream(s *MediaSession) error
}

type OnRTPReadStats added in v0.10.0

type OnRTPReadStats func(stats RTPReadStats)

type OnRTPWriteStats added in v0.10.0

type OnRTPWriteStats func(stats RTPWriteStats)

type RTCPReader

type RTCPReader interface {
	ReadRTCP(buf []byte, pkts []rtcp.Packet) (n int, err error)
}

type RTCPWriter

type RTCPWriter interface {
	WriteRTCP(p rtcp.Packet) error
}

type RTCPWriterRaw

type RTCPWriterRaw interface {
	WriteRTCPRaw(buf []byte) (int, error) // -> io.Writer
}

type RTPCReaderRaw

type RTPCReaderRaw interface {
	ReadRTCPRaw(buf []byte) (int, error)
}

type RTPComfortNoiseWriter added in v0.40.0

type RTPComfortNoiseWriter struct {
	// contains filtered or unexported fields
}

RTPComfortNoiseWriter adds explicit RFC 3389 comfort-noise packets to an RTP audio stream. It does not schedule packets or verify SDP negotiation.

func NewRTPComfortNoiseWriter added in v0.40.0

func NewRTPComfortNoiseWriter(packetWriter *RTPPacketWriter, writer io.Writer) *RTPComfortNoiseWriter

NewRTPComfortNoiseWriter adds explicit comfort-noise writes to writer while keeping them on packetWriter's SSRC and RTP timeline.

func (*RTPComfortNoiseWriter) Write added in v0.40.0

func (w *RTPComfortNoiseWriter) Write(payload []byte) (int, error)

Write forwards encoded audio and resumes the RTP clock after comfort noise.

func (*RTPComfortNoiseWriter) WriteComfortNoise added in v0.40.0

func (w *RTPComfortNoiseWriter) WriteComfortNoise(level uint8) error

WriteComfortNoise sends one zero-order RFC 3389 Silence Insertion Descriptor. Level is attenuation in -dBov and must be between 0 and 127. The caller is responsible for deciding when packets should be sent.

type RTPDtmfReader added in v0.1.1

type RTPDtmfReader struct {
	// contains filtered or unexported fields
}

func NewRTPDTMFReader added in v0.1.1

func NewRTPDTMFReader(codec Codec, packetReader *RTPPacketReader, reader io.Reader) *RTPDtmfReader

RTP DTMF writer is midleware for reading DTMF events It reads from io Reader and checks packet Reader

func (*RTPDtmfReader) Read added in v0.1.1

func (w *RTPDtmfReader) Read(b []byte) (int, error)

Write is RTP io.Writer which adds more sync mechanism

func (*RTPDtmfReader) ReadDTMF added in v0.1.1

func (w *RTPDtmfReader) ReadDTMF() (rune, bool)

type RTPDtmfWriter added in v0.1.1

type RTPDtmfWriter struct {
	// contains filtered or unexported fields
}

func NewRTPDTMFWriter added in v0.1.1

func NewRTPDTMFWriter(codec Codec, rtpPacketizer *RTPPacketWriter, writer io.Writer) *RTPDtmfWriter

RTP DTMF writer is midleware for passing RTP DTMF event. If it is chained it uses to block writer while writing DTFM events

func (*RTPDtmfWriter) Write added in v0.1.1

func (w *RTPDtmfWriter) Write(b []byte) (int, error)

Write is RTP io.Writer which adds more sync mechanism

func (*RTPDtmfWriter) WriteDTMF added in v0.1.1

func (w *RTPDtmfWriter) WriteDTMF(dtmf rune) error

type RTPExtendedSequenceNumber

type RTPExtendedSequenceNumber struct {
	// contains filtered or unexported fields
}

RTPExtendedSequenceNumber is embedable/ replacable sequnce number generator For thread safety you should wrap it

func NewRTPSequencer

func NewRTPSequencer() RTPExtendedSequenceNumber

func (*RTPExtendedSequenceNumber) InitSeq

func (sn *RTPExtendedSequenceNumber) InitSeq(seq uint16)

func (*RTPExtendedSequenceNumber) NextSeqNumber

func (s *RTPExtendedSequenceNumber) NextSeqNumber() uint16

func (*RTPExtendedSequenceNumber) ReadExtendedSeq

func (sn *RTPExtendedSequenceNumber) ReadExtendedSeq() uint64

func (*RTPExtendedSequenceNumber) UpdateSeq

func (sn *RTPExtendedSequenceNumber) UpdateSeq(seq uint16) error

Based on https://datatracker.ietf.org/doc/html/rfc1889#appendix-A.2

type RTPJitterBuffer added in v0.31.0

type RTPJitterBuffer struct {
	// contains filtered or unexported fields
}

RTPJitterBuffer is a fixed-delay, single-consumer RTPReader wrapper.

It sits after RTPSession and before RTPPacketReader, so RTPSession observes true network arrival while downstream readers get reordered packets.

func NewRTPJitterBuffer added in v0.31.0

func NewRTPJitterBuffer(reader RTPReader, packetDuration time.Duration, opts RTPJitterBufferOptions) *RTPJitterBuffer

NewRTPJitterBuffer creates a fixed jitter buffer over another RTPReader. It panics if packetDuration is not greater than zero.

func (*RTPJitterBuffer) Close added in v0.31.0

func (j *RTPJitterBuffer) Close() error

Close stops jitter-buffer delivery. It does not close the injected reader.

func (*RTPJitterBuffer) ReadRTP added in v0.31.0

func (j *RTPJitterBuffer) ReadRTP(buf []byte, p *rtp.Packet) (int, error)

ReadRTP implements RTPReader. Calls must not overlap.

func (*RTPJitterBuffer) Statistics added in v0.31.0

Statistics returns a race-safe snapshot of jitter buffer counters.

type RTPJitterBufferOptions added in v0.31.0

type RTPJitterBufferOptions struct {
	// DelayPackets is the initial fixed playout delay in packets. If unset, 3 is used.
	DelayPackets int
	// MaxPackets caps buffered packets and the forward reordering window. If unset, 10 is used.
	MaxPackets int
}

RTPJitterBufferOptions configures a fixed RTP jitter buffer.

type RTPJitterBufferStatistics added in v0.31.0

type RTPJitterBufferStatistics struct {
	PacketsRead        uint64
	PacketsReleased    uint64
	PacketsLost        uint64
	PacketsLate        uint64
	PacketsDuplicate   uint64
	PacketsDropped     uint64
	SSRCResets         uint64
	LastSequenceNumber uint16
}

RTPJitterBufferStatistics contains simple counters for buffer decisions.

type RTPPacketReader

type RTPPacketReader struct {

	// PacketHeader is stored after calling Read
	// Safe to read only in same goroutine as Read
	PacketHeader rtp.Header
	// contains filtered or unexported fields
}

RTPPacketReader reads RTP packet and extracts payload and header

func NewRTPPacketReader

func NewRTPPacketReader(reader RTPReader, codec Codec) *RTPPacketReader

func NewRTPPacketReaderSession

func NewRTPPacketReaderSession(sess *RTPSession) *RTPPacketReader

NewRTPPacketReaderSession just helper constructor

func (*RTPPacketReader) Read

func (r *RTPPacketReader) Read(b []byte) (int, error)

Read Implements io.Reader and extracts Payload from RTP packet has no input queue or sorting control of packets Buffer is used for reading headers and after parsing Headers are stored in PacketHeader

NOTE: Consider that if you are passsing smaller buffer than RTP header+payload, io.ErrShortBuffer is returned

func (*RTPPacketReader) Reader

func (r *RTPPacketReader) Reader() RTPReader

func (*RTPPacketReader) UpdateRTPSession

func (r *RTPPacketReader) UpdateRTPSession(rtpSess *RTPSession)

func (*RTPPacketReader) UpdateReader added in v0.2.0

func (r *RTPPacketReader) UpdateReader(reader RTPReader)

type RTPPacketWriter

type RTPPacketWriter struct {

	// After each write packet header is saved for more reading
	PacketHeader rtp.Header

	// SSRC is readOnly and it is not changed
	SSRC uint32
	// contains filtered or unexported fields
}

RTPPacketWriter packetize any payload before pushing to active media session It creates SSRC as identifier and all packets sent will be with this SSRC For multiple streams, multiple RTP Writer needs to be created

func NewRTPPacketWriter

func NewRTPPacketWriter(writer RTPWriter, codec Codec) *RTPPacketWriter

RTPPacketWriter packetize payload in RTP packet before passing on media session Not having: - random Timestamp - allow different clock rate - CSRC contribution source - Silence detection and marker set updateClockRate- Padding and encryyption

func NewRTPPacketWriterSession

func NewRTPPacketWriterSession(sess *RTPSession) *RTPPacketWriter

NewRTPPacketWriterSession creates RTPPacketWriter and attaches RTP Session expected values

func (*RTPPacketWriter) ClockDisable added in v0.28.0

func (w *RTPPacketWriter) ClockDisable()

func (*RTPPacketWriter) ClockEnable added in v0.28.0

func (w *RTPPacketWriter) ClockEnable()

func (*RTPPacketWriter) DelayTimestamp added in v0.17.0

func (p *RTPPacketWriter) DelayTimestamp(ofsset uint32)

func (*RTPPacketWriter) InitTimestamp added in v0.17.0

func (p *RTPPacketWriter) InitTimestamp() uint32

InitTimestamp returns init RTP timestamp

func (*RTPPacketWriter) ResetTimestamp added in v0.17.0

func (p *RTPPacketWriter) ResetTimestamp()

ResetTimestamp can mark new stream comming. If stream is continuous it will add timestamp difference MUST Not be called during stream Write

func (*RTPPacketWriter) UpdateRTPSession

func (w *RTPPacketWriter) UpdateRTPSession(rtpSess *RTPSession)

UpdateRTPSession updates the RTP writer when a new RTP session is created.

func (*RTPPacketWriter) UpdateWriter added in v0.40.0

func (w *RTPPacketWriter) UpdateWriter(writer RTPWriter, codec Codec)

func (*RTPPacketWriter) Write

func (p *RTPPacketWriter) Write(b []byte) (int, error)

Write implements io.Writer and does payload RTP packetization Media clock rate is determined For more control or dynamic payload WriteSamples can be used It is not thread safe and order of payload frames is required

func (*RTPPacketWriter) WriteSamples

func (p *RTPPacketWriter) WriteSamples(payload []byte, sampleRateTimestamp uint32, marker bool, payloadType uint8) (int, error)

WriteSamples allows to skip default packet rate. This is useful if you need to write different payload but keeping same SSRC

func (*RTPPacketWriter) Writer

func (w *RTPPacketWriter) Writer() RTPWriter

type RTPReadStats

type RTPReadStats struct {
	SSRC                   uint32
	FirstPktSequenceNumber uint16
	LastSequenceNumber     uint16

	// tracks first pkt seq in this interval to calculate loss of packets
	IntervalFirstPktSeqNum uint16
	IntervalPacketsCount   uint16

	PacketsCount uint64
	OctetCount   uint64

	// RTP reading stats
	SampleRate uint32

	// Round TRIP Time based on LSR and DLSR
	RTT time.Duration
	// contains filtered or unexported fields
}

Some of fields here are exported (as readonly) intentionally

type RTPReader

type RTPReader interface {
	ReadRTP(buf []byte, p *rtp.Packet) (int, error)
}

type RTPReaderRaw

type RTPReaderRaw interface {
	ReadRTPRaw(buf []byte) (int, error)
}

type RTPRealTimeReader added in v0.28.0

type RTPRealTimeReader struct {
	// contains filtered or unexported fields
}

func NewRTPRealTimeReader added in v0.28.0

func NewRTPRealTimeReader(reader io.Reader, rtpReader *RTPPacketReader, codec Codec) *RTPRealTimeReader

func (*RTPRealTimeReader) Init added in v0.28.0

func (r *RTPRealTimeReader) Init(reader io.Reader, rtpReader *RTPPacketReader, codec Codec)

func (*RTPRealTimeReader) Read added in v0.28.0

func (r *RTPRealTimeReader) Read(b []byte) (int, error)

func (*RTPRealTimeReader) Reset added in v0.28.0

func (r *RTPRealTimeReader) Reset()

type RTPSession

type RTPSession struct {
	// Keep pointers at top to reduce GC
	Sess *MediaSession
	// contains filtered or unexported fields
}

func NewRTPSession

func NewRTPSession(sess *MediaSession) *RTPSession

RTP session creates new RTP reader/writer from session

func (*RTPSession) Close

func (s *RTPSession) Close() error

func (*RTPSession) Fork added in v0.31.0

func (s *RTPSession) Fork(sess *MediaSession) *RTPSession

Fork creates a new RTP session lifecycle for a forked media session while preserving RTP and RTCP statistics.

func (*RTPSession) Monitor

func (s *RTPSession) Monitor() error

Monitor starts reading RTCP and monitoring media quality

func (*RTPSession) MonitorBackground

func (s *RTPSession) MonitorBackground() error

MonitorBackground is helper to keep monitoring in background MUST Be called after session REMOTE SDP is parsed

func (*RTPSession) MonitorClose added in v0.31.0

func (s *RTPSession) MonitorClose() error

MonitorClose stops RTCP monitoring and waits until all monitor goroutines have exited. The RTP/RTCP connections remain open for a replacement fork.

func (*RTPSession) OnReadRTCP

func (s *RTPSession) OnReadRTCP(f func(pkt rtcp.Packet, rtpStats RTPReadStats))

func (*RTPSession) OnWriteRTCP

func (s *RTPSession) OnWriteRTCP(f func(pkt rtcp.Packet, rtpStats RTPWriteStats))

func (*RTPSession) ReadRTP

func (s *RTPSession) ReadRTP(b []byte, readPkt *rtp.Packet) (n int, err error)

ReadRTP reads RTP NOTE: For RTCP we may read some properties of media session. Do not run this until full media session is negotiated. For updating media, media session forking must be done!

func (*RTPSession) ReadRTPRaw

func (s *RTPSession) ReadRTPRaw(buf []byte) (int, error)

func (*RTPSession) ReadStats added in v0.10.0

func (s *RTPSession) ReadStats() RTPReadStats

func (*RTPSession) WriteRTP

func (s *RTPSession) WriteRTP(pkt *rtp.Packet) error

func (*RTPSession) WriteStats added in v0.10.0

func (s *RTPSession) WriteStats() RTPWriteStats

type RTPSessionWebrtc added in v0.40.0

type RTPSessionWebrtc struct {
	// Keep pointers at the top to reduce GC scanning work.
	Sess *MediaSessionWebrtc

	// RTCPReportInterval controls sender/receiver report frequency. Set it
	// before Monitor or MonitorBackground. Zero uses five seconds. Each report
	// is scheduled between half and one-and-a-half times this mean, which is a
	// deliberately simple interval model for one audio source and one peer.
	RTCPReportInterval time.Duration
	// contains filtered or unexported fields
}

RTPSessionWebrtc adds RTP statistics and RTCP reporting to a negotiated MediaSessionWebrtc transport. It is separate from MediaSessionWebrtc so the ICE/DTLS/SRTP lifecycle does not own application-facing packet wrappers.

Unlike the legacy RTPSession this type has no symmetric-RTP address learning, RTP source lock or separate RTCP destination. ICE authenticates the selected path, while WebRTC sends both RTP and RTCP over that one path (rtcp-mux).

func NewRTPSessionWebrtc added in v0.40.0

func NewRTPSessionWebrtc(sess *MediaSessionWebrtc) *RTPSessionWebrtc

func (*RTPSessionWebrtc) Close added in v0.40.0

func (s *RTPSessionWebrtc) Close() error

Close requests RTCP monitoring to stop without waiting for the goroutines.

func (*RTPSessionWebrtc) Fork added in v0.40.0

Fork creates the RTCP/statistics lifecycle for a replacement WebRTC transport. RTP sequence numbers, timestamps and SSRC remain owned by the stable RTPPacketWriter; cumulative report state and callbacks continue here.

func (*RTPSessionWebrtc) Monitor added in v0.40.0

func (s *RTPSessionWebrtc) Monitor() error

Monitor reads incoming SRTCP and periodically writes encrypted RTCP reports. It blocks until Close, a read failure or a write failure.

func (*RTPSessionWebrtc) MonitorBackground added in v0.40.0

func (s *RTPSessionWebrtc) MonitorBackground() error

MonitorBackground starts the RTCP reader and report writer in the background. Call MonitorClose before closing MediaSessionWebrtc when deterministic cleanup is required.

func (*RTPSessionWebrtc) MonitorClose added in v0.40.0

func (s *RTPSessionWebrtc) MonitorClose() error

MonitorClose stops RTCP monitoring and waits for both monitor goroutines. The ICE and media transports remain open.

func (*RTPSessionWebrtc) OnReadRTCP added in v0.40.0

func (s *RTPSessionWebrtc) OnReadRTCP(f func(pkt rtcp.Packet, rtpStats RTPReadStats))

func (*RTPSessionWebrtc) OnWriteRTCP added in v0.40.0

func (s *RTPSessionWebrtc) OnWriteRTCP(f func(pkt rtcp.Packet, rtpStats RTPWriteStats))

func (*RTPSessionWebrtc) ReadRTCP added in v0.40.0

func (s *RTPSessionWebrtc) ReadRTCP(buf []byte, pkts []rtcp.Packet) (int, error)

func (*RTPSessionWebrtc) ReadRTP added in v0.40.0

func (s *RTPSessionWebrtc) ReadRTP(buf []byte, pkt *rtp.Packet) (int, error)

ReadRTP decrypts through MediaSessionWebrtc and updates the receiver report counters. The generic RTPPacketReader can use RTPSessionWebrtc directly.

func (*RTPSessionWebrtc) ReadRTPRaw added in v0.40.0

func (s *RTPSessionWebrtc) ReadRTPRaw(buf []byte) (int, error)

func (*RTPSessionWebrtc) ReadStats added in v0.40.0

func (s *RTPSessionWebrtc) ReadStats() RTPReadStats

func (*RTPSessionWebrtc) WriteRTCP added in v0.40.0

func (s *RTPSessionWebrtc) WriteRTCP(pkt rtcp.Packet) error

func (*RTPSessionWebrtc) WriteRTP added in v0.40.0

func (s *RTPSessionWebrtc) WriteRTP(pkt *rtp.Packet) error

WriteRTP encrypts through MediaSessionWebrtc and updates sender-report counters only after the packet has been written successfully.

func (*RTPSessionWebrtc) WriteStats added in v0.40.0

func (s *RTPSessionWebrtc) WriteStats() RTPWriteStats

type RTPStatsReader added in v0.10.0

type RTPStatsReader struct {
	// Reader should be your AudioReade or any other interceptor RTP reader that is reading audio stream
	Reader     io.Reader
	RTPSession *RTPSession
	// OnRTPReadStats is fired each time on Read RTP. Must not block
	OnRTPReadStats OnRTPReadStats
}

func (*RTPStatsReader) Read added in v0.10.0

func (i *RTPStatsReader) Read(b []byte) (int, error)

type RTPStatsWriter added in v0.10.0

type RTPStatsWriter struct {
	// Writer should be your Writer or any other interceptor RTP writer that is reading audio stream
	Writer     io.Writer
	RTPSession *RTPSession
	// ONRTPWriteStats is fired each time on Read RTP. Must not block
	OnRTPWriteStats OnRTPWriteStats
}

func (*RTPStatsWriter) Write added in v0.10.0

func (i *RTPStatsWriter) Write(b []byte) (int, error)

type RTPTracer added in v0.32.0

type RTPTracer interface {
	RTPTraceRead(laddr string, raddr string, packet *rtp.Packet)
	RTPTraceWrite(laddr string, raddr string, packet *rtp.Packet)
}

RTPTracer receives decoded RTP packets when RTPDebug is enabled.

Traces run synchronously on the media path. Implementations must not block and must clone packets that are retained after the method returns.

type RTPWriteStats

type RTPWriteStats struct {
	SSRC uint32

	// RTCP stats
	PacketsCount uint64
	OctetCount   uint64
	// contains filtered or unexported fields
}

Some of fields here are exported (as readonly) intentionally

type RTPWriter

type RTPWriter interface {
	WriteRTP(p *rtp.Packet) error
}

type RTPWriterRaw

type RTPWriterRaw interface {
	WriteRTPRaw(buf []byte) (int, error) // -> io.Writer
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址