Files
go2rtc/cmd/streams/producer.go
T
2022-08-22 15:40:28 +03:00

101 lines
1.6 KiB
Go

package streams
import (
"github.com/AlexxIT/go2rtc/pkg/streamer"
"sync"
)
type state byte
const (
stateNone state = iota
stateMedias
stateTracks
stateStart
)
type Producer struct {
streamer.Element
url string
element streamer.Producer
tracks []*streamer.Track
state state
mx sync.Mutex
}
func (p *Producer) GetMedias() []*streamer.Media {
p.mx.Lock()
defer p.mx.Unlock()
if p.state == stateNone {
log.Debug().Str("url", p.url).Msg("[streams] probe producer")
var err error
p.element, err = GetProducer(p.url)
if err != nil || p.element == nil {
log.Error().Err(err).Str("url", p.url).Msg("[streams] probe producer")
return nil
}
p.state = stateMedias
}
return p.element.GetMedias()
}
func (p *Producer) GetTrack(media *streamer.Media, codec *streamer.Codec) *streamer.Track {
p.mx.Lock()
defer p.mx.Unlock()
if p.state == stateMedias {
p.state = stateTracks
}
track := p.element.GetTrack(media, codec)
for _, t := range p.tracks {
if track == t {
return track
}
}
p.tracks = append(p.tracks, track)
return track
}
// internals
func (p *Producer) start() {
p.mx.Lock()
defer p.mx.Unlock()
if p.state != stateTracks {
return
}
log.Debug().Str("url", p.url).Msg("[streams] start producer")
p.state = stateStart
go p.element.Start()
}
func (p *Producer) stop() {
p.mx.Lock()
log.Debug().Str("url", p.url).Msg("[streams] stop producer")
if p.element != nil {
_ = p.element.Stop()
p.element = nil
} else {
log.Warn().Str("url", p.url).Msg("[streams] stop empty producer")
}
p.tracks = nil
p.state = stateNone
p.mx.Unlock()
}