mediamtx/internal/recorder/format_mpegts_track.go
dependabot[bot] f843df4ab8
build(deps): bump github.com/bluenviron/mediacommon/v2 (#5297)
Bumps [github.com/bluenviron/mediacommon/v2](https://github.com/bluenviron/mediacommon) from 2.5.3 to 2.6.0.
- [Commits](https://github.com/bluenviron/mediacommon/compare/v2.5.3...v2.6.0)

---
updated-dependencies:
- dependency-name: github.com/bluenviron/mediacommon/v2
  dependency-version: 2.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-28 15:44:36 +01:00

97 lines
2.2 KiB
Go

package recorder
import (
"fmt"
"time"
"github.com/bluenviron/mediacommon/v2/pkg/formats/mpegts"
tscodecs "github.com/bluenviron/mediacommon/v2/pkg/formats/mpegts/codecs"
)
type formatMPEGTSTrack struct {
f *formatMPEGTS
codec tscodecs.Codec
track *mpegts.Track
startInitialized bool
startDTS time.Duration
startNTP time.Time
}
func (t *formatMPEGTSTrack) initialize() {
t.track = &mpegts.Track{
Codec: t.codec,
}
}
func (t *formatMPEGTSTrack) write(
dts time.Duration,
ntp time.Time,
randomAccess bool,
cb func(track *mpegts.Track) error,
) error {
isVideo := t.track.Codec.IsVideo()
if isVideo {
t.f.hasVideo = true
}
if !t.startInitialized {
t.startDTS = dts
t.startNTP = ntp
t.startInitialized = true
} else {
drift := ntp.Sub(t.startNTP) - (dts - t.startDTS)
if drift < -ntpDriftTolerance || drift > ntpDriftTolerance {
return fmt.Errorf("detected drift between recording duration and absolute time, resetting")
}
}
switch {
case t.f.currentSegment == nil:
t.f.currentSegment = &formatMPEGTSSegment{
pathFormat2: t.f.ri.pathFormat2,
flush: t.f.bw.Flush,
onSegmentCreate: t.f.ri.onSegmentCreate,
onSegmentComplete: t.f.ri.onSegmentComplete,
startDTS: dts,
startNTP: ntp,
log: t.f.ri,
}
t.f.currentSegment.initialize()
t.f.dw.setTarget(t.f.currentSegment)
case (!t.f.hasVideo || isVideo) &&
randomAccess &&
(dts-t.f.currentSegment.startDTS) >= t.f.ri.segmentDuration:
t.f.currentSegment.lastDTS = dts
err := t.f.currentSegment.close()
if err != nil {
return err
}
t.f.currentSegment = &formatMPEGTSSegment{
pathFormat2: t.f.ri.pathFormat2,
flush: t.f.bw.Flush,
onSegmentCreate: t.f.ri.onSegmentCreate,
onSegmentComplete: t.f.ri.onSegmentComplete,
startDTS: dts,
startNTP: ntp,
log: t.f.ri,
}
t.f.currentSegment.initialize()
t.f.dw.setTarget(t.f.currentSegment)
case (dts - t.f.currentSegment.lastFlush) >= t.f.ri.partDuration:
err := t.f.bw.Flush()
if err != nil {
return err
}
t.f.currentSegment.lastFlush = dts
}
t.f.currentSegment.lastDTS = dts
return cb(t.track)
}