domain

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 22, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package domain defines core types shared across Open Streamer modules.

Index

Constants

View Source
const MaxStreamCodeLen = 128

MaxStreamCodeLen is the maximum length of a user-defined stream code.

View Source
const MaxVODNameLen = 64

MaxVODNameLen bounds the length of a VOD mount name used as a URL host component.

Variables

This section is empty.

Functions

func ValidateStreamCode

func ValidateStreamCode(s string) error

ValidateStreamCode reports whether s is a non-empty valid stream code.

func ValidateVODName

func ValidateVODName(s string) error

ValidateVODName reports whether s is a non-empty, URL-host-safe VOD mount name.

Types

type AVCodec

type AVCodec uint8

AVCodec identifies elementary stream codec for AVPacket payloads.

const (
	AVCodecUnknown AVCodec = iota
	AVCodecH264
	AVCodecH265
	AVCodecAAC
)

AVCodec values.

type AVPacket

type AVPacket struct {
	Codec         AVCodec
	Data          []byte
	PTSms         uint64
	DTSms         uint64
	KeyFrame      bool
	Discontinuity bool
}

AVPacket is one decoded video access unit (Annex B H.264/H.265) or one AAC frame (ADTS in Data). PTSms and DTSms are presentation / decode timestamps in milliseconds (MPEG-TS / gomedia convention).

func (*AVPacket) Clone

func (p *AVPacket) Clone() *AVPacket

Clone returns a deep copy suitable for buffer fan-out.

type AudioCodec

type AudioCodec string

AudioCodec identifies the audio compression format.

const (
	AudioCodecAAC  AudioCodec = "aac"  // default for HLS/DASH
	AudioCodecMP3  AudioCodec = "mp3"  // legacy compatibility
	AudioCodecOpus AudioCodec = "opus" // best for WebRTC / low-latency
	AudioCodecAC3  AudioCodec = "ac3"  // Dolby Digital — broadcast use
	AudioCodecCopy AudioCodec = "copy" // passthrough — no re-encode
)

AudioCodec values name supported output audio codecs.

type AudioConfig

type AudioConfig struct {
	Codec AudioCodec `json:"codec" yaml:"codec"`

	// Bitrate is the audio bitrate in kbps. Typical: 128 (stereo), 192 (high quality).
	Bitrate int `json:"bitrate" yaml:"bitrate"`

	// SampleRate is the output sample rate in Hz. Typical: 44100, 48000.
	SampleRate int `json:"sample_rate" yaml:"sample_rate"`

	// Channels: 1 = mono, 2 = stereo, 6 = 5.1 surround.
	Channels int `json:"channels" yaml:"channels"`

	// Language is the ISO 639-1 code embedded in HLS/DASH metadata, e.g. "en", "vi".
	Language string `json:"language" yaml:"language"`

	// Normalize applies EBU R128 loudness normalization (-23 LUFS).
	// Useful for broadcast compliance.
	Normalize bool `json:"normalize" yaml:"normalize"`
}

AudioConfig defines the audio encoding settings applied to all output profiles.

type AudioTranscodeConfig

type AudioTranscodeConfig struct {
	// Copy copies origin audio without re-encoding.
	Copy bool `json:"copy" yaml:"copy"`

	Codec AudioCodec `json:"codec" yaml:"codec"`

	// Bitrate is the audio bitrate in kbps.
	Bitrate int `json:"bitrate" yaml:"bitrate"`

	// SampleRate is output sample rate in Hz.
	SampleRate int `json:"sample_rate" yaml:"sample_rate"`

	// Channels: 1 = mono, 2 = stereo, 6 = 5.1.
	Channels int `json:"channels" yaml:"channels"`

	// Language is ISO 639-1 code, e.g. "en", "vi".
	Language string `json:"language" yaml:"language"`

	// Normalize applies EBU R128 loudness normalization.
	Normalize bool `json:"normalize" yaml:"normalize"`
}

AudioTranscodeConfig defines audio transcoding behavior.

type DVRGap

