package aoiprxkit import ( "context" "fmt" "io" ) type SRTConfig struct { URL string Mode string SampleRateHz int Channels int SourceLabel string } func DefaultSRTConfig() SRTConfig { return SRTConfig{ SampleRateHz: 48000, Channels: 2, Mode: "listener", } } func (c SRTConfig) Validate() error { if c.URL == "" { return fmt.Errorf("SRT URL must not be empty") } if c.SampleRateHz <= 0 { return fmt.Errorf("SampleRateHz must be > 0") } if c.Channels < 1 || c.Channels > 2 { return fmt.Errorf("Channels must be 1 or 2") } return nil } type SRTConnOpener func(ctx context.Context, cfg SRTConfig) (io.ReadCloser, error) type SRTReceiver struct { cfg SRTConfig streamRx *StreamReceiver } func NewSRTReceiver(cfg SRTConfig, onFrame FrameHandler) (*SRTReceiver, error) { return NewSRTReceiverWithOpener(cfg, defaultSRTConnOpener, onFrame) } func NewSRTReceiverWithOpener(cfg SRTConfig, opener SRTConnOpener, onFrame FrameHandler) (*SRTReceiver, error) { if err := cfg.Validate(); err != nil { return nil, err } if opener == nil { return nil, fmt.Errorf("SRT opener must not be nil") } src := cfg.SourceLabel if src == "" { src = cfg.URL } streamRx, err := NewStreamReceiver(StreamReceiverConfig{SourceLabel: src}, func(ctx context.Context) (io.ReadCloser, error) { return opener(ctx, cfg) }, onFrame) if err != nil { return nil, err } return &SRTReceiver{cfg: cfg, streamRx: streamRx}, nil } func (r *SRTReceiver) Start(ctx context.Context) error { return r.streamRx.Start(ctx) } func (r *SRTReceiver) Stop() error { return r.streamRx.Stop() }