2024-09-08 18:33:18 +00:00
|
|
|
package recorder
|
2023-10-26 19:40:44 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/bluenviron/mediacommon/pkg/formats/fmp4"
|
|
|
|
|
|
|
|
"github.com/bluenviron/mediamtx/internal/conf"
|
|
|
|
"github.com/bluenviron/mediamtx/internal/logger"
|
2024-09-08 18:33:18 +00:00
|
|
|
"github.com/bluenviron/mediamtx/internal/recordstore"
|
2023-10-26 19:40:44 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type sample struct {
|
|
|
|
*fmp4.PartSample
|
2024-10-07 15:59:32 +00:00
|
|
|
dts int64
|
2024-01-21 18:15:31 +00:00
|
|
|
ntp time.Time
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|
|
|
|
|
2024-10-04 22:49:44 +00:00
|
|
|
type recorderInstance struct {
|
2024-09-08 18:33:18 +00:00
|
|
|
agent *Recorder
|
2023-10-26 19:40:44 +00:00
|
|
|
|
2023-12-02 14:35:21 +00:00
|
|
|
pathFormat string
|
|
|
|
format format
|
2023-10-26 19:40:44 +00:00
|
|
|
|
|
|
|
terminate chan struct{}
|
|
|
|
done chan struct{}
|
|
|
|
}
|
|
|
|
|
2024-08-01 14:34:40 +00:00
|
|
|
// Log implements logger.Writer.
|
2024-10-04 22:49:44 +00:00
|
|
|
func (ai *recorderInstance) Log(level logger.Level, format string, args ...interface{}) {
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.agent.Log(level, format, args...)
|
|
|
|
}
|
|
|
|
|
2024-10-04 22:49:44 +00:00
|
|
|
func (ai *recorderInstance) initialize() {
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.pathFormat = ai.agent.PathFormat
|
2023-10-26 19:40:44 +00:00
|
|
|
|
2024-09-08 18:33:18 +00:00
|
|
|
ai.pathFormat = recordstore.PathAddExtension(
|
2024-08-01 14:34:40 +00:00
|
|
|
strings.ReplaceAll(ai.pathFormat, "%path", ai.agent.PathName),
|
|
|
|
ai.agent.Format,
|
2024-01-23 19:52:05 +00:00
|
|
|
)
|
2023-10-26 19:40:44 +00:00
|
|
|
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.terminate = make(chan struct{})
|
|
|
|
ai.done = make(chan struct{})
|
2023-10-26 19:40:44 +00:00
|
|
|
|
2024-08-01 14:34:40 +00:00
|
|
|
switch ai.agent.Format {
|
2023-10-26 19:40:44 +00:00
|
|
|
case conf.RecordFormatMPEGTS:
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.format = &formatMPEGTS{
|
|
|
|
ai: ai,
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.format.initialize()
|
2023-10-26 19:40:44 +00:00
|
|
|
|
|
|
|
default:
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.format = &formatFMP4{
|
|
|
|
ai: ai,
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.format.initialize()
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|
|
|
|
|
2024-10-04 22:49:44 +00:00
|
|
|
ai.agent.Stream.StartReader(ai)
|
|
|
|
|
2024-08-01 14:34:40 +00:00
|
|
|
go ai.run()
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|
|
|
|
|
2024-10-04 22:49:44 +00:00
|
|
|
func (ai *recorderInstance) close() {
|
2024-08-01 14:34:40 +00:00
|
|
|
close(ai.terminate)
|
|
|
|
<-ai.done
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|
|
|
|
|
2024-10-04 22:49:44 +00:00
|
|
|
func (ai *recorderInstance) run() {
|
2024-08-01 14:34:40 +00:00
|
|
|
defer close(ai.done)
|
2023-10-26 19:40:44 +00:00
|
|
|
|
|
|
|
select {
|
2024-10-04 22:49:44 +00:00
|
|
|
case err := <-ai.agent.Stream.ReaderError(ai):
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.Log(logger.Error, err.Error())
|
2023-10-26 19:40:44 +00:00
|
|
|
|
2024-08-01 14:34:40 +00:00
|
|
|
case <-ai.terminate:
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|
|
|
|
|
2024-10-04 22:49:44 +00:00
|
|
|
ai.agent.Stream.RemoveReader(ai)
|
|
|
|
|
2024-08-01 14:34:40 +00:00
|
|
|
ai.format.close()
|
2023-10-26 19:40:44 +00:00
|
|
|
}
|