type DVRGap struct {
	From     time.Time     `json:"from" yaml:"from"`         // wall time gap started
	To       time.Time     `json:"to" yaml:"to"`             // wall time recording resumed
	Duration time.Duration `json:"duration" yaml:"duration"` // To - From
}

DVRGap represents a period of signal loss or server downtime.

type DVRIndex

type DVRIndex struct {
	StreamCode    StreamCode `json:"stream_code" yaml:"stream_code"`
	StartedAt     time.Time  `json:"started_at" yaml:"started_at"`
	LastSegmentAt time.Time  `json:"last_segment_at,omitempty" yaml:"last_segment_at,omitempty"`

	SegmentCount   int   `json:"segment_count" yaml:"segment_count"`
	TotalSizeBytes int64 `json:"total_size_bytes" yaml:"total_size_bytes"`

	// Gaps is the list of known signal-loss / server-restart interruptions.
	Gaps []DVRGap `json:"gaps,omitempty" yaml:"gaps,omitempty"`
}

DVRIndex is the on-disk metadata index for a stream's DVR recording. Written atomically to {SegmentDir}/index.json after every segment flush.

Deliberately lightweight — no per-segment details. Per-segment timeline (wall time, duration, discontinuity) lives in playlist.m3u8 via #EXT-X-PROGRAM-DATE-TIME and #EXTINF tags.

type DecoderConfig

type DecoderConfig struct {
	// Name is the FFmpeg decoder name.
	// "" = let FFmpeg choose automatically.
	// Examples: "h264_cuvid", "h264_qsv".
	Name string `json:"name,omitempty" yaml:"name,omitempty"`
}

DecoderConfig defines decoder behavior.

type Event

type Event struct {
	ID         string         `json:"id"` // UUID for idempotent delivery
	Type       EventType      `json:"type"`
	StreamCode StreamCode     `json:"stream_code"`
	OccurredAt time.Time      `json:"occurred_at"`
	Payload    map[string]any `json:"payload,omitempty"` // event-specific fields
}

Event is an immutable fact describing a domain state change.

type EventType

type EventType string

EventType identifies the kind of domain event that occurred.

const (
	// Stream lifecycle — published by coordinator and API handler.
	EventStreamCreated EventType = "stream.created"
	EventStreamStarted EventType = "stream.started"
	EventStreamStopped EventType = "stream.stopped"
	EventStreamDeleted EventType = "stream.deleted"

	// Input health — published by ingestor worker and stream manager.
	EventInputConnected    EventType = "input.connected"    // source connected successfully
	EventInputReconnecting EventType = "input.reconnecting" // transient error, retrying
	EventInputDegraded     EventType = "input.degraded"     // error detected by manager
	EventInputFailed       EventType = "input.failed"       // worker exited / non-retriable
	EventInputFailover     EventType = "input.failover"     // switched to lower-priority input

	// DVR recordings — published by dvr.Service.
	EventRecordingStarted EventType = "recording.started"
	EventRecordingStopped EventType = "recording.stopped"
	EventRecordingFailed  EventType = "recording.failed"
	EventSegmentWritten   EventType = "segment.written"

	// Transcoder — published by transcoder.Service.
	EventTranscoderStarted EventType = "transcoder.started"
	EventTranscoderStopped EventType = "transcoder.stopped"
	EventTranscoderError   EventType = "transcoder.error"
)

EventType values are emitted on the event bus for stream lifecycle, inputs, recordings, and segments.

type GlobalConfig

type GlobalConfig struct {
	Server     *config.ServerConfig     `json:"server,omitempty" yaml:"server,omitempty"`
	Listeners  *config.ListenersConfig  `json:"listeners,omitempty" yaml:"listeners,omitempty"`
	Ingestor   *config.IngestorConfig   `json:"ingestor,omitempty" yaml:"ingestor,omitempty"`
	Buffer     *config.BufferConfig     `json:"buffer,omitempty" yaml:"buffer,omitempty"`
	Transcoder *config.TranscoderConfig `json:"transcoder,omitempty" yaml:"transcoder,omitempty"`
	Publisher  *config.PublisherConfig  `json:"publisher,omitempty" yaml:"publisher,omitempty"`
	Manager    *config.ManagerConfig    `json:"manager,omitempty" yaml:"manager,omitempty"`
	Hooks      *config.HooksConfig      `json:"hooks,omitempty" yaml:"hooks,omitempty"`
	Log        *config.LogConfig        `json:"log,omitempty" yaml:"log,omitempty"`
}

