moq

package module
v0.7.16 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: Apache-2.0, MIT Imports: 8 Imported by: 4

README

moq.dev/moq (Go module)

Auto-generated mirror of the ergonomic Go wrapper for Media over QUIC.

Source, issues, and pull requests live in moq-dev/moq; this repo only carries tagged Go module releases.

Install

go get moq.dev/moq@latest
import "moq.dev/moq"

The import path is served by moq.dev, which points the go command back at this repo, so the module can move without breaking anyone.

Hand-written Go on top of the raw moq.dev/moq-ffi bindings, which carry the prebuilt native libraries. CGO_ENABLED=1 is required (the default on Unix).

See moq-dev/moq/go/wrapper/README.md for usage and the release process.

Licensed under MIT OR Apache-2.0.

Documentation

Overview

Package moq is the ergonomic Go API for Media over QUIC: real-time pub/sub with built-in caching, fan-out, and prioritization.

It wraps the raw UniFFI bindings in moq.dev/moq-ffi with idiomatic Go: context.Context cancellation, Go error returns, and Go 1.23 range-over-func iterators (iter.Seq2) for live streams. The raw record, enum, and small object types are re-exported here without the Moq prefix (see types.go), so most programs never need to import the ffi package directly.

A typical full-duplex client wires a single origin as both publish source and consume sink; Dial does this automatically when no origin is supplied. See the package README for a runnable example.

Cancellation

Every call that can block takes a context.Context, and cancelling it (or hitting its deadline) returns ctx.Err() promptly and tears the in-flight native work down with it. Nothing is left running in the background, so a per-call deadline is a real bound on resource use. When a call finishes at the very moment its context expires, either may win: the caller gets the result or it gets ctx.Err(). What is guaranteed is that the losing side costs nothing, so a result the caller never sees is disposed of rather than left live with no owner.

What a cancel tears down depends on the call. A one-shot call (a subscribe, a fetch, RequestBroadcast, Resolve, a producer's Used/Unused, Server.Accept) aborts on its own and leaves the object it was made on usable, so the same broadcast, producer, or server takes the next call. A stream read (any Next, RecvGroup, ReadFrame, or the iterators over them) instead cancels the stream it reads, which is what a range loop over a cancelled context wants: the consumer is finished, not merely this read. Cancel a stream read only when you are done with the stream; to bound one read, cancel the whole consumer's context.

Index

Examples

Constants

View Source
const (
	// TransportQUIC is a session that arrived over native QUIC.
	TransportQUIC = ffi.MoqTransportQuic
	// TransportIroh is a session that arrived over an Iroh peer-to-peer connection.
	TransportIroh = ffi.MoqTransportIroh
	// TransportWebSocket is a session that arrived over the WebSocket fallback transport.
	TransportWebSocket = ffi.MoqTransportWebSocket
	// TransportTCP is a session that arrived over a plaintext TCP connection.
	TransportTCP = ffi.MoqTransportTcp
	// TransportUnix is a session that arrived over a Unix domain socket.
	TransportUnix = ffi.MoqTransportUnix
)
View Source
const (
	// AudioFormatAac is Advanced Audio Coding, configured by an AudioSpecificConfig.
	AudioFormatAac = ffi.MoqAudioFormatAac
	// AudioFormatOpus is Opus, configured by an OpusHead.
	AudioFormatOpus = ffi.MoqAudioFormatOpus
	// AudioFormatFlac is FLAC, configured by its STREAMINFO block.
	AudioFormatFlac = ffi.MoqAudioFormatFlac
	// AudioFormatMp3 is MPEG-1/2 Audio Layer III.
	AudioFormatMp3 = ffi.MoqAudioFormatMp3
)

AudioFormat values: a single audio codec an importer can parse.

View Source
const (
	// VideoFormatAvc1 is H.264 with length-prefixed NALUs and an out-of-band avcC.
	VideoFormatAvc1 = ffi.MoqVideoFormatAvc1
	// VideoFormatAvc3 is H.264 in Annex-B with inline SPS/PPS.
	VideoFormatAvc3 = ffi.MoqVideoFormatAvc3
	// VideoFormatHvc1 is H.265 with length-prefixed NALUs and an out-of-band hvcC.
	VideoFormatHvc1 = ffi.MoqVideoFormatHvc1
	// VideoFormatHev1 is H.265 in Annex-B with inline parameter sets.
	VideoFormatHev1 = ffi.MoqVideoFormatHev1
	// VideoFormatAv01 is AV1.
	VideoFormatAv01 = ffi.MoqVideoFormatAv01
	// VideoFormatVp8 is VP8.
	VideoFormatVp8 = ffi.MoqVideoFormatVp8
	// VideoFormatVp9 is VP9.
	VideoFormatVp9 = ffi.MoqVideoFormatVp9
)

VideoFormat values: a single video codec an importer can parse. The two H.26x pairs differ by framing, not codec: Avc1/Hvc1 are length-prefixed with an out-of-band config record, Avc3/Hev1 are Annex-B with the parameter sets inline.

View Source
const (
	// ContainerFormatFmp4 is fragmented MP4 / CMAF.
	ContainerFormatFmp4 = ffi.MoqContainerFormatFmp4
	// ContainerFormatMkv is Matroska / WebM.
	ContainerFormatMkv = ffi.MoqContainerFormatMkv
	// ContainerFormatTs is an MPEG-2 transport stream.
	ContainerFormatTs = ffi.MoqContainerFormatTs
	// ContainerFormatFlv is Flash Video, as used by RTMP.
	ContainerFormatFlv = ffi.MoqContainerFormatFlv
)

ContainerFormat values: a container that publishes its own tracks.

View Source
const (
	// AudioSampleFormatU8 is unsigned 8-bit interleaved PCM.
	AudioSampleFormatU8 = ffi.MoqAudioSampleFormatU8
	// AudioSampleFormatS16 is signed 16-bit interleaved PCM.
	AudioSampleFormatS16 = ffi.MoqAudioSampleFormatS16
	// AudioSampleFormatS32 is signed 32-bit interleaved PCM.
	AudioSampleFormatS32 = ffi.MoqAudioSampleFormatS32
	// AudioSampleFormatF32 is 32-bit float interleaved PCM.
	AudioSampleFormatF32 = ffi.MoqAudioSampleFormatF32
	// AudioSampleFormatU8Planar is unsigned 8-bit planar PCM, one buffer per channel.
	AudioSampleFormatU8Planar = ffi.MoqAudioSampleFormatU8Planar
	// AudioSampleFormatS16Planar is signed 16-bit planar PCM, one buffer per channel.
	AudioSampleFormatS16Planar = ffi.MoqAudioSampleFormatS16Planar
	// AudioSampleFormatS32Planar is signed 32-bit planar PCM, one buffer per channel.
	AudioSampleFormatS32Planar = ffi.MoqAudioSampleFormatS32Planar
	// AudioSampleFormatF32Planar is 32-bit float planar PCM, one buffer per channel.
	AudioSampleFormatF32Planar = ffi.MoqAudioSampleFormatF32Planar
)

AudioSampleFormat values: the raw PCM sample layout fed to or returned from the in-process Opus codec.

View Source
const (
	// VideoPixelFormatI420 is tightly-packed planar I420: Y, then U, then V.
	VideoPixelFormatI420 = ffi.MoqVideoPixelFormatI420
	// VideoPixelFormatRgba is tightly-packed RGBA, four bytes per pixel.
	VideoPixelFormatRgba = ffi.MoqVideoPixelFormatRgba
)

VideoPixelFormat values: the raw pixel layout fed to the in-process encoder, and the one the in-process decoder delivers.

View Source
const (
	// VideoCodecH264 publishes H.264 / AVC as an avc3 track.
	VideoCodecH264 = ffi.MoqVideoCodecH264
	// VideoCodecH265 publishes H.265 / HEVC as a hev1 track. Hardware only, so it
	// fails where no hardware encoder is available.
	VideoCodecH265 = ffi.MoqVideoCodecH265
)

VideoCodec values: the codec a published video track is encoded to.

View Source
const (
	// StatusConnected means a session connected (the first connect, or a reconnect after a drop).
	StatusConnected = ffi.MoqConnectionStatusConnected
	// StatusDisconnected means the session dropped; a reconnect attempt follows.
	StatusDisconnected = ffi.MoqConnectionStatusDisconnected
	// StatusMigrating means the peer sent a GOAWAY; the replacement is being dialed while the old session keeps serving.
	StatusMigrating = ffi.MoqConnectionStatusMigrating
)

ConnectionStatus values: the lifecycle of a client session's connection.

View Source
const (
	// ErrorScopeSession identifies a session close code.
	ErrorScopeSession = ffi.MoqErrorScopeSession
	// ErrorScopeStream identifies a stream reset code.
	ErrorScopeStream = ffi.MoqErrorScopeStream
	// ProtocolKindCancel identifies cancel.
	ProtocolKindCancel = ffi.MoqProtocolKindCancel
	// ProtocolKindInternal identifies internal.
	ProtocolKindInternal = ffi.MoqProtocolKindInternal
	// ProtocolKindUnauthorized identifies unauthorized.
	ProtocolKindUnauthorized = ffi.MoqProtocolKindUnauthorized
	// ProtocolKindProtocolViolation identifies protocol violation.
	ProtocolKindProtocolViolation = ffi.MoqProtocolKindProtocolViolation
	// ProtocolKindKeyValueFormatting identifies key value formatting.
	ProtocolKindKeyValueFormatting = ffi.MoqProtocolKindKeyValueFormatting
	// ProtocolKindGoawayTimeout identifies goaway timeout.
	ProtocolKindGoawayTimeout = ffi.MoqProtocolKindGoawayTimeout
	// ProtocolKindTimeout identifies timeout.
	ProtocolKindTimeout = ffi.MoqProtocolKindTimeout
	// ProtocolKindVersion identifies version.
	ProtocolKindVersion = ffi.MoqProtocolKindVersion
	// ProtocolKindDeliveryTimeout identifies delivery timeout.
	ProtocolKindDeliveryTimeout = ffi.MoqProtocolKindDeliveryTimeout
	// ProtocolKindSessionClosed identifies session closed.
	ProtocolKindSessionClosed = ffi.MoqProtocolKindSessionClosed
	// ProtocolKindGoingAway identifies going away.
	ProtocolKindGoingAway = ffi.MoqProtocolKindGoingAway
	// ProtocolKindTooFarBehind identifies too far behind.
	ProtocolKindTooFarBehind = ffi.MoqProtocolKindTooFarBehind
	// ProtocolKindMalformedTrack identifies malformed track.
	ProtocolKindMalformedTrack = ffi.MoqProtocolKindMalformedTrack
	// ProtocolKindNotFound identifies not found.
	ProtocolKindNotFound = ffi.MoqProtocolKindNotFound
	// ProtocolKindUnroutable identifies unroutable.
	ProtocolKindUnroutable = ffi.MoqProtocolKindUnroutable
	// ProtocolKindOld identifies old.
	ProtocolKindOld = ffi.MoqProtocolKindOld
	// ProtocolKindEvicted identifies evicted.
	ProtocolKindEvicted = ffi.MoqProtocolKindEvicted
	// ProtocolKindWrongSize identifies wrong size.
	ProtocolKindWrongSize = ffi.MoqProtocolKindWrongSize
	// ProtocolKindFrameTooLarge identifies frame too large.
	ProtocolKindFrameTooLarge = ffi.MoqProtocolKindFrameTooLarge
	// ProtocolKindTimestampMismatch identifies timestamp mismatch.
	ProtocolKindTimestampMismatch = ffi.MoqProtocolKindTimestampMismatch
	// ProtocolKindApp identifies app.
	ProtocolKindApp = ffi.MoqProtocolKindApp
	// ProtocolKindUnknown identifies unknown.
	ProtocolKindUnknown = ffi.MoqProtocolKindUnknown
)

Protocol registries and recognized kinds carried by ProtocolError.

View Source
const DefaultDeltaRatio uint32 = 8

DefaultDeltaRatio is used when JSONSnapshotOptions.DeltaRatio is nil. Go has no field defaults, so unlike the other bindings this restates the `#[uniffi(default = 8)]` on moq-ffi's MoqJsonSnapshotConfig (itself pinned to moq-json's default by a Rust test).

