mirror of
https://github.com/aler9/rtsp-simple-server
synced 2025-09-27 03:56:15 +08:00
118 lines
2.8 KiB
Go
118 lines
2.8 KiB
Go
// 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()
|
|
}
|
|
}
|