GlobalConfig holds all runtime configuration that is persisted in the store (as opposed to config.StorageConfig which is bootstrap-only from config.yaml/env).

Pointer fields: nil means the section is not configured and the corresponding service should not start. This allows users to enable/disable entire subsystems by adding or removing config sections via the API.

type HWAccel

type HWAccel string

HWAccel selects the hardware acceleration backend for encoding/decoding.

const (
	HWAccelNone         HWAccel = "none"         // CPU only (libx264, libx265)
	HWAccelNVENC        HWAccel = "nvenc"        // NVIDIA GPU (h264_nvenc, hevc_nvenc)
	HWAccelVAAPI        HWAccel = "vaapi"        // Intel/AMD GPU via VA-API (Linux)
	HWAccelVideoToolbox HWAccel = "videotoolbox" // Apple GPU (macOS)
	HWAccelQSV          HWAccel = "qsv"          // Intel Quick Sync Video
)

HWAccel values map to FFmpeg hardware device options.

type Hook

type Hook struct {
	ID     HookID   `json:"id" yaml:"id"`
	Name   string   `json:"name" yaml:"name"`
	Type   HookType `json:"type" yaml:"type"`
	Target string   `json:"target" yaml:"target"` // HTTP URL or Kafka topic
	Secret string   `json:"secret" yaml:"secret"` // HMAC-SHA256 signing secret (HTTP only)

	// EventTypes filters which events trigger delivery. Empty = all events.
	EventTypes []EventType `json:"event_types,omitempty" yaml:"event_types,omitempty"`

	// StreamCodes filters delivery by stream code.
	// Only and Except are mutually exclusive; Only takes precedence when both are set.
	// Omitting the field (nil) means all streams are included.
	StreamCodes *StreamCodeFilter `json:"stream_codes,omitempty" yaml:"stream_codes,omitempty"`

	// Metadata holds user-defined key-value pairs merged into every event payload
	// delivered by this hook. Useful for tagging events with custom context
	// (e.g. environment, tenant ID, region) without modifying the server config.
	Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty"`

	Enabled bool `json:"enabled" yaml:"enabled"`

	// MaxRetries is the number of delivery attempts before giving up.
	// 0 means use the server default (3).
	MaxRetries int `json:"max_retries" yaml:"max_retries"`

	// TimeoutSec is the per-attempt delivery timeout in seconds.
	// 0 means use the server default (10s).
	TimeoutSec int `json:"timeout_sec" yaml:"timeout_sec"`
}

Hook is a registered external integration that receives domain events.

type HookID

type HookID string

HookID is the unique identifier for a registered hook.

type HookType

type HookType string

HookType is the delivery mechanism for a hook.

const (
	HookTypeHTTP  HookType = "http"
	HookTypeKafka HookType = "kafka"
)

HookType values name supported hook transports.

type Input

type Input struct {
	// URL is the source endpoint. See the package doc for supported formats.
	URL string `json:"url" yaml:"url"`

	// Priority determines failover order. Lower value = higher priority.
	// The Stream Manager always prefers the lowest-priority alive input.
	Priority int `json:"priority" yaml:"priority"`

	// Headers are arbitrary HTTP headers sent with every request for HTTP/HLS inputs.
	// Common uses:
	//   "Authorization": "Bearer <token>"
	//   "Authorization": "Basic <base64(user:pass)>"
	//   "X-Custom-Token": "secret"
	Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"`

	// Params are extra URL query parameters merged into the source URL before
	// connecting. Used for protocols that carry credentials or options in the
	// query string (SRT ?passphrase=, S3 ?access_key= / ?secret_key=, etc.).
	//   "passphrase": "my-srt-passphrase"
	//   "access_key": "AKID..."   (S3)
	//   "secret_key": "wJal..."   (S3)
	Params map[string]string `json:"params,omitempty" yaml:"params,omitempty"`

	// Net controls reconnect and timeout behaviour.
	Net InputNetConfig `json:"net,omitempty" yaml:"net,omitempty"`

	// Alive is a runtime-only field updated by the Stream Manager health checker.
	// Not persisted to storage.
	Alive bool `json:"-" yaml:"-"`
}