View Source
const RetryForever time.Duration = -1

RetryForever, passed as Backoff.Timeout, keeps a reconnecting session retrying indefinitely instead of giving up.

Variables

View Source
var (
	// ErrProtocol matches a session or stream protocol error; inspect ProtocolError for the code.
	ErrProtocol = ffi.ErrMoqErrorProtocol
	// ErrTransport matches a QUIC/WebTransport connection failure, not a protocol code.
	ErrTransport = ffi.ErrMoqErrorTransport
	// ErrInternal matches a local failure without a protocol code.
	ErrInternal = ffi.ErrMoqErrorInternal
	// ErrMedia matches a media error from the hang layer, such as a malformed catalog or container.
	ErrMedia = ffi.ErrMoqErrorMedia
	// ErrMux matches a muxing or demuxing failure from moq-mux.
	ErrMux = ffi.ErrMoqErrorMux
	// ErrJSONTrack matches a JSON track encoding or decoding failure.
	ErrJSONTrack = ffi.ErrMoqErrorJsonTrack
	// ErrAudio matches a raw-audio encode or decode failure.
	ErrAudio = ffi.ErrMoqErrorAudio
	// ErrVideo matches a raw-video encode or decode failure.
	ErrVideo = ffi.ErrMoqErrorVideo
	// ErrURL matches a malformed URL passed when connecting or publishing.
	ErrURL = ffi.ErrMoqErrorUrl
	// ErrTimeOverflow matches a timestamp that overflowed its timescale.
	ErrTimeOverflow = ffi.ErrMoqErrorTimeOverflow
	// ErrLogLevel matches an unparseable log level string passed to LogLevel.
	ErrLogLevel = ffi.ErrMoqErrorLogLevel
	// ErrTask matches a panic or cancellation in a background native task.
	ErrTask = ffi.ErrMoqErrorTask
	// ErrJSON matches malformed JSON passed through the FFI API.
	ErrJSON = ffi.ErrMoqErrorJson
	// ErrCancelled is returned when an operation is cancelled, e.g. via a cancelled context; IsShutdown treats it as a graceful stop.
	ErrCancelled = ffi.ErrMoqErrorCancelled
	// ErrClosed is returned when the session or stream has closed; IsShutdown treats it as a graceful stop.
	ErrClosed = ffi.ErrMoqErrorClosed
	// ErrBusy is returned when a configuration setter races an in-flight connect, listen, or accept.
	ErrBusy = ffi.ErrMoqErrorBusy
	// ErrConnect is returned when establishing a client session fails.
	ErrConnect = ffi.ErrMoqErrorConnect
	// ErrBind is returned when the server fails to bind its listening address.
	ErrBind = ffi.ErrMoqErrorBind
	// ErrReject is returned when a session is refused during the handshake.
	ErrReject = ffi.ErrMoqErrorReject
	// ErrAlreadyResponded is returned when a Request is accepted or rejected more than once.
	ErrAlreadyResponded = ffi.ErrMoqErrorAlreadyResponded
	// ErrCodec is returned when codec configuration or bitstream parsing fails.
	ErrCodec = ffi.ErrMoqErrorCodec
	// ErrUnauthorized is returned when the relay rejects the session with HTTP 401.
	ErrUnauthorized = ffi.ErrMoqErrorUnauthorized
	// ErrForbidden is returned when the relay rejects the session with HTTP 403.
	ErrForbidden = ffi.ErrMoqErrorForbidden
	// ErrNotFound is returned when the requested track or group is not available.
	ErrNotFound = ffi.ErrMoqErrorNotFound
	// ErrUnsupported is returned when the requested operation is not supported by this build or peer, however it is asked for.
	ErrUnsupported = ffi.ErrMoqErrorUnsupported
	// ErrAlreadyCommitted is returned when a track already reading in one group order is asked for the other; subscribe again for a second cursor.
	ErrAlreadyCommitted = ffi.ErrMoqErrorAlreadyCommitted
	// ErrInvalidRoute is returned when a route has an invalid hop ID or too many hops.
	ErrInvalidRoute = ffi.ErrMoqErrorInvalidRoute
	// ErrInvalidPattern is returned when a path pattern is empty, has a doubled slash, or uses a reserved segment form.
	ErrInvalidPattern = ffi.ErrMoqErrorInvalidPattern
	// ErrUnresolvableBroadcast is returned when a referenced sibling broadcast cannot be resolved without an origin.
	ErrUnresolvableBroadcast = ffi.ErrMoqErrorUnresolvableBroadcast
	// ErrLog is returned when installing or configuring the native log subscriber fails.
	ErrLog = ffi.ErrMoqErrorLog
)

Error sentinels re-exported from the ffi layer without the MoqError prefix, so callers can errors.Is against them without importing moq.dev/moq-ffi directly. These mirror the variants of the native error enum; transparent variants (Protocol, Media, ...) wrap a lower-level error whose detail survives in the message.

View Source
var (
	// ErrNoPublishOrigin is returned when a publish operation is attempted but the server has no publish origin configured.
	ErrNoPublishOrigin = errors.New("moq: no publish origin configured")
)

Configuration errors returned by the wrapper itself (not the FFI layer).

Functions

func IsAuthError

func IsAuthError(err error) bool

IsAuthError reports whether err is an authentication/authorization failure (HTTP 401/403, or a protocol Unauthorized session close).

func IsShutdown

func IsShutdown(err error) bool

IsShutdown reports whether err is the expected result of a graceful shutdown (Cancelled or Closed) rather than an actual failure. It's the value to check when a stream ends because its consumer was cancelled or the session closed.

func LogLevel

func LogLevel(level string) error

LogLevel configures the native tracing log level (e.g. "info", "debug").

func ProtocolError

func ProtocolError(err error) (ffi.MoqProtocolError, bool)

ProtocolError reports the structured protocol failure, if err is one.

The record carries the peer's session or stream scope, the verbatim wire code, a known kind when recognized, and a diagnostic message.

Types

type AnnounceConsumer

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

AnnounceConsumer is a stream of route announcements and retractions.

func (*AnnounceConsumer) All

All ranges over announcements until the stream ends or the loop breaks.

func (*AnnounceConsumer) Cancel

func (a *AnnounceConsumer) Cancel()

Cancel stops the announcement stream.

func (*AnnounceConsumer) Next

Next returns the next announcement, or (nil, nil) when the stream ends.

type AnnounceOptions

type AnnounceOptions struct {
	// Prefix is a literal path root beneath the origin.
	Prefix string
	// Filter is a pattern relative to Prefix. Nil matches every path beneath it.
	Filter *string
	// Hidden also lists paths with a segment starting with "." below Prefix.
	Hidden bool
}

AnnounceOptions scopes an announcement stream.

type AnnounceUpdate

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

AnnounceUpdate is a route announcement or retraction. A route claims that Prefix and every path beneath it can be served; it carries no broadcast. Resolve a specific path with OriginConsumer.RequestBroadcast. By convention a publisher announces each broadcast's exact path.

func (*AnnounceUpdate) Active

func (a *AnnounceUpdate) Active() bool

Active reports whether the route is active (true) or was retracted (false). A repeated active announcement for the same prefix is a metadata update.

func (*AnnounceUpdate) Captures

func (a *AnnounceUpdate) Captures() []string

Captures reports what each filter wildcard matched. Nil means the route only overlaps the scope without pinning every wildcard.

func (*AnnounceUpdate) Prefix

func (a *AnnounceUpdate) Prefix() string

Prefix is the covered prefix, relative to the origin.

func (*AnnounceUpdate) Route

func (a *AnnounceUpdate) Route() Route

Route is the route serving the prefix: its relay hops and costs (warm Cost, undiscounted Cold).

type AnnouncedBroadcast

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

AnnouncedBroadcast awaits a specific broadcast becoming available.

func (*AnnouncedBroadcast) Available

Available blocks until the broadcast is available and returns its consumer.

func (*AnnouncedBroadcast) Cancel

func (a *AnnouncedBroadcast) Cancel()

Cancel stops awaiting the broadcast.

type Audio

type Audio = ffi.MoqAudio

Audio describes one audio rendition in a broadcast catalog: codec, sample rate, channel count, and container.

type AudioCodec

type AudioCodec = ffi.MoqAudioCodec

AudioCodec selects the audio encoder codec. Build one with OpusAudioCodec or AacAudioCodec; adding a codec later adds a constructor, not a breaking enum change.

func AacAudioCodec added in v0.7.9

func AacAudioCodec() *AudioCodec

AacAudioCodec selects AAC-LC through the platform's encoder for EncodeAudio. A host without one refuses it. Leave FrameDurationUs at 0 for AAC's own frame.

func OpusAudioCodec

func OpusAudioCodec() *AudioCodec

OpusAudioCodec selects Opus (RFC 6716) for EncodeAudio.

type AudioConsumer

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

