diff --git a/apidocs/openapi.yaml b/apidocs/openapi.yaml index 417d353b..ad82a07b 100644 --- a/apidocs/openapi.yaml +++ b/apidocs/openapi.yaml @@ -221,9 +221,11 @@ components: fallback: type: string - # Record + # Record and playback record: type: boolean + playback: + type: boolean recordPath: type: string recordFormat: diff --git a/internal/conf/conf.go b/internal/conf/conf.go index e9520230..30e3df54 100644 --- a/internal/conf/conf.go +++ b/internal/conf/conf.go @@ -447,7 +447,7 @@ func (conf *Conf) Validate() error { } } - // Record + // Record (deprecated) if conf.Record != nil { conf.PathDefaults.Record = *conf.Record } diff --git a/internal/conf/conf_test.go b/internal/conf/conf_test.go index e6126213..6575c545 100644 --- a/internal/conf/conf_test.go +++ b/internal/conf/conf_test.go @@ -52,6 +52,7 @@ func TestConfFromFile(t *testing.T) { Source: "publisher", SourceOnDemandStartTimeout: 10 * StringDuration(time.Second), SourceOnDemandCloseAfter: 10 * StringDuration(time.Second), + Playback: true, RecordPath: "./recordings/%path/%Y-%m-%d_%H-%M-%S-%f", RecordFormat: RecordFormatFMP4, RecordPartDuration: 100000000, diff --git a/internal/conf/path.go b/internal/conf/path.go index d6da3ee4..a6b840a0 100644 --- a/internal/conf/path.go +++ b/internal/conf/path.go @@ -96,8 +96,9 @@ type Path struct { SRTReadPassphrase string `json:"srtReadPassphrase"` Fallback string `json:"fallback"` - // Record + // Record and playback Record bool `json:"record"` + Playback bool `json:"playback"` RecordPath string `json:"recordPath"` RecordFormat RecordFormat `json:"recordFormat"` RecordPartDuration StringDuration `json:"recordPartDuration"` @@ -186,7 +187,8 @@ func (pconf *Path) setDefaults() { pconf.SourceOnDemandStartTimeout = 10 * StringDuration(time.Second) pconf.SourceOnDemandCloseAfter = 10 * StringDuration(time.Second) - // Record + // Record and playback + pconf.Playback = true pconf.RecordPath = "./recordings/%path/%Y-%m-%d_%H-%M-%S-%f" pconf.RecordFormat = RecordFormatFMP4 pconf.RecordPartDuration = 100 * StringDuration(time.Millisecond) diff --git a/internal/playback/fmp4.go b/internal/playback/fmp4.go index 179a90ef..a19e41de 100644 --- a/internal/playback/fmp4.go +++ b/internal/playback/fmp4.go @@ -179,31 +179,9 @@ func seekAndMuxParts( if !fsw { if !isRandom { - /* - var nalus [][]byte - for _, sa2 := range gop[tfhd.TrackID] { - auNALUS, err := h264.AVCCUnmarshal(sa2.Payload) - if err != nil { - return nil, err - } - // auNALUS = append([][]byte{{byte(h264.NALUTypeAccessUnitDelimiter), 240}}, auNALUS...) - nalus = append(nalus, auNALUS...) - } - - newPayload, err := h264.AVCCMarshal(nalus) - if err != nil { - return nil, err - } - - sa.Payload = newPayload - // sa.PTSOffset = gop[tfhd.TrackID][0].PTSOffset - sa.IsNonSyncSample = false - - */ - for _, sa2 := range gop[tfhd.TrackID][:len(gop[tfhd.TrackID])-1] { sa2.Duration = 0 - sa2.PTSOffset = 0 // sa.PTSOffset // // -90000 //30 * 90000 + sa2.PTSOffset = 0 outTrack.Samples = append(outTrack.Samples, sa2) } } diff --git a/internal/playback/server.go b/internal/playback/server.go index 87513c54..7aee0a46 100644 --- a/internal/playback/server.go +++ b/internal/playback/server.go @@ -52,8 +52,8 @@ func findSegments( start time.Time, duration time.Duration, ) ([]segment, error) { - if !pathConf.Record { - return nil, fmt.Errorf("record is disabled on path '%s'", pathName) + if !pathConf.Playback { + return nil, fmt.Errorf("playback is disabled on path '%s'", pathName) } recordPath := record.PathAddExtension( diff --git a/mediamtx.yml b/mediamtx.yml index 2cc101bc..d0d63d18 100644 --- a/mediamtx.yml +++ b/mediamtx.yml @@ -303,10 +303,12 @@ pathDefaults: fallback: ############################################### - # Default path settings -> Recording + # Default path settings -> Record and playback # Record streams to disk. record: no + # Enable serving recordings with the playback server. + playback: yes # Path of recording segments. # Extension is added automatically. # Available variables are %path (path name), %Y %m %d %H %M %S %f %s (time in strftime format)