// Package recorder contains the recorder. package recorder import ( "time" "github.com/bluenviron/mediamtx/internal/conf" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/stream" ) // OnSegmentCreateFunc is the prototype of the function passed as OnSegmentCreate type OnSegmentCreateFunc = func(path string) // OnSegmentCompleteFunc is the prototype of the function passed as OnSegmentComplete type OnSegmentCompleteFunc = func(path string, duration time.Duration) // Recorder writes recordings to disk. type Recorder struct { PathFormat string Format conf.RecordFormat PartDuration time.Duration MaxPartSize conf.StringSize SegmentDuration time.Duration PathName string Stream *stream.Stream OnSegmentCreate OnSegmentCreateFunc OnSegmentComplete OnSegmentCompleteFunc Parent logger.Writer restartPause time.Duration currentInstance *recorderInstance terminate chan struct{} done chan struct{} } // Initialize initializes Recorder. func (r *Recorder) Initialize() { if r.OnSegmentCreate == nil { r.OnSegmentCreate = func(string) { } } if r.OnSegmentComplete == nil { r.OnSegmentComplete = func(string, time.Duration) { } } if r.restartPause == 0 { r.restartPause = 2 * time.Second } r.terminate = make(chan struct{}) r.done = make(chan struct{}) r.currentInstance = &recorderInstance{ pathFormat: r.PathFormat, format: r.Format, partDuration: r.PartDuration, maxPartSize: r.MaxPartSize, segmentDuration: r.SegmentDuration, pathName: r.PathName, stream: r.Stream, onSegmentCreate: r.OnSegmentCreate, onSegmentComplete: r.OnSegmentComplete, parent: r, } r.currentInstance.initialize() go r.run() } // Log implements logger.Writer. func (r *Recorder) Log(level logger.Level, format string, args ...interface{}) { r.Parent.Log(level, "[recorder] "+format, args...) } // Close closes the agent. func (r *Recorder) Close() { r.Log(logger.Info, "recording stopped") close(r.terminate) <-r.done } func (r *Recorder) run() { defer close(r.done) for { select { case <-r.currentInstance.done: r.currentInstance.close() case <-r.terminate: r.currentInstance.close() return } select { case <-time.After(r.restartPause): case <-r.terminate: return } r.currentInstance = &recorderInstance{ pathFormat: r.PathFormat, format: r.Format, partDuration: r.PartDuration, maxPartSize: r.MaxPartSize, segmentDuration: r.SegmentDuration, pathName: r.PathName, stream: r.Stream, onSegmentCreate: r.OnSegmentCreate, onSegmentComplete: r.OnSegmentComplete, parent: r, } r.currentInstance.initialize() } }