Input is a single ingest source for a stream. Multiple inputs can be configured; the Stream Manager selects the active one based on Priority and runtime health (Alive flag).

The only required field is URL. The ingestor derives the ingest protocol and connection mode (pull vs push-listen) automatically from the URL scheme and host — no additional protocol configuration is needed.

Supported URL formats:

Pull (server connects to remote source):
  rtmp://server.com/live/stream_key       RTMP pull from remote
  rtsp://camera.local:554/stream          RTSP pull (IP camera)
  http://cdn.example.com/live.ts          HTTP MPEG-TS stream
  https://cdn.example.com/playlist.m3u8   HLS pull (grafov m3u8 parser)
  udp://239.1.1.1:5000                    UDP multicast MPEG-TS
  srt://relay.example.com:9999            SRT pull (caller mode)
  file:///recordings/source.ts            local file (loops if ?loop=true)

Push (external encoder connects to our server):
  rtmp://0.0.0.0:1935/live/stream_key     RTMP push — our RTMP server listens
  srt://0.0.0.0:9999?streamid=stream_key  SRT push  — our SRT server listens

Push mode is detected automatically when the URL host is a wildcard address (0.0.0.0, ::, empty) and the scheme is rtmp or srt.

type InputNetConfig

type InputNetConfig struct {
	// ConnectTimeoutSec caps each HTTP round-trip (headers + full body) for pull
	// readers that use net/http (e.g. HLS playlist and segment GETs). Zero uses
	// the reader's default (30s for HLS).
	ConnectTimeoutSec int `json:"connect_timeout_sec,omitempty" yaml:"connect_timeout_sec,omitempty"`

	// ReadTimeoutSec is the max silence duration before declaring the input dead.
	ReadTimeoutSec int `json:"read_timeout_sec,omitempty" yaml:"read_timeout_sec,omitempty"`

	// Reconnect enables automatic reconnection when the input drops.
	Reconnect bool `json:"reconnect,omitempty" yaml:"reconnect,omitempty"`

	// ReconnectDelaySec is the initial delay before the first reconnect attempt.
	ReconnectDelaySec int `json:"reconnect_delay_sec,omitempty" yaml:"reconnect_delay_sec,omitempty"`

	// ReconnectMaxDelaySec caps the exponential backoff delay.
	ReconnectMaxDelaySec int `json:"reconnect_max_delay_sec,omitempty" yaml:"reconnect_max_delay_sec,omitempty"`

	// MaxReconnects is the total number of reconnect attempts (0 = unlimited).
	MaxReconnects int `json:"max_reconnects,omitempty" yaml:"max_reconnects,omitempty"`
}

InputNetConfig controls reconnect and timeout behaviour for an input.

type OutputProtocols

type OutputProtocols struct {
	// HLS enables Apple HTTP Live Streaming (m3u8 + segments over HTTP).
	// Compatible with browsers, iOS, Android, Smart TVs.
	HLS bool `json:"hls" yaml:"hls"`

	// DASH enables MPEG-DASH packaging over HTTP.
	// Required for Widevine/PlayReady DRM.
	DASH bool `json:"dash" yaml:"dash"`

	// RTSP opens an RTSP listener for pull clients (VLC, broadcast tools).
	RTSP bool `json:"rtsp" yaml:"rtsp"`

	// RTMP opens an RTMP publish endpoint for legacy players/CDNs.
	RTMP bool `json:"rtmp" yaml:"rtmp"`

	// SRT opens an SRT listener port for contribution-quality pull.
	SRT bool `json:"srt" yaml:"srt"`
}

OutputProtocols defines which delivery protocols are opened for a stream. Each enabled protocol starts a corresponding listener or packager. Protocol-level settings (ports, segment duration, CDN URL, etc.) are configured globally in the server config.

type PushDestination