AudioConsumer is a stream of decoded audio frames.

func (*AudioConsumer) Cancel

func (a *AudioConsumer) Cancel()

Cancel stops the stream.

func (*AudioConsumer) Frames

Frames ranges over audio frames until the track ends or the loop breaks.

func (*AudioConsumer) Next

func (a *AudioConsumer) Next(ctx context.Context) (*AudioFrame, error)

Next returns the next audio frame, or (nil, nil) when the track ends.

type AudioDecoderOutput

type AudioDecoderOutput = ffi.MoqAudioDecoderOutput

AudioDecoderOutput configures the PCM format, sample rate, and channels DecodeAudio delivers.

type AudioEncoderInput

type AudioEncoderInput = ffi.MoqAudioEncoderInput

AudioEncoderInput declares the PCM sample format, sample rate, and channel count of frames written to an audio producer.

type AudioEncoderOutput

type AudioEncoderOutput = ffi.MoqAudioEncoderOutput

AudioEncoderOutput configures the encoder: codec, optional sample rate, channels, bitrate, and frame duration.

type AudioFormat

type AudioFormat = ffi.MoqAudioFormat

AudioFormat is a single audio codec an importer can parse.

type AudioFrame

type AudioFrame = ffi.MoqAudioFrame

AudioFrame is one audio frame: PCM payload plus a presentation timestamp in microseconds.

type AudioOption

type AudioOption func(*ffi.MoqAudioInit)

AudioOption configures an audio publish.

func WithAudioLabel

func WithAudioLabel(label string) AudioOption

WithAudioLabel sets the human-readable rendition name stored in the catalog.

func WithAudioTrack added in v0.7.3

func WithAudioTrack(track string) AudioOption

WithAudioTrack names the track instead of deriving a unique name from the format. A requested track already has a name, so the OnTrack variant refuses it.

type AudioProducer

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

AudioProducer pushes raw PCM and lets libopus encode it on the way out.

func (*AudioProducer) Demand

func (a *AudioProducer) Demand() (*TrackDemand, error)

Demand returns a watch-only handle to whether the audio track has subscribers.

func (*AudioProducer) Finish

func (a *AudioProducer) Finish() error

Finish flushes pending samples and finalizes the track.

func (*AudioProducer) Name

func (a *AudioProducer) Name() (string, error)

Name returns the audio track's name.

func (*AudioProducer) Reservation

func (a *AudioProducer) Reservation() *Reservation

Reservation returns this encoder's bandwidth reservation, or nil if it was published without an allocator.

func (*AudioProducer) ResetEpoch

func (a *AudioProducer) ResetEpoch() error

ResetEpoch re-anchors the timeline to the next frame after an idle gap.

func (*AudioProducer) Unused

func (a *AudioProducer) Unused(ctx context.Context) error

Unused blocks until the audio track has no active subscribers. Prefer Demand.

func (*AudioProducer) Used

func (a *AudioProducer) Used(ctx context.Context) error

Used blocks until the audio track has at least one active subscriber. Prefer Demand.

func (*AudioProducer) Write

func (a *AudioProducer) Write(frame AudioFrame) error

Write pushes one frame of PCM in the configured input format.

type AudioSampleFormat

type AudioSampleFormat = ffi.MoqAudioSampleFormat

AudioSampleFormat is a raw PCM sample layout, mirroring WebCodecs AudioData.format.

type Backoff

type Backoff struct {
	Initial    time.Duration // delay before the first retry (default 1s)
	Multiplier uint32        // applied to the delay after each failure (default 2)
	Max        time.Duration // ceiling on the delay (default 5s)
	Timeout    time.Duration // give up after this long (default 10s)
}

Backoff is the retry pacing for automatic reconnects: the delay starts at Initial, multiplies by Multiplier after each failed attempt, and caps at Max. After Timeout of consecutive failures the connection gives up for good.

Every field is optional: the zero value means the default beside it, so a partial Backoff overrides only what it sets. Pass RetryForever as Timeout to keep retrying indefinitely.

type Bandwidth

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

Bandwidth divides one connection's send estimate among the tracks sharing it.

func (*Bandwidth) Reserve

func (b *Bandwidth) Reserve(track *TrackProducer, maxBps uint64) (*Reservation, error)

Reserve claims up to maxBps for track. maxBps is a ceiling, not a measurement: reserve the most the track can ever send. Drop the reservation to hand the room back.

type BroadcastConsumer

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

BroadcastConsumer reads tracks from a broadcast.

func (*BroadcastConsumer) Catalog

func (b *BroadcastConsumer) Catalog(ctx context.Context) (*Catalog, error)

Catalog subscribes and returns the first catalog. It reports ErrClosed if the catalog track ends before any catalog arrives.

func (*BroadcastConsumer) DecodeAudio

func (b *BroadcastConsumer) DecodeAudio(
	ctx context.Context,
	name string,
	catalogAudio Audio,
	output AudioDecoderOutput,
) (*AudioConsumer, error)

DecodeAudio subscribes to a raw-audio track; samples come back in the format declared by output. catalogAudio comes from the catalog.

func (*BroadcastConsumer) DecodeVideo

func (b *BroadcastConsumer) DecodeVideo(
	ctx context.Context,
	name string,
	catalogVideo Video,
	output VideoDecoderOutput,
) (*VideoConsumer, error)

DecodeVideo subscribes to a video track and decodes it inside the bindings. catalogVideo comes from the catalog. output.Format picks the packed CPU layout every frame arrives in, defaulting to I420 when nil; each frame repeats it. output.Resize is best effort, so read each frame's own dimensions.

func (*BroadcastConsumer) FetchGroup

func (b *BroadcastConsumer) FetchGroup(
	ctx context.Context,
	name string,
	sequence uint64,
	options *FetchGroupOptions,
) (*GroupConsumer, error)

FetchGroup fetches one complete group by track name and group sequence without holding a live subscription.

func (*BroadcastConsumer) FetchMediaGroup

func (b *BroadcastConsumer) FetchMediaGroup(
	ctx context.Context,
	name string,
	sequence uint64,
	container Container,
	options *FetchGroupOptions,
) (*MediaGroupConsumer, error)

FetchMediaGroup fetches one group by sequence and decodes it with the given container. Unlike SubscribeMedia this holds no live subscription and applies no latency-based group skipping, so every frame in the group is delivered.

func (*BroadcastConsumer) Resolve

func (b *BroadcastConsumer) Resolve(ctx context.Context, reference *string) (*BroadcastConsumer, error)

Resolve returns the broadcast serving a catalog rendition, honoring its broadcast reference: Video.Broadcast / Audio.Broadcast. A nil or empty reference names this broadcast, anything else names a sibling relative to it (e.g. "./source"). Call it on a rendition that carries one before SubscribeMedia, SubscribeTrack, FetchGroup, or FetchMediaGroup, which take a track name rather than a rendition; DecodeAudio and DecodeVideo resolve it themselves.

Errors if this broadcast came from a local producer rather than an origin, since a standalone broadcast has no sibling to name.

func (*BroadcastConsumer) SubscribeCatalog

func (b *BroadcastConsumer) SubscribeCatalog(ctx context.Context) (*CatalogConsumer, error)

SubscribeCatalog subscribes to the broadcast's catalog track.

func (*BroadcastConsumer) SubscribeJSONSnapshot

func (b *BroadcastConsumer) SubscribeJSONSnapshot(
	ctx context.Context,
	name string,
	options JSONSubscribeOptions,
) (*JSONSnapshotConsumer, error)

SubscribeJSONSnapshot subscribes to a lossy latest-value JSON track.

func (*BroadcastConsumer) SubscribeJSONStream

func (b *BroadcastConsumer) SubscribeJSONStream(
	ctx context.Context,
	name string,
	options JSONSubscribeOptions,
) (*JSONStreamConsumer, error)

SubscribeJSONStream subscribes to a lossless append-log JSON track.

func (*BroadcastConsumer) SubscribeMedia

func (b *BroadcastConsumer) SubscribeMedia(
	ctx context.Context,
	name string,
	container Container,
	subscription *Subscription,
) (*MediaConsumer, error)

SubscribeMedia subscribes to a media track, decoded with the given container. subscription tunes delivery priority, group range, and the max age; pass nil for defaults. Raise Subscription.MaxAgeUs to buffer instead of skipping a stalled group.

func (*BroadcastConsumer) SubscribeTrack

func (b *BroadcastConsumer) SubscribeTrack(
	ctx context.Context,
	name string,
	subscription *Subscription,
) (*TrackConsumer, error)

SubscribeTrack subscribes to a track, receiving arbitrary byte payloads. subscription tunes delivery priority, group range, and staleness; pass nil for defaults.

type BroadcastDynamic

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

BroadcastDynamic is a stream of subscriber-requested tracks.

func (*BroadcastDynamic) Cancel

func (d *BroadcastDynamic) Cancel()

Cancel stops the dynamic request stream.

func (*BroadcastDynamic) RequestedTrack

func (d *BroadcastDynamic) RequestedTrack(ctx context.Context) (*TrackRequest, error)

RequestedTrack waits for the next subscriber-requested track.

func (*BroadcastDynamic) Requests

Requests ranges over subscriber-requested tracks until the dynamic source ends.

type BroadcastProducer

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

BroadcastProducer publishes a collection of tracks. Create one at a path with OriginProducer.CreateBroadcast (or Client.CreateBroadcast), then publish tracks onto it.

func NewBroadcastProducer

func NewBroadcastProducer() (*BroadcastProducer, error)

NewBroadcastProducer creates a standalone broadcast, not attached to any origin: use it to serve a dynamic request (BroadcastRequest.Accept) or for local pub/sub. To publish at a path, use OriginProducer.CreateBroadcast.

func (*BroadcastProducer) Announce

func (b *BroadcastProducer) Announce(route Route) error

Announce advertises this broadcast's exact path as a route.

Announcing again re-prices the route in place. Until announced, the broadcast is invisible and unroutable for local consumers and peers alike.

func (*BroadcastProducer) Close added in v0.7.6

func (b *BroadcastProducer) Close() error

Close ends the broadcast for good: it retracts and serves no new tracks. Tracks already subscribed carry on to their own end. Closing again is a no-op.

func (*BroadcastProducer) Consume

func (b *BroadcastProducer) Consume() (*BroadcastConsumer, error)

Consume returns a consumer that reads from this broadcast's tracks.

func (*BroadcastProducer) Dynamic

func (b *BroadcastProducer) Dynamic() (*BroadcastDynamic, error)

Dynamic accepts requests for tracks that are not published yet.

