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 ¶
- Constants
- Variables
- func CodecsFromSDPRead(formats []string, attrs []string, codecsAudio []Codec) (int, error)
- func Copy(reader io.Reader, writer io.Writer) (int64, error)
- func CopyContext(ctx context.Context, reader io.Reader, writer io.Writer) (int64, error)
- func CopyWithBuf(reader io.Reader, writer io.Writer, payloadBuf []byte) (int64, error)
- func CopyWithBufContext(ctx context.Context, reader io.Reader, writer io.Writer, payloadBuf []byte) (int64, error)
- func DTMFDecode(payload []byte, d *DTMFEvent) error
- func DTMFEncode(d DTMFEvent) []byte
- func DTMFToRune(dtmf uint8) rune
- func DefaultLogger() *slog.Logger
- func ErrorIsTimeout(err error) bool
- func FractionLostFloat(f uint8) float64
- func GetCurrentNTPTimestamp() uint64
- func IsDTMFEvent(char rune) bool
- func NTPTimestamp(t time.Time) uint64
- func NTPToTime(ntpTimestamp uint64) time.Time
- func OpusSupportedForNegotiation() bool
- func RTCPUnmarshal(data []byte, packets []rtcp.Packet) (n int, err error)
- func RTPDebugTracer(t RTPTracer)
- func RTPUnmarshal(buf []byte, p *rtp.Packet) error
- func ReadAll(reader io.Reader, sampleSize int) ([]byte, error)
- func SetDefaultLogger(l *slog.Logger)
- func StringRTCP(p rtcp.Packet) string
- func ValidateSDPSessionName(name string) error
- func WriteAll(w io.Writer, data []byte, sampleSize int) (int64, error)
- type Codec
- type DTLSConfig
- type DTMFEncodeOptions
- type DTMFEvent
- type MediaSession
- func (s *MediaSession) Close() error
- func (s *MediaSession) CodecForPayloadType(payloadType uint8) (Codec, bool)
- func (s *MediaSession) CommonCodecs() []Codec
- func (s *MediaSession) DTMFCodec() Codecdeprecated
- func (s *MediaSession) DTMFCodecNegotiated() (Codec, bool)
- func (m *MediaSession) DiscardQueuedRTP() (int, error)
- func (s *MediaSession) Finalize() error
- func (s *MediaSession) Fork() *MediaSession
- func (s *MediaSession) Init() error
- func (s *MediaSession) InitWithListeners(lRTP net.PacketConn, lRTCP net.PacketConn, raddr *net.UDPAddr)deprecated
- func (s *MediaSession) InitWithSDP(localSDP []byte) errordeprecated
- func (s *MediaSession) LocalSDP() []byte
- func (s *MediaSession) NegotiatedDirection() string
- func (m *MediaSession) ReadRTCP(buf []byte, pkts []rtcp.Packet) (n int, err error)
- func (m *MediaSession) ReadRTCPRaw(buf []byte) (int, net.Addr, error)
- func (m *MediaSession) ReadRTCPRawDeadline(buf []byte, t time.Time) (int, error)deprecated
- func (m *MediaSession) ReadRTP(buf []byte, pkt *rtp.Packet) (int, error)
- func (m *MediaSession) ReadRTPRaw(buf []byte) (int, error)
- func (m *MediaSession) ReadRTPRawDeadline(buf []byte, t time.Time) (int, error)deprecated
- func (s *MediaSession) RemoteSDP(sdpReceived []byte) error
- func (s *MediaSession) SetRemoteAddr(raddr *net.UDPAddr)
- func (s *MediaSession) StartRTP(rw int8) errordeprecated
- func (s *MediaSession) StopRTP(rw int8, dur time.Duration) errordeprecated
- func (s *MediaSession) String() string
- func (m *MediaSession) WriteRTCP(p rtcp.Packet) error
- func (m *MediaSession) WriteRTCPDeadline(p rtcp.Packet, deadline time.Time) errordeprecated
- func (m *MediaSession) WriteRTCPRaw(data []byte) (int, error)
- func (m *MediaSession) WriteRTCPs(pkts []rtcp.Packet) errordeprecated
- func (m *MediaSession) WriteRTP(p *rtp.Packet) error
- func (m *MediaSession) WriteRTPRaw(data []byte) (n int, err error)
- type MediaStreamer
- type OnRTPReadStats
- type OnRTPWriteStats
- type RTCPReaderdeprecated
- type RTCPWriterdeprecated
- type RTCPWriterRawdeprecated
- type RTPCReaderRawdeprecated
- type RTPDtmfReader
- type RTPDtmfWriter
- func (w *RTPDtmfWriter) Write(b []byte) (int, error)
- func (w *RTPDtmfWriter) WriteDTMF(dtmf rune) error
- func (w *RTPDtmfWriter) WriteDTMFContext(ctx context.Context, dtmf rune) error
- func (w *RTPDtmfWriter) WriteDTMFWithOptions(dtmf rune, opts DTMFEncodeOptions) error
- func (w *RTPDtmfWriter) WriteDTMFWithOptionsContext(ctx context.Context, dtmf rune, opts DTMFEncodeOptions) error
- type RTPExtendedSequenceNumber
- type RTPJitterBuffer
- type RTPJitterBufferOptions
- type RTPJitterBufferStatistics
- type RTPPacketReader
- func (r *RTPPacketReader) ArmReadInterrupt(ctx context.Context) (disarm func())
- func (r *RTPPacketReader) PauseRead() (release func())
- func (r *RTPPacketReader) Read(b []byte) (int, error)
- func (r *RTPPacketReader) ReadContext(ctx context.Context, b []byte) (int, error)
- func (r *RTPPacketReader) Reader() RTPReader
- func (r *RTPPacketReader) UpdateRTPSession(rtpSess *RTPSession)
- func (r *RTPPacketReader) UpdateReader(reader RTPReader)
- type RTPPacketWriter
- func (w *RTPPacketWriter) ClockDisable()deprecated
- func (w *RTPPacketWriter) ClockEnable()deprecated
- func (w *RTPPacketWriter) Close() error
- func (p *RTPPacketWriter) DelayTimestamp(ofsset uint32)deprecated
- func (p *RTPPacketWriter) InitTimestamp() uint32
- func (p *RTPPacketWriter) PauseWrite() (release func())
- func (p *RTPPacketWriter) ResetTimestamp()
- func (w *RTPPacketWriter) UpdateRTPSession(rtpSess *RTPSession)
- func (p *RTPPacketWriter) Write(b []byte) (int, error)
- func (p *RTPPacketWriter) WriteSamples(payload []byte, sampleRateTimestamp uint32, marker bool, payloadType uint8) (int, error)
- func (w *RTPPacketWriter) Writer() RTPWriterdeprecated
- type RTPReadStats
- type RTPReader
- type RTPReaderRawdeprecated
- type RTPRealTimeReader
- type RTPSession
- func (s *RTPSession) Close() error
- func (s *RTPSession) Fork(sess *MediaSession) *RTPSession
- func (s *RTPSession) Monitor() error
- func (s *RTPSession) MonitorBackground() error
- func (s *RTPSession) MonitorClose() error
- func (s *RTPSession) OnReadRTCP(f func(pkt rtcp.Packet, rtpStats RTPReadStats))
- func (s *RTPSession) OnWriteRTCP(f func(pkt rtcp.Packet, rtpStats RTPWriteStats))
- func (s *RTPSession) ReadRTP(b []byte, readPkt *rtp.Packet) (n int, err error)
- func (s *RTPSession) ReadRTPRaw(buf []byte) (int, error)
- func (s *RTPSession) ReadStats() RTPReadStats
- func (s *RTPSession) WriteRTP(pkt *rtp.Packet) error
- func (s *RTPSession) WriteStats() RTPWriteStats
- type RTPStatsReader
- type RTPStatsWriter
- type RTPTracer
- type RTPWriteStats
- type RTPWriter
- type RTPWriterRawdeprecated
Examples ¶
Constants ¶
const ( ServerClientAuthNoCert = int(dtls.NoClientCert) ServerClientAuthRequireCert = int(dtls.RequireAnyClientCert) // ServerClientAuthRequestCert keeps the previous (misleading) mapping // of ServerClientAuthRequireCert for compatibility: request but not require. // Deprecated: use ServerClientAuthRequireCert. ServerClientAuthRequestCert = int(dtls.RequestClientCert) EllipticCurveP256 uint16 = uint16(elliptic.P256) EllipticCurveP384 uint16 = uint16(elliptic.P384) EllipticCurveX25519 uint16 = uint16(elliptic.X25519) )
const ( RTPNATDisabled = 0 RTPNATSymetric = 1 )
RTPNAT options
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) )
const DefaultDTMFVolume uint8 = 10
DefaultDTMFVolume is the signal volume applied when DTMFEncodeOptions marks no explicit choice.
Variables ¶
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"} )
var ( // ErrReadPaused is returned by RTPPacketReader reads while the reader is // paused (PauseRead) or interrupted through a context. ErrReadPaused = errors.New("rtp read paused") // ErrWritePaused is returned by RTPPacketWriter writes while the writer is // paused (PauseWrite). ErrWritePaused = errors.New("rtp write paused") )
Pause/interrupt sentinels for the media read/write gates.
The gates replace the legacy pattern of expressing "stop/pause" by expiring the shared UDP conn deadlines (StopRTP/StartRTP), where multiple components overwrote each other's state. With the gates, the read/write deadline is a transient interrupt signal owned by the stable handles; a pause is a refcounted state resolved at use time.
var ( // RTPPortStart and RTPPortEnd allows defining rtp port range for media. // They are the process-wide fallback: MediaConfig.RTPPortStart/RTPPortEnd // (and the per-session fields set from it) take precedence when non-zero. RTPPortStart = 0 RTPPortEnd = 0 // RTPBufSize is the minimum size of buffers used on RTP read paths (MTU // guard). It is a PROCESS-WIDE constant: sync.Pools and the jitter buffer // capture it lazily at first use, so changing it mid-process has // inconsistent effect. Set it once at startup before any media flows. // There is intentionally no per-instance override yet. RTPBufSize = 1500 // RTPDebug/RTCPDebug enable synchronous packet tracing on media paths. // Atomic so tests and examples can flip them while media runs RTPDebug atomic.Bool RTCPDebug atomic.Bool // RTPProfileSAVPDisable disables offering RTP/SAVP and keeps standard RTP/AVP for backward compatibilit needs // // Experimental // Kept process-global: it is a bool flag where "unset" and "false" are // indistinguishable, so a per-instance override cannot fall back cleanly. RTPProfileSAVPDisable = false // SDP codec exchanges // 0 (Default) - answerer prefers offerer order recomended by rfc // 1 - answerer prefers local order // Process-wide fallback: MediaConfig.SDPCodecPreferLocalOrder (and the // per-session field set from it) takes precedence when non-zero. SDPCodecPreferLocalOrder int = 0 )
var ( ErrRTPSequenceOutOfOrder = errors.New("out of order") ErrRTPSequenceBad = errors.New("bad sequence") ErrRTPSequnceDuplicate = errors.New("sequence duplicate") )
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 // ErrRTPSessionClosed is the exported counterpart of errRTPSessionClosed. // Exposed so callers can detect the "media already torn down" condition // without depending on internal state. ErrRTPSessionClosed = errRTPSessionClosed )
var ( // DTLSDebug enables DTLS handshake logging. Atomic so it can be flipped // while handshakes run DTLSDebug atomic.Bool )
Functions ¶
func CodecsFromSDPRead ¶
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 CopyContext ¶
CopyContext is CopyWithBuf that stops with ctx.Err() when ctx is done. The check runs between reads/writes; a read blocked on the network is expected to be interrupted through the reader's own gate (ReadContext or ArmReadInterrupt), keeping cancellation latency within one packet interval.
func CopyWithBuf ¶
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 CopyWithBufContext ¶
func CopyWithBufContext(ctx context.Context, reader io.Reader, writer io.Writer, payloadBuf []byte) (int64, error)
CopyWithBufContext is CopyWithBuf with context checks between iterations.
func DTMFDecode ¶
DecodeRTPPayload decodes an RTP payload into a DTMF event
func DTMFEncode ¶
func DTMFToRune ¶
func DefaultLogger ¶
func ErrorIsTimeout ¶
func FractionLostFloat ¶
func GetCurrentNTPTimestamp ¶
func GetCurrentNTPTimestamp() uint64
func IsDTMFEvent ¶ added in v0.0.4
IsDTMFEvent reports whether char has an RFC 4733 event code ('0'-'9', 'A'-'D', '*', '#').
func NTPTimestamp ¶
func OpusSupportedForNegotiation ¶ added in v0.0.6
func OpusSupportedForNegotiation() bool
OpusSupportedForNegotiation is the public gate for tests/docs.
func RTCPUnmarshal ¶
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 ¶
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 ¶
RTPUnmarshal wrapper for now used for optimizing unmarshal
func SetDefaultLogger ¶
SetDefaultLogger sets default logger that will be used withing sip package Must be called before any usage of library
func StringRTCP ¶
func ValidateSDPSessionName ¶ added in v0.0.4
ValidateSDPSessionName rejects session names that could break out of the "s=" line: SDP line breaks are CR or LF, so a name carrying them would inject additional SDP attributes. Empty keeps the library default and is valid here; option-level empty checks are callers' responsibility.
Types ¶
type Codec ¶
type Codec struct {
Name string
PayloadType uint8
SampleRate uint32
SampleDur time.Duration
NumChannels int // 1 or 2
}
func CodecAudioFromList ¶
func CodecAudioFromSession ¶
func CodecAudioFromSession(s *MediaSession) Codec
func CodecFromPayloadType
deprecated
func CodecFromSession
deprecated
func CodecFromSession(s *MediaSession) Codec
Deprecated: Use CodecAudioFromSession
func (*Codec) SampleTimestamp ¶
SampleTimestamp returns number of samples as RTP Timestamp measure
type DTLSConfig ¶
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 ¶
func (conf *DTLSConfig) ToLibConf(fingerprints []sdpFingerprints) *dtls.Config
type DTMFEncodeOptions ¶ added in v0.0.4
type DTMFEncodeOptions struct {
// Volume is the RFC 4733 signal volume (0-63 relative dBov, 0 being the
// loudest). It is only honored when VolumeSet is true — the zero value of
// the struct must keep the legacy default (DefaultDTMFVolume), and volume
// 0 is itself a legal wire value, so it cannot double as "unset".
Volume uint8
// VolumeSet marks Volume as explicitly provided.
VolumeSet bool
// EventDuration is the event hold duration reported in the Duration
// fields. Zero means the default, 80ms.
EventDuration time.Duration
}
DTMFEncodeOptions tunes the event packet series generated for one digit.
type DTMFEvent ¶
DTMFEvent represents a DTMF event
func RTPDTMFEncode ¶ added in v0.0.4
func RTPDTMFEncode(codec Codec, char rune, opts DTMFEncodeOptions) ([]DTMFEvent, error)
RTPDTMFEncode creates the series of redundant event packets for one digit, scaled to the codec clock rate (160 ticks @8k, 960 @48k per 20ms). A zero/negative codec clock falls back to the canonical 8 kHz telephone-event rate (mirroring the pacing guard in WriteDTMFWithOptions). Layout: 4 active packets with growing Duration, then 3 EndOfEvent packets repeating the final duration.
func RTPDTMFEncode8000
deprecated
type MediaSession ¶
type MediaSession struct {
// Codecs are initial list of Codecs that would be used in SDP generation
Codecs []Codec
// Creation-time config normally set from diago's MediaConfig. Zero values
// fall back to the package globals (RTPPortStart/RTPPortEnd,
// SDPCodecPreferLocalOrder). Set only in the Config phase (before Init);
// carried through Fork for re-INVITE consistency.
RTPPortStart int
RTPPortEnd int
SDPCodecPreferLocalOrder int
// SDPSessionName overrides the SDP "s=" line. Empty keeps the default
// "Sip Go Media". Set only in the Config phase; carried through Fork.
SDPSessionName string
// 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) CodecForPayloadType ¶ added in v0.0.6
func (s *MediaSession) CodecForPayloadType(payloadType uint8) (Codec, bool)
CodecForPayloadType resolves a codec by payload type. The negotiated list (filterCodecs) is searched first so remote-assigned dynamic payload types (ex. opus at PT 111, telephone-event at PT 100) resolve to the negotiated codec instead of failing against locally configured defaults. Falls back to the configured codecs before/without negotiation.
func (*MediaSession) CommonCodecs ¶
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) DTMFCodec
deprecated
func (s *MediaSession) DTMFCodec() Codec
DTMFCodec returns negotiated telephone-event codec. DTMF payload type is negotiated per peer (RFC 4733), so it may differ from the default constant. Falls back to the default codec when DTMF was not negotiated. NOTE: Not thread safe, should be called after negotiation Only!
Deprecated: The silent PT 101 fallback cannot distinguish "negotiated" from "peer has no telephone-event" — events sent on an unnegotiated payload type are dropped by most peers. Use DTMFCodecNegotiated, which reports ok=false so callers can fall back to inband tones or SIP INFO.
func (*MediaSession) DTMFCodecNegotiated ¶ added in v0.0.4
func (s *MediaSession) DTMFCodecNegotiated() (Codec, bool)
DTMFCodecNegotiated resolves the telephone-event codec from the effective codec list (negotiated filterCodecs when present, otherwise the local list). ok=false means the peer does not support RFC 4733 — callers should fall back to inband tones or SIP INFO. Unlike DTMFCodec it never invents PT 101.
func (*MediaSession) DiscardQueuedRTP ¶ added in v0.0.6
func (m *MediaSession) DiscardQueuedRTP() (int, error)
DiscardQueuedRTP drains datagrams already queued on the RTP socket and returns how many were discarded. It exists for the moment a media consumer starts (ex. a Bridge about to proxy): without it, whatever arrived while nobody was reading is replayed at the line rate and becomes permanent one-way latency (see docs/contracts.md §15).
The caller must guarantee that no other component is reading this session concurrently - the drain consumes datagrams from the same socket. Packets are dropped raw: no SRTP decryption, RTP/RTCP statistics, RTPNAT source learning or reader-chain taps observe them. Any read deadline is cleared before returning, so normal blocking reads keep working. A nil conn (media never initialized) is a no-op.
On a DTLS-SRTP session the drain is a no-op until the handshake completes (Finalize returns): DTLS flights share the RTP socket with SRTP, so draining before then would eat handshake records. Afterwards the socket carries SRTP only.
func (*MediaSession) Finalize ¶
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 creates a draft copy for a session update (re-INVITE, hold, ...). The draft shares the parent's RTP/RTCP connections; everything negotiated (Raddr, rtcpRaddr, negotiated mode, filterCodecs, SRTP/DTLS state, NAT-learned addresses) is reset and must be re-established via RemoteSDP on the draft. The draft becomes active only when installed through diago's DialogMedia (docs/contracts.md §3); mutating the active session in place is forbidden.
An established DTLS-SRTP association is the exception: its keys cannot be re-derived without re-running the handshake (which is impossible while media is flowing on the shared socket), so the SRTP contexts are carried over and the fork keeps encrypting with the existing association (RFC 5763 §6.6).
func (*MediaSession) Init ¶
func (s *MediaSession) Init() error
Init should be called if session is created manually Use NewMediaSession for default building
func (*MediaSession) InitWithListeners
deprecated
func (s *MediaSession) InitWithListeners(lRTP net.PacketConn, lRTCP net.PacketConn, raddr *net.UDPAddr)
InitWithListeners wires pre-created RTP/RTCP listeners into the session.
Deprecated: MediaSession setup is performed by diago's signaling layer (see docs/contracts.md). Construct sessions through diago APIs instead; manual init is not part of the supported flow.
func (*MediaSession) InitWithSDP
deprecated
func (s *MediaSession) InitWithSDP(localSDP []byte) error
InitWithSDP allows creating media session with own SDP and bypassing other needs
Deprecated: MediaSession setup is performed by diago's signaling layer (see docs/contracts.md). Construct sessions through diago APIs instead.
func (*MediaSession) LocalSDP ¶
func (s *MediaSession) LocalSDP() []byte
LocalSDP generates SDP based on local settings and remote SDP. It is part of the offer/answer flow, not a pure getter: the first call allocates the o= session id, every call increments its version, and on an SRTP offer it creates the local crypto context. SDES setup failures are logged and the SDP continues in plaintext. It must never be called in parallel to RemoteSDP; see docs/contracts.md §2.
func (*MediaSession) NegotiatedDirection ¶ added in v0.0.5
func (s *MediaSession) NegotiatedDirection() string
NegotiatedDirection returns the direction negotiated in the last completed offer/answer exchange: one of sdp.ModeSendrecv, sdp.ModeSendonly, sdp.ModeRecvonly or sdp.ModeInactive. It returns "" before the first negotiation and after a Fork (forks reset it until RemoteSDP applies).
The value is written while the owning DialogMedia holds its lock (all RemoteSDP/install paths do); read it under the same discipline. From component code, resolve through DialogMedia instead of capturing a session.
func (*MediaSession) ReadRTCP ¶
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 (*MediaSession) ReadRTCPRawDeadline
deprecated
ReadRTCPRawDeadline reads raw RTCP bytes with a one-shot read deadline.
Deprecated: Deadline-based cancellation is superseded by the pause/interrupt gates on RTPPacketReader (PauseRead, ReadContext); see docs/contracts.md §5.
func (*MediaSession) ReadRTP ¶
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
deprecated
ReadRTPRawDeadline reads raw RTP bytes with a one-shot read deadline.
Deprecated: Deadline-based cancellation is superseded by the pause/interrupt gates on RTPPacketReader (PauseRead, ReadContext); see docs/contracts.md §5.
func (*MediaSession) RemoteSDP ¶
func (s *MediaSession) RemoteSDP(sdpReceived []byte) error
RemoteSDP applies remote SDP. 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. The RTCP address is derived as RTP port + 1 (rtcp-mux is not supported). It is not thread safe
func (*MediaSession) StartRTP
deprecated
func (s *MediaSession) StartRTP(rw int8) error
StartRTP clears the conn deadline (both directions when the mask covers them), restoring blocking reads and writes.
Deprecated: Use the release function returned by diago's DialogMedia.PauseAudioRead / PauseAudioWrite.
func (*MediaSession) StopRTP
deprecated
func (s *MediaSession) StopRTP(rw int8, dur time.Duration) error
StopRTP pauses reading and/or writing by expiring the shared conn deadline. This is a durable, global state on the conn: any later StartRTP clears it for everyone, so concurrent components overwrite each other.
Deprecated: The conn deadline is an implementation detail of the media stack. Use diago's DialogMedia.PauseAudioRead / PauseAudioWrite, which are refcounted and scoped to the stable handles. The rw mask values 1 (read) and 2 (write) can be combined.
func (*MediaSession) String ¶
func (s *MediaSession) String() string
func (*MediaSession) WriteRTCPDeadline
deprecated
func (*MediaSession) WriteRTCPRaw ¶
func (m *MediaSession) WriteRTCPRaw(data []byte) (int, error)
func (*MediaSession) WriteRTCPs
deprecated
func (m *MediaSession) WriteRTCPs(pkts []rtcp.Packet) error
Use this to write Multi RTCP packets if they can fit in MTU=1500
Deprecated: Use RTPPacketWriter (stable handle) for writing; see docs/contracts.md §5.
func (*MediaSession) WriteRTPRaw ¶
func (m *MediaSession) WriteRTPRaw(data []byte) (n int, err error)
type MediaStreamer ¶
type MediaStreamer interface {
MediaStream(s *MediaSession) error
}
type OnRTPReadStats ¶
type OnRTPReadStats func(stats RTPReadStats)
type OnRTPWriteStats ¶
type OnRTPWriteStats func(stats RTPWriteStats)
type RTCPWriter
deprecated
type RTCPWriterRaw
deprecated
type RTPCReaderRaw
deprecated
type RTPDtmfReader ¶
type RTPDtmfReader struct {
// contains filtered or unexported fields
}
func NewRTPDTMFReader ¶
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 ¶
func (w *RTPDtmfReader) Read(b []byte) (int, error)
Write is RTP io.Writer which adds more sync mechanism
func (*RTPDtmfReader) ReadDTMF ¶
func (w *RTPDtmfReader) ReadDTMF() (rune, bool)
type RTPDtmfWriter ¶
type RTPDtmfWriter struct {
// contains filtered or unexported fields
}
func NewRTPDTMFWriter ¶
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 ¶
func (w *RTPDtmfWriter) Write(b []byte) (int, error)
Write is RTP io.Writer which adds more sync mechanism
func (*RTPDtmfWriter) WriteDTMF ¶
func (w *RTPDtmfWriter) WriteDTMF(dtmf rune) error
WriteDTMF encodes and sends one RFC 4733 event with defaults (volume 10, 80ms hold). It blocks for the whole event (~7 * codec.SampleDur). A concurrent PauseWrite gate is waited out; use WriteDTMFContext when that wait must be cancellable.
func (*RTPDtmfWriter) WriteDTMFContext ¶ added in v0.0.4
func (w *RTPDtmfWriter) WriteDTMFContext(ctx context.Context, dtmf rune) error
WriteDTMFContext is WriteDTMF with a context: ctx never starts the event once canceled and it interrupts a wait spent behind the PauseWrite gate. An event whose first packet was accepted completes regardless.
func (*RTPDtmfWriter) WriteDTMFWithOptions ¶ added in v0.0.4
func (w *RTPDtmfWriter) WriteDTMFWithOptions(dtmf rune, opts DTMFEncodeOptions) error
WriteDTMFWithOptions sends one event with tuned encoding (volume, event hold). The event packets ride on the packet writer's SSRC with their own timestamp (no audio clock advance), paced one codec.SampleDur per packet. It works at any telephone-event clock rate (8k/16k/32k/48k per RFC 4733).
func (*RTPDtmfWriter) WriteDTMFWithOptionsContext ¶ added in v0.0.4
func (w *RTPDtmfWriter) WriteDTMFWithOptionsContext(ctx context.Context, dtmf rune, opts DTMFEncodeOptions) error
WriteDTMFWithOptionsContext is WriteDTMFWithOptions with a context. A canceled context never starts the event, and it cuts short a wait on a paused write gate (returning ctx.Err()); once the first packet is accepted the event completes, so cancellation latency is one event with the gate open and immediate while it stays closed.
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 ¶
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 ¶
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 ¶
func (j *RTPJitterBuffer) Close() error
Close stops jitter-buffer delivery. It does not close the injected reader.
func (*RTPJitterBuffer) Statistics ¶
func (j *RTPJitterBuffer) Statistics() RTPJitterBufferStatistics
Statistics returns a race-safe snapshot of jitter buffer counters.
type RTPJitterBufferOptions ¶
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 ¶
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) ArmReadInterrupt ¶
func (r *RTPPacketReader) ArmReadInterrupt(ctx context.Context) (disarm func())
ArmReadInterrupt arranges for an in-flight read to be interrupted when ctx is done. The returned disarm joins the watcher and, when the interrupt was delivered, restores the reader (unless a pause owns the state). Disarm must be called exactly once; it is safe to call after ctx is already done.
func (*RTPPacketReader) PauseRead ¶
func (r *RTPPacketReader) PauseRead() (release func())
PauseRead pauses the reader: current and subsequent Read calls return ErrReadPaused until the returned release is called.
Pause is refcounted: the reader stays paused until every release is called, so concurrent components can not accidentally resume each other (this is the fix for the legacy StartRTP "resume stomps everyone" behavior). Release must be called exactly once per PauseRead call.
The pause is delivered to the active reader: pause-aware readers (ex. RTPJitterBuffer) are signaled directly, session-owned readers are interrupted by a one-shot read deadline poke which the last release restores. Underlying network buffering is not stopped by a pause.
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) ReadContext ¶
ReadContext reads the next payload, interrupting the underlying blocking read when ctx is done. On cancellation it returns ctx.Err(). The reader stays fully usable afterwards.
func (*RTPPacketReader) Reader ¶
func (r *RTPPacketReader) Reader() RTPReader
func (*RTPPacketReader) UpdateRTPSession ¶
func (r *RTPPacketReader) UpdateRTPSession(rtpSess *RTPSession)
func (*RTPPacketReader) UpdateReader ¶
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 packetizes payload in RTP packet before passing on media session Not having: - 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
deprecated
func (w *RTPPacketWriter) ClockDisable()
ClockDisable stops the internal media clock ticker.
Deprecated: Not part of the stable-handle contract; the clock is owned and managed by the write pipeline. Use Close. It will be removed.
func (*RTPPacketWriter) ClockEnable
deprecated
func (w *RTPPacketWriter) ClockEnable()
ClockEnable restarts the internal media clock ticker.
Deprecated: Not part of the stable-handle contract; the clock is owned and managed by the write pipeline. It will be removed.
func (*RTPPacketWriter) Close ¶ added in v0.0.6
func (w *RTPPacketWriter) Close() error
Close stops the media clock ticker, releasing the pacing timer when the write pipeline is torn down. Idempotent.
Writes parked waiting for the next tick are woken through the stop channel so they observe the teardown (their packet write fails on the closed conn) instead of waiting for a tick that will never come.
func (*RTPPacketWriter) DelayTimestamp
deprecated
func (p *RTPPacketWriter) DelayTimestamp(ofsset uint32)
DelayTimestamp shifts next RTP timestamp by an offset.
Deprecated: Not part of the stable-handle contract. It will be removed.
func (*RTPPacketWriter) InitTimestamp ¶
func (p *RTPPacketWriter) InitTimestamp() uint32
InitTimestamp returns init RTP timestamp
func (*RTPPacketWriter) PauseWrite ¶
func (p *RTPPacketWriter) PauseWrite() (release func())
PauseWrite pauses the writer: Write and WriteSamples return ErrWritePaused until the returned release is called. Refcounted like PauseRead; release must be called exactly once per PauseWrite call.
An in-flight write completes first (pacing wait is at most one packet interval), so pause latency is bounded by the codec sample duration.
func (*RTPPacketWriter) ResetTimestamp ¶
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) 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 Concurrent writes are serialized with internal lock, but payload frame order is a caller responsibility
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
deprecated
func (w *RTPPacketWriter) Writer() RTPWriter
Writer returns the raw writer chain element behind the handle.
Deprecated: Bypasses the stable-handle pipeline (pause gates, hot swap); write through RTPPacketWriter itself. It will be removed.
type RTPReadStats ¶
type RTPReadStats struct {
SSRC uint32
FirstPktSequenceNumber uint16
LastSequenceNumber uint16
// tracks first pkt seq in this interval to calculate loss of packets.
// Ext variant keeps cycles, so interval math survives sequence wrap
IntervalFirstPktSeqNum uint16
IntervalFirstPktSeqNumExt uint64
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 RTPReaderRaw
deprecated
type RTPRealTimeReader ¶
type RTPRealTimeReader struct {
// contains filtered or unexported fields
}
func NewRTPRealTimeReader ¶
func NewRTPRealTimeReader(reader io.Reader, rtpReader *RTPPacketReader, codec Codec) *RTPRealTimeReader
func (*RTPRealTimeReader) Init ¶
func (r *RTPRealTimeReader) Init(reader io.Reader, rtpReader *RTPPacketReader, codec Codec)
func (*RTPRealTimeReader) Reset ¶
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 ¶
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 ¶
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 ¶
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 ¶
func (s *RTPSession) ReadStats() RTPReadStats
func (*RTPSession) WriteStats ¶
func (s *RTPSession) WriteStats() RTPWriteStats
type RTPStatsReader ¶
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
}
type RTPStatsWriter ¶
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
}
type RTPTracer ¶
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 RTPWriterRaw
deprecated
Source Files
¶
- codec.go
- dtls.go
- logger.go
- media_gate.go
- media_session.go
- media_stream.go
- opus_supported.go
- rtp_dtmf.go
- rtp_dtmf_reader.go
- rtp_dtmf_writer.go
- rtp_jitter_buffer.go
- rtp_packet_reader.go
- rtp_packet_writer.go
- rtp_parse.go
- rtp_realtime_reader.go
- rtp_sequencer.go
- rtp_session.go
- rtp_stats_reader_writer.go
- rtp_utils.go
- srtp.go