type PushDestination struct {
	// URL is the destination ingest endpoint.
	// Supported schemes:
	//   rtmp://  — plain TCP, default port 1935 (e.g. rtmp://a.rtmp.youtube.com/live2/{key})
	//   rtmps:// — TLS-wrapped RTMP, default port 443 (e.g. rtmps://live-api-s.facebook.com:443/rtmp/{key})
	URL string `json:"url" yaml:"url"`

	// Enabled controls whether this destination is active.
	Enabled bool `json:"enabled" yaml:"enabled"`

	// TimeoutSec is the connection/write timeout in seconds.
	TimeoutSec int `json:"timeout_sec" yaml:"timeout_sec"`

	// RetryTimeoutSec is the delay between retry attempts in seconds.
	RetryTimeoutSec int `json:"retry_timeout_sec" yaml:"retry_timeout_sec"`

	// Limit is the maximum number of retry attempts. 0 = unlimited.
	Limit int `json:"limit" yaml:"limit"`

	// Comment is a human-readable note for this destination.
	Comment string `json:"comment" yaml:"comment"`

	// Status is a runtime-only field updated by the publisher.
	// Not persisted to storage.
	Status PushStatus `json:"status,omitempty" yaml:"-"`
}

PushDestination is an external endpoint the server actively pushes the stream to.

type PushStatus

type PushStatus string

PushStatus is the runtime state of a push destination.

const (
	PushStatusIdle       PushStatus = "idle"
	PushStatusConnecting PushStatus = "connecting"
	PushStatusActive     PushStatus = "active"
	PushStatusRetrying   PushStatus = "retrying"
	PushStatusFailed     PushStatus = "failed"
	PushStatusDisabled   PushStatus = "disabled"
)

PushStatus values describe outbound publisher connectivity.

type Recording

type Recording struct {
	ID         RecordingID     `json:"id" yaml:"id"`
	StreamCode StreamCode      `json:"stream_code" yaml:"stream_code"`
	StartedAt  time.Time       `json:"started_at" yaml:"started_at"`
	StoppedAt  *time.Time      `json:"stopped_at,omitempty" yaml:"stopped_at,omitempty"`
	Status     RecordingStatus `json:"status" yaml:"status"`

	// SegmentDir is the absolute path to the directory holding TS files,
	// playlist.m3u8, and index.json.
	SegmentDir string `json:"segment_dir" yaml:"segment_dir"`
}

Recording represents the lifecycle metadata for a DVR recording session. ID equals StreamCode — one persistent recording per stream. Segment data lives in DVRIndex (index.json on disk), not here.

type RecordingID

type RecordingID string

RecordingID is the unique identifier for a DVR recording. Always equals the stream code — one recording per stream.

type RecordingStatus

type RecordingStatus string

RecordingStatus represents the lifecycle state of a recording.

const (
	RecordingStatusRecording RecordingStatus = "recording"
	RecordingStatusStopped   RecordingStatus = "stopped"
	RecordingStatusFailed    RecordingStatus = "failed"
)

RecordingStatus values.

type Stream

