2023-09-16 15:27:07 +00:00
|
|
|
package record
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
2023-10-14 20:52:10 +00:00
|
|
|
"github.com/bluenviron/mediamtx/internal/conf"
|
2023-09-16 15:27:07 +00:00
|
|
|
"github.com/bluenviron/mediamtx/internal/logger"
|
|
|
|
"github.com/bluenviron/mediamtx/internal/stream"
|
|
|
|
)
|
|
|
|
|
2023-12-02 14:15:17 +00:00
|
|
|
// Agent writes recordings to disk.
|
2023-09-16 15:27:07 +00:00
|
|
|
type Agent struct {
|
2023-10-26 19:40:44 +00:00
|
|
|
WriteQueueSize int
|
2023-12-02 14:35:21 +00:00
|
|
|
PathFormat string
|
2023-10-26 19:40:44 +00:00
|
|
|
Format conf.RecordFormat
|
|
|
|
PartDuration time.Duration
|
|
|
|
SegmentDuration time.Duration
|
|
|
|
PathName string
|
|
|
|
Stream *stream.Stream
|
|
|
|
OnSegmentCreate OnSegmentFunc
|
|
|
|
OnSegmentComplete OnSegmentFunc
|
|
|
|
Parent logger.Writer
|
|
|
|
|
|
|
|
restartPause time.Duration
|
|
|
|
|
|
|
|
currentInstance *agentInstance
|
|
|
|
|
|
|
|
terminate chan struct{}
|
|
|
|
done chan struct{}
|
2023-09-16 15:27:07 +00:00
|
|
|
}
|
|
|
|
|
2023-10-26 19:40:44 +00:00
|
|
|
// Initialize initializes Agent.
|
|
|
|
func (w *Agent) Initialize() {
|
2023-11-23 12:36:07 +00:00
|
|
|
if w.OnSegmentCreate == nil {
|
|
|
|
w.OnSegmentCreate = func(string) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if w.OnSegmentComplete == nil {
|
|
|
|
w.OnSegmentComplete = func(string) {
|
|
|
|
}
|
|
|
|
}
|
2023-10-26 19:40:44 +00:00
|
|
|
if w.restartPause == 0 {
|
|
|
|
w.restartPause = 2 * time.Second
|
2023-10-14 20:52:10 +00:00
|
|
|
}
|
2023-09-16 15:27:07 +00:00
|
|
|
|
2023-10-26 19:40:44 +00:00
|
|
|
w.terminate = make(chan struct{})
|
|
|
|
w.done = make(chan struct{})
|
2023-09-16 15:27:07 +00:00
|
|
|
|
2023-10-26 19:40:44 +00:00
|
|
|
w.currentInstance = &agentInstance{
|
2023-12-02 14:15:17 +00:00
|
|
|
agent: w,
|
2023-09-16 15:27:07 +00:00
|
|
|
}
|
2023-10-26 19:40:44 +00:00
|
|
|
w.currentInstance.initialize()
|
2023-09-16 15:27:07 +00:00
|
|
|
|
2023-10-26 19:40:44 +00:00
|
|
|
go w.run()
|
2023-09-16 15:27:07 +00:00
|
|
|
}
|
|
|
|
|
2023-12-08 18:17:17 +00:00
|
|
|
// Log implements logger.Writer.
|
2023-10-26 19:40:44 +00:00
|
|
|
func (w *Agent) Log(level logger.Level, format string, args ...interface{}) {
|
|
|
|
w.Parent.Log(level, "[record] "+format, args...)
|
2023-09-16 15:27:07 +00:00
|
|
|
}
|
|
|
|
|
2023-10-26 19:40:44 +00:00
|
|
|
// Close closes the agent.
|
|
|
|
func (w *Agent) Close() {
|
|
|
|
w.Log(logger.Info, "recording stopped")
|
|
|
|
close(w.terminate)
|
|
|
|
<-w.done
|
|
|
|
}
|
2023-09-16 15:27:07 +00:00
|
|
|
|
2023-10-26 19:40:44 +00:00
|
|
|
func (w *Agent) run() {
|
|
|
|
defer close(w.done)
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-w.currentInstance.done:
|
|
|
|
w.currentInstance.close()
|
|
|
|
case <-w.terminate:
|
|
|
|
w.currentInstance.close()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-time.After(w.restartPause):
|
|
|
|
case <-w.terminate:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
w.currentInstance = &agentInstance{
|
2023-12-02 14:15:17 +00:00
|
|
|
agent: w,
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|
|
|
|
w.currentInstance.initialize()
|
2023-09-16 15:27:07 +00:00
|
|
|
}
|
|
|
|
}
|