func (*BroadcastProducer) EncodeAudio

func (b *BroadcastProducer) EncodeAudio(name string, input AudioEncoderInput, output AudioEncoderOutput, bandwidth *Bandwidth) (*AudioProducer, error)

EncodeAudio publishes a raw-audio track with an in-process encoder.

Select the codec with OpusAudioCodec or AacAudioCodec. Pass bandwidth to reserve this track's bitrate against the session's allocator so a co-resident video encoder sizes itself against what is left.

func (*BroadcastProducer) EncodeVideo

func (b *BroadcastProducer) EncodeVideo(input VideoEncoderInput, output VideoEncoderOutput, bandwidth *Bandwidth) (*VideoProducer, error)

EncodeVideo publishes a raw-video track with an in-process H.264/H.265 encoder.

Set output.Track to choose the track name; otherwise one is derived from the codec (.avc3 / .hev1). The catalog rendition is published immediately so subscribers can discover it before the first frame exists.

Pass bandwidth to reserve this track's configured bitrate and follow the grant.

func (*BroadcastProducer) Finish deprecated

func (b *BroadcastProducer) Finish() error

Finish ends the broadcast.

Deprecated: use BroadcastProducer.Close; a broadcast end carries no cause.

func (*BroadcastProducer) PublishAudio

func (b *BroadcastProducer) PublishAudio(format AudioFormat, init []byte, opts ...AudioOption) (*MediaProducer, error)

PublishAudio publishes one audio codec as a new track, fed frame by frame with explicit timestamps. init carries the codec init bytes, which audio requires.

func (*BroadcastProducer) PublishAudioOnTrack

func (b *BroadcastProducer) PublishAudioOnTrack(request *TrackRequest, format AudioFormat, init []byte, opts ...AudioOption) (*MediaProducer, error)

PublishAudioOnTrack publishes one audio codec onto a subscriber-requested track.

func (*BroadcastProducer) PublishContainer

func (b *BroadcastProducer) PublishContainer(format ContainerFormat, init []byte) (*ContainerProducer, error)

PublishContainer publishes a container, which demuxes and publishes its own tracks. There is no label or hint: a container describes each track itself.

func (*BroadcastProducer) PublishContainerStream

func (b *BroadcastProducer) PublishContainerStream(format ContainerFormat) (*ContainerStreamProducer, error)

PublishContainerStream publishes a container fed by a raw byte stream, which recovers its own framing.

func (*BroadcastProducer) PublishJSONSnapshot

func (b *BroadcastProducer) PublishJSONSnapshot(
	name string,
	options JSONSnapshotOptions,
) (*JSONSnapshotProducer, error)

PublishJSONSnapshot opens a lossy latest-value JSON track.

func (*BroadcastProducer) PublishJSONStream

func (b *BroadcastProducer) PublishJSONStream(name string, options JSONStreamOptions) (*JSONStreamProducer, error)

PublishJSONStream opens a lossless append-log JSON track.

func (*BroadcastProducer) PublishTrack

func (b *BroadcastProducer) PublishTrack(name string, info *TrackInfo) (*TrackProducer, error)

PublishTrack creates a track that carries arbitrary byte payloads with no codec validation. info sets track properties (priority, cache, timescale); pass nil for defaults.

func (*BroadcastProducer) PublishVideo

func (b *BroadcastProducer) PublishVideo(format VideoFormat, init []byte, opts ...VideoOption) (*MediaProducer, error)

PublishVideo publishes one video codec as a new track. init may be nil for a format that resolves in band.

Example (VideoHint)

Publish a video track with catalog hints known before the first keyframe.

package main

import (
	"log"

	"moq.dev/moq"
)

func main() {
	broadcast, err := moq.NewBroadcastProducer()
	if err != nil {
		log.Fatal(err)
	}
	defer broadcast.Close()

	media, err := broadcast.PublishVideo(moq.VideoFormatAvc3, nil, moq.WithVideoHint(moq.VideoHint{}))
	if err != nil {
		log.Fatal(err)
	}
	defer media.Finish()
}

func (*BroadcastProducer) PublishVideoOnTrack

func (b *BroadcastProducer) PublishVideoOnTrack(request *TrackRequest, format VideoFormat, init []byte, opts ...VideoOption) (*MediaProducer, error)

PublishVideoOnTrack publishes one video codec onto a subscriber-requested track.

func (*BroadcastProducer) PublishVideoStream

func (b *BroadcastProducer) PublishVideoStream(format VideoFormat, opts ...VideoOption) (*MediaStreamProducer, error)

PublishVideoStream publishes a video track fed by a raw byte stream with unknown frame boundaries (e.g. Annex-B H.264). Only the self-delimiting formats work: Avc3, Hev1, Av01. Audio has no counterpart, having no frame boundaries to infer.

func (*BroadcastProducer) RemoveCatalogSection

func (b *BroadcastProducer) RemoveCatalogSection(name string) error

RemoveCatalogSection removes an untyped application catalog section by name. It is a no-op if the section was absent.

func (*BroadcastProducer) SetCatalogSection

func (b *BroadcastProducer) SetCatalogSection(name string, json string) error

SetCatalogSection sets (or replaces) an untyped application catalog section by name. json is any JSON document as a string; it rides alongside video/audio and reaches subscribers via Catalog.Sections. name must not be a reserved media section ("video"/"audio"). The catalog is republished automatically.

func (*BroadcastProducer) SetVideoProperties

func (b *BroadcastProducer) SetVideoProperties(properties VideoProperties) error

SetVideoProperties replaces the catalog properties shared by every video rendition.

func (*BroadcastProducer) Unannounce

func (b *BroadcastProducer) Unannounce() error

Unannounce retracts this broadcast's exact-path advertisement, if any, from local consumers and peers alike. Tracks already in flight carry on.

type BroadcastRequest

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

BroadcastRequest is a requested broadcast that has not been accepted yet.

func (*BroadcastRequest) Accept

func (r *BroadcastRequest) Accept(broadcast *BroadcastProducer) error

Accept serves the request with an unannounced broadcast.

func (*BroadcastRequest) Path

func (r *BroadcastRequest) Path() (string, error)

Path returns the requested broadcast path.

func (*BroadcastRequest) Reject

func (r *BroadcastRequest) Reject(errorCode uint16) error

Reject fails the request with an application error code.

type Catalog

type Catalog = ffi.MoqCatalog

Catalog is a broadcast's manifest: its video and audio renditions plus display metadata.

type CatalogConsumer

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

CatalogConsumer is a stream of catalog updates.

func (*CatalogConsumer) Cancel

func (c *CatalogConsumer) Cancel()

Cancel stops the stream.

func (*CatalogConsumer) Next

func (c *CatalogConsumer) Next(ctx context.Context) (*Catalog, error)

Next returns the next catalog, or (nil, nil) when the track ends.

func (*CatalogConsumer) Updates

func (c *CatalogConsumer) Updates(ctx context.Context) iter.Seq2[*Catalog, error]

Updates ranges over catalog updates until the track ends or the loop breaks.

type Client

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

Client is a connected MoQ client with automatic origin wiring. When no origin option is given, both sides share one origin, so a broadcast announced here is also discoverable here.

func Dial

func Dial(ctx context.Context, url string, opts ...ClientOption) (*Client, error)

Dial connects to a MoQ server and returns the established client. Cancel ctx to abort an in-flight connect.

func (*Client) Announced

func (c *Client) Announced(options AnnounceOptions) (*AnnounceConsumer, error)

Announced streams routes announced by the remote under a pattern scope.

Example

Subscribe to a broadcast and print its catalog. These examples have no Output line, so they are compiled (API-checked) but not executed.

package main

import (
	"context"
	"fmt"
	"log"

	"moq.dev/moq"
)

func main() {
	ctx := context.Background()

	client, err := moq.Dial(ctx, "https://relay.example.com")
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	announced, err := client.Announced(moq.AnnounceOptions{Prefix: "demos/"})
	if err != nil {
		log.Fatal(err)
	}
	defer announced.Cancel()

	for ann, err := range announced.All(ctx) {
		if err != nil {
			if moq.IsShutdown(err) {
				break
			}
			log.Fatal(err)
		}
		if !ann.Active() {
			continue
		}
		fmt.Println("broadcast:", ann.Prefix())
	}
}

func (*Client) AnnouncedBroadcast

func (c *Client) AnnouncedBroadcast(path string) (*AnnouncedBroadcast, error)

AnnouncedBroadcast waits for a route covering path, then resolves the broadcast there.

func (*Client) Close

func (c *Client) Close() error

Close gracefully shuts down the session and stops the client. Safe to call more than once.

func (*Client) CreateBroadcast

func (c *Client) CreateBroadcast(path string) (*BroadcastProducer, error)

CreateBroadcast creates an unannounced broadcast at path, invisible to everyone until announced. Announce it after populating tracks.

See OriginProducer.CreateBroadcast.

Example

Publish a media track to a relay.

ctx := context.Background()

client, err := moq.Dial(ctx, "https://relay.example.com")
if err != nil {
	log.Fatal(err)
}
defer client.Close()

broadcast, err := client.CreateBroadcast("me/mic")
if err != nil {
	log.Fatal(err)
}
// Closing ends the broadcast for good.
defer broadcast.Close()

media, err := broadcast.PublishAudio(moq.AudioFormatOpus, opusHead())
if err != nil {
	log.Fatal(err)
}
_ = broadcast.Announce(moq.Route{})

if err := media.WriteFrame(moq.Frame{Payload: []byte("opus frame")}); err != nil {
	log.Fatal(err)
}

func (*Client) RequestBroadcast

func (c *Client) RequestBroadcast(ctx context.Context, path string) (*BroadcastConsumer, error)

RequestBroadcast resolves a broadcast at path as soon as it can be served: an existing exact-path broadcast, a covering announced route, or a dynamic fallback on the origin, or an error. Unlike AnnouncedBroadcast, it does not wait for a future announcement.

func (*Client) Session

func (c *Client) Session() *Session

Session returns the underlying session. Hold the client (or session) to keep the connection alive.

Example (Stats)

Connect with pinned TLS material and read a stats snapshot.

package main

import (
	"context"
	"fmt"
	"log"

	"moq.dev/moq"
)