type Stream struct {
	// Code is the unique key chosen by the user ([a-zA-Z0-9_]).
	Code StreamCode `json:"code" yaml:"code"`

	Name        string   `json:"name" yaml:"name"`
	Description string   `json:"description" yaml:"description"`
	Tags        []string `json:"tags" yaml:"tags"`

	// StreamKey is used to authenticate RTMP/SRT push ingest.
	StreamKey string `json:"stream_key" yaml:"stream_key"`

	// Status is the runtime lifecycle state.
	// It is never persisted — always computed from the coordinator's in-memory
	// state and overlaid by the API layer before returning responses to clients.
	Status StreamStatus `json:"-" yaml:"-"`

	// Disabled when true excludes the stream from server bootstrap and rejects pipeline Start.
	Disabled bool `json:"disabled" yaml:"disabled"`

	// Inputs are the available ingest sources ordered by Priority.
	// The Stream Manager monitors health and switches between them on failure.
	Inputs []Input `json:"inputs" yaml:"inputs"`

	// Transcoder controls encoding/decoding settings.
	// nil means no transcoding for this stream.
	Transcoder *TranscoderConfig `json:"transcoder,omitempty" yaml:"transcoder,omitempty"`

	// Protocols defines which delivery protocols are opened for this stream.
	// The server opens a listener/packager for each enabled protocol.
	// Protocol-level config (ports, segment duration, CDN URL) lives in server config.
	Protocols OutputProtocols `json:"protocols" yaml:"protocols"`

	// Push is the list of external destinations the server actively pushes to.
	// Each entry defines one push target (YouTube, Facebook, Twitch, CDN relay, etc.).
	Push []PushDestination `json:"push" yaml:"push"`

	// DVR overrides the global DVR settings for this specific stream.
	// If nil, the global config is used (when DVR is enabled globally).
	DVR *StreamDVRConfig `json:"dvr,omitempty" yaml:"dvr,omitempty"`

	// Watermark is an optional text or image overlay applied before encoding.
	Watermark *WatermarkConfig `json:"watermark,omitempty" yaml:"watermark,omitempty"`

	// Thumbnail controls periodic screenshot generation for preview images.
	Thumbnail *ThumbnailConfig `json:"thumbnail,omitempty" yaml:"thumbnail,omitempty"`
}

Stream is the central domain entity. It describes everything needed to ingest, process, and deliver a live stream.

func (*Stream) ValidateInputPriorities

func (s *Stream) ValidateInputPriorities() error

ValidateInputPriorities enforces that input priorities are contiguous and sorted. For N inputs, expected priorities are exactly 0..N-1 in ascending order.

func (*Stream) ValidateUniqueInputs

func (s *Stream) ValidateUniqueInputs() error

ValidateUniqueInputs enforces that inputs in one stream are not duplicated. Two inputs are considered duplicates if their URL (trimmed) is identical.

type StreamCode

type StreamCode string

StreamCode is the user-assigned primary key for a stream. Allowed characters: a-z, A-Z, 0-9, underscore.

type StreamCodeFilter

type StreamCodeFilter struct {
	// Only delivers events only for streams in this list.
	Only []StreamCode `json:"only,omitempty" yaml:"only,omitempty"`
	// Except delivers events for all streams except those in this list.
	Except []StreamCode `json:"except,omitempty" yaml:"except,omitempty"`
}

StreamCodeFilter defines include/exclude rules for stream code matching. Only and Except are mutually exclusive; Only takes precedence when both are set.

func (*StreamCodeFilter) Matches

func (f *StreamCodeFilter) Matches(code StreamCode) bool

Matches reports whether the given stream code passes the filter.

type StreamDVRConfig

type StreamDVRConfig struct {
	Enabled bool `json:"enabled" yaml:"enabled"`

	// RetentionSec is the retention window in seconds.
	// 0 = keep forever.
	RetentionSec int `json:"retention_sec" yaml:"retention_sec"`

	// SegmentDuration overrides the global segment length in seconds.
	// 0 = use default (4s).
	SegmentDuration int `json:"segment_duration" yaml:"segment_duration"`

	// StoragePath overrides the default DVR root directory for this stream.
	// "" = use "./dvr/{streamCode}".
	StoragePath string `json:"storage_path" yaml:"storage_path"`

	// MaxSizeGB caps total disk usage. Oldest segments pruned when exceeded.
	// 0 = no limit.
	MaxSizeGB float64 `json:"max_size_gb" yaml:"max_size_gb"`
}

StreamDVRConfig overrides the global DVR settings for a specific stream.

type StreamStatus

type StreamStatus string

StreamStatus represents the lifecycle state of a stream.

const (
	StatusIdle     StreamStatus = "idle"
	StatusActive   StreamStatus = "active"
	StatusDegraded StreamStatus = "degraded"
	StatusStopped  StreamStatus = "stopped"
)

StreamStatus values are used by the stream manager and API.

type ThumbnailConfig

