mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-20 02:00:05 -08:00
Some checks are pending
code_lint / go (push) Waiting to run
code_lint / go_mod (push) Waiting to run
code_lint / docs (push) Waiting to run
code_lint / api_docs (push) Waiting to run
code_test / test_64 (push) Waiting to run
code_test / test_32 (push) Waiting to run
code_test / test_e2e (push) Waiting to run
in API (/paths/list, /paths/get) and metrics (paths_bytes_sent), the amount of sent bytes was increased even in case of writes to the recorder and HLS muxer, which are not generating network traffic. This fixes the issue.
106 lines
2 KiB
Go
106 lines
2 KiB
Go
package recorder
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/bluenviron/mediacommon/v2/pkg/formats/fmp4"
|
|
|
|
"github.com/bluenviron/mediamtx/internal/conf"
|
|
"github.com/bluenviron/mediamtx/internal/logger"
|
|
"github.com/bluenviron/mediamtx/internal/recordstore"
|
|
"github.com/bluenviron/mediamtx/internal/stream"
|
|
)
|
|
|
|
type sample struct {
|
|
*fmp4.Sample
|
|
dts int64
|
|
ntp time.Time
|
|
}
|
|
|
|
type recorderInstance 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
|
|
|
|
pathFormat2 string
|
|
format2 format
|
|
skip bool
|
|
reader *stream.Reader
|
|
|
|
terminate chan struct{}
|
|
done chan struct{}
|
|
}
|
|
|
|
// Log implements logger.Writer.
|
|
func (ri *recorderInstance) Log(level logger.Level, format string, args ...interface{}) {
|
|
ri.parent.Log(level, format, args...)
|
|
}
|
|
|
|
func (ri *recorderInstance) initialize() {
|
|
ri.pathFormat2 = ri.pathFormat
|
|
ri.pathFormat2 = recordstore.PathAddExtension(
|
|
strings.ReplaceAll(ri.pathFormat2, "%path", ri.pathName),
|
|
ri.format,
|
|
)
|
|
ri.reader = &stream.Reader{
|
|
SkipBytesSent: true,
|
|
Parent: ri,
|
|
}
|
|
|
|
ri.terminate = make(chan struct{})
|
|
ri.done = make(chan struct{})
|
|
|
|
switch ri.format {
|
|
case conf.RecordFormatMPEGTS:
|
|
ri.format2 = &formatMPEGTS{
|
|
ri: ri,
|
|
}
|
|
ok := ri.format2.initialize()
|
|
ri.skip = !ok
|
|
|
|
default:
|
|
ri.format2 = &formatFMP4{
|
|
ri: ri,
|
|
}
|
|
ok := ri.format2.initialize()
|
|
ri.skip = !ok
|
|
}
|
|
|
|
if !ri.skip {
|
|
ri.stream.AddReader(ri.reader)
|
|
}
|
|
|
|
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.reader.Error():
|
|
ri.Log(logger.Error, err.Error())
|
|
|
|
case <-ri.terminate:
|
|
}
|
|
|
|
ri.stream.RemoveReader(ri.reader)
|
|
} else {
|
|
<-ri.terminate
|
|
}
|
|
|
|
ri.format2.close()
|
|
}
|