mediamtx/internal/recorder/recorder_instance.go
Alessandro Ros b77df43536
fix crash when recording a stream with unsupported tracks (#3978) (#3996)
* normalize variable names

* fix file name

* fix crash when recording a stream with unsupported tracks (#3978)
2024-11-30 11:23:41 +01:00

93 lines
1.6 KiB
Go

package recorder
import (
"strings"
"time"
"github.com/bluenviron/mediacommon/pkg/formats/fmp4"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/logger"
"github.com/bluenviron/mediamtx/internal/recordstore"
)
type sample struct {
*fmp4.PartSample
dts int64
ntp time.Time
}
type recorderInstance struct {
rec *Recorder
pathFormat string
format format
skip bool
terminate chan struct{}
done chan struct{}
}
// Log implements logger.Writer.
func (ri *recorderInstance) Log(level logger.Level, format string, args ...interface{}) {
ri.rec.Log(level, format, args...)
}
func (ri *recorderInstance) initialize() {
ri.pathFormat = ri.rec.PathFormat
ri.pathFormat = recordstore.PathAddExtension(
strings.ReplaceAll(ri.pathFormat, "%path", ri.rec.PathName),
ri.rec.Format,
)
ri.terminate = make(chan struct{})
ri.done = make(chan struct{})
switch ri.rec.Format {
case conf.RecordFormatMPEGTS:
ri.format = &formatMPEGTS{
ri: ri,
}
ok := ri.format.initialize()
ri.skip = !ok
default:
ri.format = &formatFMP4{
ri: ri,
}
ok := ri.format.initialize()
ri.skip = !ok
}
if !ri.skip {
ri.rec.Stream.StartReader(ri)
}
go ri.run()
}
func (ri *recorderInstance) close() {
close(ri.terminate)
<-ri.done
}
func (ri *recorderInstance) run() {
defer close(ri.done)
if !ri.skip {
select {
case err := <-ri.rec.Stream.ReaderError(ri):
ri.Log(logger.Error, err.Error())
case <-ri.terminate:
}
ri.rec.Stream.RemoveReader(ri)
} else {
<-ri.terminate
}
ri.format.close()
}