func main() {
	ctx := context.Background()

	client, err := moq.Dial(ctx, "https://relay.example.com",
		moq.WithTLSRoots("/etc/ssl/custom-ca.pem"),
		moq.WithTLSSystemRoots(true),
		moq.WithTLSFingerprints("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	stats := client.Session().Stats()
	fmt.Println("rtt:", stats.RttUs)
}

type ClientOption

type ClientOption func(*clientConfig)

ClientOption configures a client created with Dial.

func WithBackoff

func WithBackoff(backoff Backoff) ClientOption

WithBackoff sets retry pacing for the automatic reconnect.

func WithBind

func WithBind(addr string) ClientOption

WithBind sets the local UDP socket bind address (default "[::]:0").

func WithClientTLSCert

func WithClientTLSCert(path string) ClientOption

WithClientTLSCert sets the path to a PEM certificate chain for mTLS.

func WithClientTLSKey

func WithClientTLSKey(path string) ClientOption

WithClientTLSKey sets the path to a PEM private key for mTLS.

func WithPublishOrigin

func WithPublishOrigin(o *OriginProducer) ClientOption

WithPublishOrigin sets the origin whose broadcasts are published to the remote. Pair with WithSubscribeOrigin for full control; omit both to get a shared internal origin.

func WithQUICMaxStreams

func WithQUICMaxStreams(maxStreams uint64) ClientOption

WithQUICMaxStreams caps the concurrent QUIC streams the peer may open toward this connection (default 1024). MoQ opens a stream per group, and for a subscriber those arrive from the relay, so a client subscribing to many tracks wants this raised. A publisher's own streams are bounded by the relay's advertised limit, not this one. Ignored by the WebSocket fallback.

func WithReconnect

func WithReconnect(enabled bool) ClientOption

WithReconnect toggles automatic reconnecting. It is on by default: the session redials with backoff whenever the transport drops, and broadcasts consumed through it ride out the gap. Pass false for a one-shot dial whose transport close ends the session.

func WithSubscribeOrigin

func WithSubscribeOrigin(o *OriginProducer) ClientOption

WithSubscribeOrigin sets the origin that receives broadcasts consumed from the remote.

func WithTLSFingerprints

func WithTLSFingerprints(fingerprints ...string) ClientOption

WithTLSFingerprints pins the peer to one of these SHA-256 certificate fingerprints.

func WithTLSRoots

func WithTLSRoots(paths ...string) ClientOption

WithTLSRoots trusts PEM root certificate files instead of the system roots.

func WithTLSSystemRoots

func WithTLSSystemRoots(systemRoots bool) ClientOption

WithTLSSystemRoots controls whether platform roots are trusted with custom roots.

func WithTLSVerify

func WithTLSVerify(verify bool) ClientOption

WithTLSVerify toggles TLS certificate verification. Verification is on by default; pass false only against a relay with a self-signed certificate during development.

func WithWebSocketDelay added in v0.7.3

func WithWebSocketDelay(delay time.Duration) ClientOption

WithWebSocketDelay sets the head start QUIC gets before the WebSocket fallback joins the race (default 200ms). Zero races both at once, and a negative delay fails Dial.

func WithWebSocketEnabled added in v0.7.3

func WithWebSocketEnabled(enabled bool) ClientOption

WithWebSocketEnabled toggles the WebSocket fallback, which races QUIC for http(s) URLs. It is on by default; pass false against a relay that only serves QUIC.

type ConnectionStats

type ConnectionStats = ffi.MoqConnectionStats

ConnectionStats holds transport metrics for a session (RTT, bandwidth, byte and packet counters); each field is nil when unreported.

type ConnectionStatus

type ConnectionStatus = ffi.MoqConnectionStatus

ConnectionStatus is a connection lifecycle transition reported by Session.Status.

type Container

type Container = ffi.MoqContainer

Container selects how subscribed media frames are demuxed. Build one with LegacyContainer, CmafContainer, or LocContainer.

func CmafContainer

func CmafContainer(init []byte) Container

CmafContainer selects the CMAF (fMP4) container for a media subscription, initialized from the given init segment.

func LegacyContainer

func LegacyContainer() Container

LegacyContainer selects the legacy hang container for a media subscription.

func LocContainer

func LocContainer() Container

LocContainer selects the low-overhead container for a media subscription.

type ContainerCmaf

type ContainerCmaf = ffi.MoqContainerCmaf

ContainerCmaf is the CMAF (fMP4) container variant of Container, carrying its init segment; build one with CmafContainer.

type ContainerFormat

type ContainerFormat = ffi.MoqContainerFormat

ContainerFormat is a container that publishes its own tracks.

type ContainerLegacy

type ContainerLegacy = ffi.MoqContainerLegacy

ContainerLegacy is the legacy hang container variant of Container; build one with LegacyContainer.

type ContainerLoc

type ContainerLoc = ffi.MoqContainerLoc

ContainerLoc is the low-overhead container variant of Container; build one with LocContainer.

type ContainerProducer

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

ContainerProducer publishes a container, which demuxes and publishes its own tracks. Unlike MediaProducer there is no per-frame timestamp: a container carries its tracks' timing itself.

func (*ContainerProducer) Cut

func (c *ContainerProducer) Cut() error

Cut declares that the next chunk starts a new segment, rolling a group on every track. An fMP4 source carrying styp atoms declares its own, so this is only needed when it doesn't; MKV, TS, and FLV ignore it.

func (*ContainerProducer) Finish

func (c *ContainerProducer) Finish() error

Finish finishes every track this container publishes.

func (*ContainerProducer) Seek

func (c *ContainerProducer) Seek(sequence uint64) error

Seek starts a new segment and numbers its groups sequence.

func (*ContainerProducer) Write

func (c *ContainerProducer) Write(payload []byte) error

Write pushes a whole chunk of container bytes.

type ContainerStreamProducer

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

ContainerStreamProducer publishes a container fed by a raw byte stream, which recovers its own framing.

func (*ContainerStreamProducer) Finish

func (c *ContainerStreamProducer) Finish() error

Finish finishes every track this container publishes.

func (*ContainerStreamProducer) Write

func (c *ContainerStreamProducer) Write(payload []byte) error

Write pushes raw container bytes; chunk boundaries don't matter.

type Datagram

type Datagram = ffi.MoqDatagram

Datagram is a best-effort track datagram as received: sequence number, timestamp, and payload.

type Dimensions

type Dimensions = ffi.MoqDimensions

Dimensions is a width and height in pixels.

type Error

type Error = ffi.MoqError

Error is the error type returned across the FFI boundary. Compare against the sentinels below with errors.Is, or use one of the Is* helpers for the common cases.

type ErrorScope

type ErrorScope = ffi.MoqErrorScope

ErrorScope is whether a protocol code is from the session or stream registry.

type FetchGroupOptions

type FetchGroupOptions = ffi.MoqFetchGroupOptions

FetchGroupOptions configures a single FetchGroup call, currently just the delivery priority.

type Frame

type Frame = ffi.MoqFrame

Frame is a raw track frame: a payload and its presentation timestamp in microseconds.

type GroupConsumer

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

GroupConsumer is a stream of timestamped raw frames within a single group.

func (*GroupConsumer) Cancel

func (g *GroupConsumer) Cancel()

Cancel stops the stream.

func (*GroupConsumer) Frames

func (g *GroupConsumer) Frames(ctx context.Context) iter.Seq2[*Frame, error]

Frames ranges over timestamped frames until the group ends or the loop breaks.

func (*GroupConsumer) ReadFrame

func (g *GroupConsumer) ReadFrame(ctx context.Context) (*Frame, error)

ReadFrame returns the next timestamped frame, or (nil, nil) when the group ends.

func (*GroupConsumer) Sequence

func (g *GroupConsumer) Sequence() uint64

Sequence is this group's sequence number within the track.

type GroupProducer

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

GroupProducer writes frames into a single group on a track.

func (*GroupProducer) Abort

func (g *GroupProducer) Abort(errorCode uint16) error

Abort terminates the group with an application error code.

func (*GroupProducer) Consume

func (g *GroupProducer) Consume() (*GroupConsumer, error)

Consume reads frames from this group.

func (*GroupProducer) Finish

func (g *GroupProducer) Finish() error

Finish marks the group complete. The handle remains so Abort can still run.

func (*GroupProducer) Sequence

func (g *GroupProducer) Sequence() uint64

Sequence is this group's sequence number within the track.

func (*GroupProducer) WriteFrame

func (g *GroupProducer) WriteFrame(frame Frame) error

WriteFrame appends frame to the group.

type GroupRequest

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

GroupRequest requests one uncached group from a track producer.

func (*GroupRequest) Abort

func (r *GroupRequest) Abort(errorCode uint16) error

Abort rejects the fetch with an application error code.

func (*GroupRequest) Accept

func (r *GroupRequest) Accept() (*GroupProducer, error)

Accept accepts the request and returns a producer for the group.

func (*GroupRequest) Priority

func (r *GroupRequest) Priority() uint8

Priority is the consumer's delivery priority for this fetch.

func (*GroupRequest) Sequence

func (r *GroupRequest) Sequence() uint64

Sequence is the requested group sequence within the track.

type JSONSnapshotConsumer

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

JSONSnapshotConsumer receives the latest reconstructed JSON value.

func (*JSONSnapshotConsumer) Cancel

func (c *JSONSnapshotConsumer) Cancel()

Cancel stops current and future reads.

func (*JSONSnapshotConsumer) Next

Next returns the next JSON value, or nil when the track ends.

func (*JSONSnapshotConsumer) Values

Values ranges over reconstructed JSON values until the track ends.

type JSONSnapshotOptions

type JSONSnapshotOptions struct {
	// DeltaRatio controls how aggressively deltas replace full snapshots. Nil uses
	// [DefaultDeltaRatio]; a pointer to zero disables deltas entirely.
	DeltaRatio *uint32
	// Compression enables group-scoped DEFLATE and must match on the consumer.
	Compression bool
}

JSONSnapshotOptions configures publishing a lossy latest-value JSON track.

type JSONSnapshotProducer

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

JSONSnapshotProducer publishes a JSON value as lossy latest state.

func (*JSONSnapshotProducer) Demand

func (p *JSONSnapshotProducer) Demand() (*TrackDemand, error)

Demand returns a watch-only handle to whether the track has subscribers.

func (*JSONSnapshotProducer) Finish

func (p *JSONSnapshotProducer) Finish() error

Finish closes the snapshot track.

func (*JSONSnapshotProducer) Update

func (p *JSONSnapshotProducer) Update(value any) error

Update publishes value as a JSON snapshot or delta. It is a no-op when unchanged.

type JSONStreamConsumer

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

JSONStreamConsumer receives every JSON record in order.

func (*JSONStreamConsumer) Cancel

func (c *JSONStreamConsumer) Cancel()

Cancel stops current and future reads.

func (*JSONStreamConsumer) Next

Next returns the next JSON record, or nil when the track ends.

func (*JSONStreamConsumer) Values

Values ranges over every JSON record until the track ends.

type JSONStreamOptions

type JSONStreamOptions struct {
	// Compression enables group-scoped DEFLATE and must match on the consumer.
	Compression bool
}

JSONStreamOptions configures publishing a lossless append-log JSON track.

type JSONStreamProducer

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

JSONStreamProducer publishes an ordered lossless log of JSON records.

func (*JSONStreamProducer) Append

func (p *JSONStreamProducer) Append(value any) error

Append adds one JSON record to the log.

func (*JSONStreamProducer) Demand

func (p *JSONStreamProducer) Demand() (*TrackDemand, error)

Demand returns a watch-only handle to whether the track has subscribers.

func (*JSONStreamProducer) Finish

func (p *JSONStreamProducer) Finish() error

Finish closes the stream track.

type JSONSubscribeOptions

type JSONSubscribeOptions struct {
	// Compression enables group-scoped DEFLATE and must match the producer.
	Compression bool
}

JSONSubscribeOptions configures subscribing to either kind of JSON track.

Delta encoding is a producer-side choice the consumer reconstructs automatically, so only the compression setting has to match.

type MediaConsumer

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

MediaConsumer is a stream of decoded media frames.

func (*MediaConsumer) Cancel

func (m *MediaConsumer) Cancel()

Cancel stops the stream.

func (*MediaConsumer) Frames

Frames ranges over frames until the track ends or the loop breaks.

func (*MediaConsumer) Next

func (m *MediaConsumer) Next(ctx context.Context) (*MediaFrame, error)

Next returns the next frame, or (nil, nil) when the track ends.

type MediaFrame

type MediaFrame = ffi.MoqMediaFrame

MediaFrame is a Frame plus a flag for group starts or video keyframes; audio flags only group starts.

type MediaGroupConsumer

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

MediaGroupConsumer is a finite stream of decoded media frames from one fetched group. It ends after the group's last frame.

func (*MediaGroupConsumer) Cancel

func (m *MediaGroupConsumer) Cancel()

Cancel stops the stream.

func (*MediaGroupConsumer) Frames

Frames ranges over decoded frames until the group ends or the loop breaks.

func (*MediaGroupConsumer) Next

Next returns the next decoded frame, or (nil, nil) when the group ends.

func (*MediaGroupConsumer) Sequence

func (m *MediaGroupConsumer) Sequence() uint64

Sequence is this group's sequence number within the track.

type MediaProducer

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

MediaProducer writes timestamped frames into a media track.

func (*MediaProducer) Cut

func (m *MediaProducer) Cut() error

Cut draws a group boundary here.

Audio has no boundary of its own (every packet is independently decodable), so this is the only thing that gives it groups: call it after every frame for one group (one QUIC stream) the relay forwards without waiting, or at a segment cadence to align with video. Video groups at its own keyframes and needs this only to override that.

On a container this declares a new segment, rolling a group on every track it publishes.

func (*MediaProducer) Demand

func (m *MediaProducer) Demand() (*TrackDemand, error)

Demand returns a watch-only handle to whether the track has subscribers.

func (*MediaProducer) Discontinuity added in v0.7.6

func (m *MediaProducer) Discontinuity() error

Discontinuity marks a timeline break and restarts handoff measurement, preserving advertised jitter.

func (*MediaProducer) Finish

func (m *MediaProducer) Finish() error

Finish closes the media track.

func (*MediaProducer) Flush added in v0.7.3

func (m *MediaProducer) Flush(timestampUs uint64) error

Flush records a local encoder's frame handoff on the broadcast media clock. Call after WriteFrame only for local encoder output, not file or network imports.

func (*MediaProducer) Name

func (m *MediaProducer) Name() (string, error)

Name is the generated media track name.

func (*MediaProducer) Seek

func (m *MediaProducer) Seek(sequence uint64) error

Seek draws a group boundary and numbers the next group sequence.

Cut with an explicit sequence, for a publisher whose group numbers have to be deterministic: two encoders aligning per GOP so a consumer can fail over between them.

func (*MediaProducer) Unused

func (m *MediaProducer) Unused(ctx context.Context) error

Unused blocks until the track has no active subscribers. Prefer Demand.

func (*MediaProducer) Used

func (m *MediaProducer) Used(ctx context.Context) error

Used blocks until the track has at least one active subscriber. Prefer Demand.

func (*MediaProducer) WriteFrame

func (m *MediaProducer) WriteFrame(frame Frame) error

WriteFrame appends frame to the media track. The importer derives keyframe status from the bitstream, so a Frame carries only the payload and its timestamp.

type MediaStreamProducer

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

MediaStreamProducer feeds a raw encoder byte stream; whole frames are emitted as they complete.

func (*MediaStreamProducer) Finish

func (m *MediaStreamProducer) Finish() error

Finish closes the stream.

func (*MediaStreamProducer) Write

func (m *MediaStreamProducer) Write(payload []byte) error

Write pushes raw stream bytes.

type OriginConfig

type OriginConfig = ffi.MoqOriginConfig

OriginConfig configures a new origin, such as its maximum cache size in bytes.

type OriginConsumer

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

OriginConsumer discovers and requests broadcasts published to an origin.

func (*OriginConsumer) Announced

func (o *OriginConsumer) Announced(options AnnounceOptions) (*AnnounceConsumer, error)

Announced streams routes under a literal prefix matching an optional pattern filter.

func (*OriginConsumer) AnnouncedBroadcast

func (o *OriginConsumer) AnnouncedBroadcast(path string) (*AnnouncedBroadcast, error)

AnnouncedBroadcast waits for a route covering an exact path, then resolves the broadcast there.

func (*OriginConsumer) RequestBroadcast

func (o *OriginConsumer) RequestBroadcast(ctx context.Context, path string) (*BroadcastConsumer, error)

RequestBroadcast resolves a broadcast at path as soon as it can be served, through the best announced route covering it: an announced broadcast on this origin, a route a session announced (served on demand by that session), or a dynamic handler on the origin; errors if nothing can serve it, including a broadcast created but not announced. Unlike AnnouncedBroadcast, it does not wait for a future announcement. Blocks until resolved.

type OriginDynamic

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

OriginDynamic streams requests for paths with no existing exact-path broadcast.

func (*OriginDynamic) Cancel

func (d *OriginDynamic) Cancel()

Cancel stops serving requested broadcasts and retracts the route.

func (*OriginDynamic) RequestedBroadcast

func (d *OriginDynamic) RequestedBroadcast(ctx context.Context) (*BroadcastRequest, error)

RequestedBroadcast blocks until a consumer requests a path with no existing exact-path broadcast.

func (*OriginDynamic) Requests

Requests ranges over requested broadcasts until the stream errors or the loop breaks.

func (*OriginDynamic) Update

func (d *OriginDynamic) Update(route Route) error

Update re-prices the route in place: replaces its hops and costs.

type OriginProducer

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

OriginProducer publishes broadcasts under paths and hands out consumers that discover them. Wire one as both a client's/server's publish source and consume sink for a full-duplex peer.

There is no Close: the origin ends once the collector reaches every owner (each producer, published broadcast, and OriginDynamic), and its consumers then fail with ErrClosed. Keep an owner reachable for as long as the origin should live.

func NewOriginProducer

func NewOriginProducer() *OriginProducer

NewOriginProducer creates an empty origin.

func NewOriginProducerWithConfig

func NewOriginProducerWithConfig(config OriginConfig) *OriginProducer

NewOriginProducerWithConfig creates an origin with explicit config.

func (*OriginProducer) Consume

func (o *OriginProducer) Consume() *OriginConsumer

Consume returns a consumer that observes broadcasts published to this origin.

func (*OriginProducer) CreateBroadcast

func (o *OriginProducer) CreateBroadcast(path string) (*BroadcastProducer, error)

CreateBroadcast creates a broadcast at the given path, returning the producer that feeds it.

The broadcast is invisible and unroutable, for this origin's consumers and peers alike, until BroadcastProducer.Announce. Announce it after populating tracks. BroadcastProducer.Close ends it for good; dropping the last handle does the same.

func (*OriginProducer) Dynamic

func (o *OriginProducer) Dynamic(prefix string, route Route) (*OriginDynamic, error)

Dynamic advertises prefix and serves the requests beneath it.

A route claims prefix and every path beneath it ("" claims every path). A service that only serves some of them rejects the rest as they are requested. Create, Dynamic if tracks are served on demand, populate, then BroadcastProducer.Announce.

type ProtocolKind

type ProtocolKind = ffi.MoqProtocolKind

ProtocolKind is a recognized protocol kind, or App / Unknown when the code is not named.

type Request

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

Request is an incoming session that can be accepted (Accept) or rejected (Reject). Dropping a Request without responding closes the connection silently.

func (*Request) Accept

func (r *Request) Accept(ctx context.Context) (*Session, error)

Accept completes the handshake and returns the established session. Hold the session to keep the connection alive.

func (*Request) Cancel

func (r *Request) Cancel()

Cancel aborts an in-flight Accept or Reject.

func (*Request) Path

func (r *Request) Path() string

Path is the query-free request path, or an empty string for the root/missing path.

func (*Request) Query

func (r *Request) Query() *string

Query is the encoded request query without "?"; it may contain credentials.

func (*Request) Reject

func (r *Request) Reject(ctx context.Context, code uint16) error

Reject refuses the session with an application error code; 401 and 403 map to unauthorized.

func (*Request) SetConsume

func (r *Request) SetConsume(o *OriginProducer) error

SetConsume overrides the consume origin for this session. Pass nil to fall back to the server's configured consume origin. Captured at Accept.

func (*Request) SetPublish

func (r *Request) SetPublish(o *OriginProducer) error

SetPublish overrides the publish origin for this session. Pass nil to fall back to the server's configured publish origin. Captured at Accept.

func (*Request) Transport

func (r *Request) Transport() Transport

Transport is the wire transport the request arrived over, e.g. TransportQUIC.

func (*Request) URL

func (r *Request) URL() *string

URL is the requested URL, if any.

type Reservation

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

Reservation is one track's standing claim on a Bandwidth.

Grant is a snapshot: nil means no estimate or no demand, so hold the current rate, and 0 is a real zero grant.

func (*Reservation) Grant

func (r *Reservation) Grant() *uint64

Grant returns this reservation's slice right now, in bits per second.

func (*Reservation) Update

func (r *Reservation) Update(maxBps uint64)

Update changes the ceiling, keeping the same claim.

type Route

type Route = ffi.MoqRoute

Route is the hop chain a broadcast takes to reach an origin, and its costs: warm Cost plus undiscounted Cold (nil Cold means Cost).

type Server

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

Server accepts incoming sessions with automatic origin wiring.

func Listen

func Listen(ctx context.Context, bind string, opts ...ServerOption) (*Server, error)

Listen binds the server and starts accepting. Cancel ctx to abort the bind.

Example

Run a server with a self-signed certificate, accepting every session.

package main

import (
	"context"
	"log"

	"moq.dev/moq"
)

func main() {
	ctx := context.Background()

	server, err := moq.Listen(ctx, "127.0.0.1:4443", moq.WithTLSGenerate("localhost"))
	if err != nil {
		log.Fatal(err)
	}
	defer server.Close()

	if err := server.Serve(ctx); err != nil && !moq.IsShutdown(err) {
		log.Fatal(err)
	}
}

func (*Server) Accept

func (s *Server) Accept(ctx context.Context) (*Request, error)

Accept returns the next incoming request, or (nil, nil) when the server stops.

Cancelling ctx aborts this accept alone and leaves the server listening; use Close to tear the listener down.

func (*Server) CertFingerprints

func (s *Server) CertFingerprints() ([]string, error)

CertFingerprints returns the SHA-256 fingerprints of the configured TLS certificates, hex-encoded. Useful for pinning a generated self-signed certificate in a browser via WebTransport's serverCertificateHashes.

func (*Server) Close

func (s *Server) Close() error

Close stops accepting new sessions and releases the listening socket before it returns, so the same address can be bound again immediately. In-flight sessions stay alive until their handles are dropped or cancelled. Safe to call more than once and from multiple goroutines (Serve calls it on ctx-driven shutdown).

func (*Server) CreateBroadcast

func (s *Server) CreateBroadcast(path string) (*BroadcastProducer, error)

CreateBroadcast creates an unannounced broadcast at path, invisible to everyone until announced. Announce it after populating tracks.

See OriginProducer.CreateBroadcast.

func (*Server) LocalAddr

func (s *Server) LocalAddr() string

LocalAddr is the bound local address.

func (*Server) Requests

func (s *Server) Requests(ctx context.Context) iter.Seq2[*Request, error]

Requests ranges over incoming requests until the server stops or the loop breaks. Each request must be answered with Accept or Reject.

Example

Drive the accept loop directly to decide which sessions to admit.

package main

import (
	"context"
	"log"

	"moq.dev/moq"
)

func main() {
	ctx := context.Background()

	server, err := moq.Listen(ctx, "127.0.0.1:4443", moq.WithTLSGenerate("localhost"))
	if err != nil {
		log.Fatal(err)
	}
	defer server.Close()

	for req, err := range server.Requests(ctx) {
		if err != nil {
			if moq.IsShutdown(err) {
				break
			}
			log.Fatal(err)
		}

		// Reject anything that didn't arrive over QUIC.
		if req.Transport() != moq.TransportQUIC {
			_ = req.Reject(ctx, 403)
			continue
		}

		session, err := req.Accept(ctx)
		if err != nil {
			continue
		}
		// Hold the session to keep the connection alive.
		go func() { _ = session.Closed(ctx) }()
	}
}

func (*Server) Serve

func (s *Server) Serve(ctx context.Context) error

Serve accepts every session in a loop, holding each one alive in its own goroutine until it closes, so memory does not grow with past connections. It returns when Accept stops (nil) or fails, after the in-flight sessions wind down.

To inspect or reject requests, range over Requests instead:

for req, err := range server.Requests(ctx) {
    if err != nil {
        return err
    }
    if req.Path() == "/admin" {
        _ = req.Reject(ctx, 403)
        continue
    }
    session, err := req.Accept(ctx)
    // hold the session to keep the connection alive
}

type ServerOption

type ServerOption func(*serverConfig)

ServerOption configures a server created with Listen.

func WithServerPublishOrigin

func WithServerPublishOrigin(o *OriginProducer) ServerOption

WithServerPublishOrigin sets the origin whose broadcasts are served to incoming sessions. Omit both origin options to get a shared internal origin.

func WithServerSubscribeOrigin

func WithServerSubscribeOrigin(o *OriginProducer) ServerOption

WithServerSubscribeOrigin sets the origin that receives broadcasts published by incoming sessions.

func WithTLSCert

func WithTLSCert(paths ...string) ServerOption

WithTLSCert sets paths to TLS certificate chains.

func WithTLSGenerate

func WithTLSGenerate(hostnames ...string) ServerOption

WithTLSGenerate generates a self-signed certificate for the given hostnames.

func WithTLSKey

func WithTLSKey(paths ...string) ServerOption

WithTLSKey sets paths to TLS private keys.

type Session

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

Session is an established MoQ connection. Hold it (or the Client/Server that produced it) to keep the connection alive; once every handle is dropped the connection closes.

func (*Session) Bandwidth

func (s *Session) Bandwidth() *Bandwidth

Bandwidth is the session's bandwidth allocator. Every call returns a handle to the same registry, so reservations made through one are visible to the others. A client handle survives reconnects: the grant is nil while disconnected and resumes on the next connection.

func (*Session) Cancel

func (s *Session) Cancel(code uint32)

Cancel closes the session abruptly with an application error code.

func (*Session) Closed

func (s *Session) Closed(ctx context.Context) error

Closed blocks until the session closes and returns the reason. A graceful close reports an error for which IsShutdown returns true. Cancelling ctx gives up waiting and shuts the session down, so a caller that no longer cares about the connection can tear it down by cancelling.

func (*Session) Consume

func (s *Session) Consume() *OriginConsumer

Consume returns the origin used to receive broadcasts from the remote.

func (*Session) Epoch

func (s *Session) Epoch() uint64

Epoch is the connection epoch: 1 for the connect that built this session, one more on each reconnect. A server-accepted session stays at 1.

Pair it with Status to log each reconnect by number: a StatusConnected whose Epoch grew is a reconnect. Like Status, it reports the current state, so a drop that reconnects between reads is coalesced away.

func (*Session) Publish

func (s *Session) Publish() *OriginProducer

Publish returns the origin used to advertise local broadcasts to the remote.

func (*Session) Shutdown

func (s *Session) Shutdown()

Shutdown closes the session gracefully.

func (*Session) Stats

func (s *Session) Stats() ConnectionStats

Stats snapshots the current connection statistics.

func (*Session) Status

func (s *Session) Status(ctx context.Context) (ConnectionStatus, error)

Status blocks until the connection status differs from the one this session last reported. A client session reports StatusConnected first (the connect it was built from), then follows the reconnect loop: StatusDisconnected while redialing, StatusMigrating during a GOAWAY handover. It returns an error once the connection stops for good. A server-accepted session's only transition is terminal, so Status waits for the close and returns its reason. Cancelling ctx gives up waiting and shuts the session down.

This reports the current status rather than every edge: a drop that reconnects before the next call is coalesced away, so the outages it hides are the ones that already healed. Don't count outages with it.

type Subscription

type Subscription = ffi.MoqSubscription

Subscription holds subscriber-side delivery preferences: priority, ordering, max age, and group range.

type TrackConsumer

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

TrackConsumer is a stream of groups from a track. Each group is itself a stream of timestamped raw frames.

func (*TrackConsumer) Cancel

func (t *TrackConsumer) Cancel()

Cancel stops the stream.

func (*TrackConsumer) Datagrams

func (t *TrackConsumer) Datagrams(ctx context.Context) iter.Seq2[*Datagram, error]

Datagrams ranges over best-effort datagrams in arrival order.

func (*TrackConsumer) Groups

Groups ranges over groups in sequence order.

func (*TrackConsumer) GroupsAsArrived

func (t *TrackConsumer) GroupsAsArrived(ctx context.Context) iter.Seq2[*GroupConsumer, error]

GroupsAsArrived ranges over groups in arrival order, including out-of-sequence deliveries.

func (*TrackConsumer) Info

func (t *TrackConsumer) Info() (TrackInfo, error)

Info returns the publisher-side track properties learned during subscription.

func (*TrackConsumer) NextGroup

func (t *TrackConsumer) NextGroup(ctx context.Context) (*GroupConsumer, error)

NextGroup returns the next group in sequence order, skipping forward if behind, or (nil, nil) when the track ends. Prefer this when order matters more than latency. Shares the sequence cursor with ReadFrame: a group one method has already taken is not returned by the other.

func (*TrackConsumer) ReadFrame

func (t *TrackConsumer) ReadFrame(ctx context.Context) (*Frame, error)

ReadFrame reads the first timestamped frame of the next group, or (nil, nil) when the track ends. Convenient for one-frame-per-group tracks. Completed empty groups are skipped; a nil frame is track EOF, not an empty group. Cancelling the context cancels this consumer, not just this call: see package docs.

func (*TrackConsumer) RecvDatagram

func (t *TrackConsumer) RecvDatagram(ctx context.Context) (*Datagram, error)

RecvDatagram returns the next best-effort datagram in arrival order, or (nil, nil) when the track ends.

func (*TrackConsumer) RecvGroup

func (t *TrackConsumer) RecvGroup(ctx context.Context) (*GroupConsumer, error)

RecvGroup returns the next group in arrival order (possibly out of sequence), or (nil, nil) when the track ends. Prefer this for live, latency-sensitive consumption.

func (*TrackConsumer) Update

func (t *TrackConsumer) Update(subscription Subscription)

Update changes this subscriber's delivery preferences.

type TrackDemand

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

TrackDemand watches whether a published track has subscribers.

It is weak: holding it neither keeps the track open nor locks the producer, so a wait can park here while the producer keeps publishing. Waits return ErrClosed once the track is released.

func (*TrackDemand) IsUsed

func (d *TrackDemand) IsUsed() bool

IsUsed reports whether the track has at least one active subscriber right now.

func (*TrackDemand) Name

func (d *TrackDemand) Name() string

Name is the name of the track this watches.

func (*TrackDemand) Unused

func (d *TrackDemand) Unused(ctx context.Context) error

Unused blocks until the track has no active subscribers.

func (*TrackDemand) Used

func (d *TrackDemand) Used(ctx context.Context) error

Used blocks until the track has at least one active subscriber.

type TrackDynamic

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

TrackDynamic yields uncached groups requested by fetch consumers.

func (*TrackDynamic) Cancel

func (d *TrackDynamic) Cancel()

Cancel stops current and future requested-group waits.

func (*TrackDynamic) RequestedGroup

func (d *TrackDynamic) RequestedGroup(ctx context.Context) (*GroupRequest, error)

RequestedGroup waits for the next uncached group request.

func (*TrackDynamic) Requests

func (d *TrackDynamic) Requests(ctx context.Context) iter.Seq2[*GroupRequest, error]

Requests ranges over uncached group requests until the dynamic source ends.

type TrackInfo

type TrackInfo = ffi.MoqTrackInfo

TrackInfo holds publisher-side track properties: priority, ordering, max age, and timescale. A zero Priority is the least urgent, not the default; set 127 for the midpoint a nil TrackInfo uses.

type TrackProducer

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

TrackProducer writes arbitrary byte payloads with no codec required.

func (*TrackProducer) Abort

func (t *TrackProducer) Abort(errorCode uint16) error

Abort closes the track with an application error code.

func (*TrackProducer) AppendDatagram

func (t *TrackProducer) AppendDatagram(frame Frame) (uint64, error)

AppendDatagram sends frame as a best-effort datagram and returns the sequence number assigned to it. Payloads are capped at 1200 bytes. There is no stream fallback.

func (*TrackProducer) AppendGroup

func (t *TrackProducer) AppendGroup() (*GroupProducer, error)

AppendGroup starts a new group; write frames into it, then Finish.

func (*TrackProducer) Consume

func (t *TrackProducer) Consume(subscription *Subscription) (*TrackConsumer, error)

Consume reads directly from this producer's track. subscription tunes delivery (delivery priority, group range); pass nil for defaults.

func (*TrackProducer) CreateGroup

func (t *TrackProducer) CreateGroup(sequence uint64) (*GroupProducer, error)

CreateGroup creates a group with an explicit sequence number.

func (*TrackProducer) Demand

func (t *TrackProducer) Demand() (*TrackDemand, error)

Demand returns a watch-only handle to whether the track has subscribers.

func (*TrackProducer) Dynamic

func (t *TrackProducer) Dynamic() (*TrackDynamic, error)

Dynamic serves fetches for groups that are not currently cached.

func (*TrackProducer) Finish

func (t *TrackProducer) Finish() error

Finish ends the track at the live edge. The handle remains so Abort can still run.

func (*TrackProducer) FinishAt

func (t *TrackProducer) FinishAt(finalSequence uint64) error

FinishAt declares the exclusive final group sequence ahead of the live edge. The producer remains open for groups below the boundary.

func (*TrackProducer) Name

func (t *TrackProducer) Name() (string, error)

Name is the track name.

func (*TrackProducer) Unused

func (t *TrackProducer) Unused(ctx context.Context) error

Unused blocks until the track has no active subscribers. Prefer Demand.

func (*TrackProducer) Used

func (t *TrackProducer) Used(ctx context.Context) error

Used blocks until the track has at least one active subscriber. Prefer Demand.

func (*TrackProducer) WriteFrame

func (t *TrackProducer) WriteFrame(frame Frame) error

WriteFrame writes frame as a single-frame group.

type TrackRequest

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

TrackRequest is a subscriber-requested track that has not been accepted yet.

func (*TrackRequest) Abort

func (r *TrackRequest) Abort(errorCode uint16) error

Abort rejects the request with an application error code.

func (*TrackRequest) Accept

func (r *TrackRequest) Accept(info *TrackInfo) (*TrackProducer, error)

Accept accepts the request as a raw track. For media, use PublishAudioOnTrack or PublishVideoOnTrack.

func (*TrackRequest) Dynamic

func (r *TrackRequest) Dynamic() (*TrackDynamic, error)

Dynamic creates a fetch handler before accepting this requested track.

func (*TrackRequest) Name

func (r *TrackRequest) Name() (string, error)

Name is the requested track name.

type Transport

type Transport = ffi.MoqTransport

Transport is the network transport carrying an incoming session.

type Video

type Video = ffi.MoqVideo

Video describes one catalog rendition, including whether the publisher recommends temporarily avoiding it.

type VideoCodec

type VideoCodec = ffi.MoqVideoCodec

VideoCodec identifies a published video track's codec: H.264 or H.265.

type VideoConsumer

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

VideoConsumer is a stream of decoded video frames.

func (*VideoConsumer) Cancel

func (v *VideoConsumer) Cancel()

Cancel stops the stream.

func (*VideoConsumer) Frames

Frames ranges over decoded frames until the track ends or the loop breaks.

func (*VideoConsumer) Next

Next returns the next decoded frame, or (nil, nil) when the track ends.

type VideoDecodedFrame

type VideoDecodedFrame = ffi.MoqVideoDecodedFrame

VideoDecodedFrame is one decoded video frame: packed pixels, the layout they are in, their dimensions, and a timestamp in microseconds.

type VideoDecoderOutput

type VideoDecoderOutput = ffi.MoqVideoDecoderOutput

VideoDecoderOutput configures what DecodeVideo delivers: an optional pixel format and resize, plus a max age.

type VideoEncoderInput

type VideoEncoderInput = ffi.MoqVideoEncoderInput

VideoEncoderInput declares the pixel layout, resolution, and framerate of frames written to a video producer.

type VideoEncoderKind

type VideoEncoderKind = ffi.MoqVideoEncoderKind

VideoEncoderKind selects the encoder implementation. Build one with AutoEncoder, HardwareEncoder, SoftwareEncoder, or NamedEncoder.

func AutoEncoder

func AutoEncoder() VideoEncoderKind

AutoEncoder prefers a platform hardware encoder, falling back to software.

func HardwareEncoder

func HardwareEncoder() VideoEncoderKind

HardwareEncoder requires a hardware encoder, failing if none is available.

func NamedEncoder

func NamedEncoder(name string) VideoEncoderKind

NamedEncoder selects a specific backend these bindings compile: "videotoolbox" (macOS), "mediafoundation" (Windows), or "openh264" (software, everywhere). Naming one this build lacks fails with a no-encoder error.

func SoftwareEncoder

func SoftwareEncoder() VideoEncoderKind

SoftwareEncoder requires the software encoder (openh264, H.264 only).

type VideoEncoderKindAuto

type VideoEncoderKindAuto = ffi.MoqVideoEncoderKindAuto

VideoEncoderKindAuto is the automatic variant of VideoEncoderKind; build one with AutoEncoder.

type VideoEncoderKindHardware

type VideoEncoderKindHardware = ffi.MoqVideoEncoderKindHardware

VideoEncoderKindHardware is the hardware-only variant of VideoEncoderKind; build one with HardwareEncoder.

type VideoEncoderKindNamed

type VideoEncoderKindNamed = ffi.MoqVideoEncoderKindNamed

VideoEncoderKindNamed is the specific-backend variant of VideoEncoderKind; build one with NamedEncoder.

type VideoEncoderKindSoftware

type VideoEncoderKindSoftware = ffi.MoqVideoEncoderKindSoftware

VideoEncoderKindSoftware is the software-only variant of VideoEncoderKind; build one with SoftwareEncoder.

type VideoEncoderOutput

type VideoEncoderOutput = ffi.MoqVideoEncoderOutput

VideoEncoderOutput configures the video track name, codec, bitrate, keyframe interval, and backend preference.

type VideoFormat

type VideoFormat = ffi.MoqVideoFormat

VideoFormat is a single video codec an importer can parse.

type VideoFrame

type VideoFrame = ffi.MoqVideoFrame

VideoFrame is one raw video frame: pixels in the configured layout plus a presentation timestamp in microseconds.

type VideoHint

type VideoHint = ffi.MoqVideoHint

VideoHint supplies catalog fields a video stream can't reveal itself, such as bitrate, filling only the gaps.

type VideoOption

type VideoOption func(*ffi.MoqVideoInit)

VideoOption configures a video publish.

func WithVideoHint

func WithVideoHint(hint VideoHint) VideoOption

WithVideoHint seeds catalog fields that a video stream cannot reveal itself.

func WithVideoLabel

func WithVideoLabel(label string) VideoOption

WithVideoLabel sets the human-readable rendition name stored in the catalog.

func WithVideoTrack added in v0.7.3

func WithVideoTrack(track string) VideoOption

WithVideoTrack names the track instead of deriving a unique name from the format. A requested track already has a name, so the OnTrack variant refuses it.

type VideoPixelFormat

type VideoPixelFormat = ffi.MoqVideoPixelFormat

VideoPixelFormat is a CPU pixel layout (I420 or RGBA): written to a VideoProducer, or delivered by DecodeVideo.

type VideoProducer

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

VideoProducer pushes raw pictures and lets a native encoder compress them on the way out.

func (*VideoProducer) Cut

func (v *VideoProducer) Cut() error

Cut starts a new group at the next written frame.

Optional: the encoder keyframes every Gop frames on its own, and each of those cuts a group, so a subscriber can always join without this. Reach for it only to place the boundaries yourself, aligning groups with something the encoder can't see such as a scene change. An error means the selected encoder cannot force a keyframe; nothing is queued and groups keep their interval.

func (*VideoProducer) Demand

func (v *VideoProducer) Demand() (*TrackDemand, error)

Demand returns a watch-only handle to whether the video track has subscribers.

func (*VideoProducer) Finish

func (v *VideoProducer) Finish() error

Finish flushes any frames the codec is holding and finalizes the track.

func (*VideoProducer) Name

func (v *VideoProducer) Name() (string, error)

Name returns the video track's name.

func (*VideoProducer) Reservation

func (v *VideoProducer) Reservation() *Reservation

Reservation returns this encoder's bandwidth reservation, or nil if it was published without an allocator.

func (*VideoProducer) SetBitrate

func (v *VideoProducer) SetBitrate(bitrate uint64) error

SetBitrate retunes the live encoder, in bits per second. Cheap enough to drive from a congestion controller: no keyframe is forced. An error means this backend can't retune while running, which is not fatal; the encoder keeps its current rate.

func (*VideoProducer) Unused

func (v *VideoProducer) Unused(ctx context.Context) error

Unused blocks until the video track has no active subscribers. Prefer Demand.

func (*VideoProducer) Used

func (v *VideoProducer) Used(ctx context.Context) error

Used blocks until the video track has at least one active subscriber. Prefer Demand.

func (*VideoProducer) Write

func (v *VideoProducer) Write(frame VideoFrame) error

Write encodes and publishes one frame in the configured input format. A hardware encoder pipelines, so a call that puts nothing on the wire is normal rather than an error.

type VideoProperties

type VideoProperties = ffi.MoqVideoProperties

VideoProperties holds catalog properties shared by every video rendition; nil fields clear those properties.

Jump to

Keyboard shortcuts

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