type ThumbnailConfig struct {
	Enabled bool `json:"enabled" yaml:"enabled"`

	// IntervalSec generates one thumbnail every N seconds.
	IntervalSec int `json:"interval_sec" yaml:"interval_sec"`

	// Width and Height of the output thumbnail in pixels.
	// 0 = match source resolution.
	Width  int `json:"width" yaml:"width"`
	Height int `json:"height" yaml:"height"`

	// Quality is the JPEG quality (1–31, lower = better). Default: 5.
	Quality int `json:"quality" yaml:"quality"`

	// OutputDir is relative to the publisher HLS directory.
	// E.g. "thumbnails" → written to {hls_dir}/{stream_code}/thumbnails/thumb.jpg
	OutputDir string `json:"output_dir" yaml:"output_dir"`
}

ThumbnailConfig controls periodic screenshot generation for stream preview. Thumbnails are written as JPEG files alongside HLS segments.

type TranscoderConfig

type TranscoderConfig struct {
	Video   VideoTranscodeConfig   `json:"video" yaml:"video"`
	Audio   AudioTranscodeConfig   `json:"audio" yaml:"audio"`
	Decoder DecoderConfig          `json:"decoder" yaml:"decoder"`
	Global  TranscoderGlobalConfig `json:"global" yaml:"global"`

	// ExtraArgs are raw FFmpeg arguments appended after the generated command.
	// Use with caution — may conflict with generated arguments.
	ExtraArgs []string `json:"extra_args,omitempty" yaml:"extra_args,omitempty"`
}

TranscoderConfig is the complete transcoding configuration for a stream.

type TranscoderGlobalConfig

type TranscoderGlobalConfig struct {
	// HW selects the acceleration backend.
	HW HWAccel `json:"hw" yaml:"hw"`

	// FPS sets output framerate. 0 = source/default.
	FPS int `json:"fps" yaml:"fps"`

	// GOP sets keyframe interval in frames. 0 = encoder default.
	GOP int `json:"gop" yaml:"gop"`

	// DeviceID selects hardware device index.
	DeviceID int `json:"deviceid" yaml:"deviceid"`
}

TranscoderGlobalConfig holds global transcoder parameters.

type VODMount

type VODMount struct {
	Name    VODName `json:"name" yaml:"name"`
	Storage string  `json:"storage" yaml:"storage"`
	Comment string  `json:"comment,omitempty" yaml:"comment,omitempty"`
}

VODMount registers a host filesystem directory as a named media library. The system does not maintain a file index; file lookups and listings are resolved live against Storage.

Ingest URLs take the form file://<Name>/<relative/path/inside/storage>. Any path that would escape Storage (via "..", absolute components, or symlink traversal) must be rejected by the resolver.

func (*VODMount) ValidateStorage

func (m *VODMount) ValidateStorage() error

ValidateStorage checks that Storage is a syntactically valid absolute path. The directory itself is not required to exist at validation time — operators may create it later — but the path must be absolute to avoid surprises from the server's working directory.

type VODName

type VODName string

