101 lines
1.6 KiB
Go
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()
|
|
}
|