VODName identifies a VOD mount. It appears as the URL host in ingest sources (e.g. file://<name>/path/to/file.mp4), so it must be URL-host-safe.

type VideoCodec

type VideoCodec string

VideoCodec identifies the video compression format.

const (
	VideoCodecH264 VideoCodec = "h264" // AVC — widest device support
	VideoCodecH265 VideoCodec = "h265" // HEVC — ~50% smaller than H.264
	VideoCodecAV1  VideoCodec = "av1"  // royalty-free, best compression (high CPU)
	VideoCodecVP9  VideoCodec = "vp9"  // Google codec, WebRTC-friendly
	VideoCodecCopy VideoCodec = "copy" // passthrough — no re-encode
)

VideoCodec values name supported output video codecs.

type VideoProfile

type VideoProfile struct {
	// Width and Height define the output resolution.
	// Set to 0 to keep the source dimensions (Width=0 & Height=0 = no scaling).
	Width  int `json:"width" yaml:"width"`
	Height int `json:"height" yaml:"height"`

	// Bitrate is the target video bitrate in kbps. 0 = encoder auto.
	Bitrate int `json:"bitrate" yaml:"bitrate"`

	// MaxBitrate caps the peak bitrate in kbps (CBR/VBR ceiling). 0 = no cap.
	MaxBitrate int `json:"max_bitrate" yaml:"max_bitrate"`

	// Framerate is the output frame rate (fps). 0 = match source.
	Framerate float64 `json:"framerate" yaml:"framerate"`

	// KeyframeInterval is the GOP size in seconds.
	// Must match or be a multiple of the HLS/DASH segment duration.
	KeyframeInterval int `json:"keyframe_interval" yaml:"keyframe_interval"`

	Codec VideoCodec `json:"codec" yaml:"codec"`

	// Preset controls the encoder speed/quality tradeoff.
	// libx264: "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "medium" | "slow" | "veryslow"
	// NVENC:   "p1" (fastest) .. "p7" (highest quality)
	Preset string `json:"preset" yaml:"preset"`

	// Profile controls the H.264/H.265 encoding profile.
	// "baseline" | "main" | "high" (H.264); "main" | "main10" (H.265)
	Profile string `json:"profile" yaml:"profile"`

	// Level controls the H.264/H.265 encoding level.
	// Common: "3.1", "4.0", "4.1", "4.2", "5.0", "5.1"
	Level string `json:"level" yaml:"level"`
}

VideoProfile is a single rendition in the ABR (Adaptive Bitrate) ladder. The Transcoder produces one FFmpeg output per profile. Stable rendition ids are derived from slice order: track_1, track_2, track_3, … (1-based).

type VideoTranscodeConfig

type VideoTranscodeConfig struct {
	// Copy copies origin video without re-encoding.
	Copy bool `json:"copy" yaml:"copy"`

	// Profiles defines ABR renditions when re-encoding.
	Profiles []VideoProfile `json:"profiles,omitempty" yaml:"profiles,omitempty"`
}

VideoTranscodeConfig defines video transcoding behavior.

type WatermarkConfig

type WatermarkConfig struct {
	Enabled bool          `json:"enabled" yaml:"enabled"`
	Type    WatermarkType `json:"type" yaml:"type"`

	// Text is the string to render. Supports strftime directives for live timestamps.
	// E.g. "LIVE %{localtime:%H:%M:%S}"
	Text string `json:"text" yaml:"text"`

	// FontFile is the path to a .ttf/.otf font file.
	// "" = FFmpeg default font.
	FontFile string `json:"font_file" yaml:"font_file"`

	// FontSize in pixels. Default: 24.
	FontSize int `json:"font_size" yaml:"font_size"`

	// FontColor in FFmpeg color syntax. E.g. "white", "#FFFFFF", "white@0.8".
	FontColor string `json:"font_color" yaml:"font_color"`

	// ImagePath is the path to the watermark image (PNG with alpha recommended).
	ImagePath string `json:"image_path" yaml:"image_path"`

	// Opacity controls transparency: 0.0 = fully transparent, 1.0 = fully opaque.
	Opacity float64 `json:"opacity" yaml:"opacity"`

	// Position is the corner/center anchor for the watermark.
	Position WatermarkPosition `json:"position" yaml:"position"`

	// OffsetX and OffsetY are pixel offsets from the chosen position edge.
	OffsetX int `json:"offset_x" yaml:"offset_x"`
	OffsetY int `json:"offset_y" yaml:"offset_y"`
}

WatermarkConfig defines an overlay applied to the video before encoding. Applied via FFmpeg drawtext (text) or overlay (image) filter.

type WatermarkPosition

type WatermarkPosition string

WatermarkPosition controls where the overlay is placed in the frame.

const (
	WatermarkTopLeft     WatermarkPosition = "top_left"
	WatermarkTopRight    WatermarkPosition = "top_right"
	WatermarkBottomLeft  WatermarkPosition = "bottom_left"
	WatermarkBottomRight WatermarkPosition = "bottom_right"
	WatermarkCenter      WatermarkPosition = "center"
)

WatermarkPosition values name corners and center for overlay placement.

type WatermarkType

type WatermarkType string

WatermarkType determines whether the overlay is text or an image.

const (
	WatermarkTypeText  WatermarkType = "text"
	WatermarkTypeImage WatermarkType = "image"
)

WatermarkType values select overlay content kind.

Jump to

Keyboard shortcuts

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