Skip to content

Commit

Permalink
support recording to MPEG-TS (#2505)
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 authored Oct 14, 2023
1 parent 4ec12a6 commit 95ab937
Show file tree
Hide file tree
Showing 33 changed files with 1,911 additions and 1,336 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ And can be recorded with:
|format|video codecs|audio codecs|
|------|------------|------------|
|[fMP4](#record-streams-to-disk)|AV1, VP9, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG|Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, LPCM|
|[MPEG-TS](#record-streams-to-disk)|H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video|Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3|

**Features**

Expand Down
2 changes: 1 addition & 1 deletion internal/conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ type Conf struct {
// Record
Record *bool `json:"record,omitempty"` // deprecated
RecordPath *string `json:"recordPath,omitempty"` // deprecated
RecordFormat *string `json:"recordFormat,omitempty"` // deprecated
RecordFormat *RecordFormat `json:"recordFormat,omitempty"` // deprecated
RecordPartDuration *StringDuration `json:"recordPartDuration,omitempty"` // deprecated
RecordSegmentDuration *StringDuration `json:"recordSegmentDuration,omitempty"` // deprecated
RecordDeleteAfter *StringDuration `json:"recordDeleteAfter,omitempty"` // deprecated
Expand Down
2 changes: 1 addition & 1 deletion internal/conf/conf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestConfFromFile(t *testing.T) {
SourceOnDemandStartTimeout: 10 * StringDuration(time.Second),
SourceOnDemandCloseAfter: 10 * StringDuration(time.Second),
RecordPath: "./recordings/%path/%Y-%m-%d_%H-%M-%S-%f",
RecordFormat: "fmp4",
RecordFormat: RecordFormatFMP4,
RecordPartDuration: 100000000,
RecordSegmentDuration: 3600000000000,
RecordDeleteAfter: 86400000000000,
Expand Down
10 changes: 2 additions & 8 deletions internal/conf/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type Path struct {
// Record
Record bool `json:"record"`
RecordPath string `json:"recordPath"`
RecordFormat string `json:"recordFormat"`
RecordFormat RecordFormat `json:"recordFormat"`
RecordPartDuration StringDuration `json:"recordPartDuration"`
RecordSegmentDuration StringDuration `json:"recordSegmentDuration"`
RecordDeleteAfter StringDuration `json:"recordDeleteAfter"`
Expand Down Expand Up @@ -150,7 +150,7 @@ func (pconf *Path) setDefaults() {

// Record
pconf.RecordPath = "./recordings/%path/%Y-%m-%d_%H-%M-%S-%f"
pconf.RecordFormat = "fmp4"
pconf.RecordFormat = RecordFormatFMP4
pconf.RecordPartDuration = 100 * StringDuration(time.Millisecond)
pconf.RecordSegmentDuration = 3600 * StringDuration(time.Second)
pconf.RecordDeleteAfter = 24 * 3600 * StringDuration(time.Second)
Expand Down Expand Up @@ -400,12 +400,6 @@ func (pconf *Path) check(conf *Conf, name string) error {
}
}

// Record

if pconf.RecordFormat != "fmp4" {
return fmt.Errorf("unsupported record format '%s'", pconf.RecordFormat)
}

// Publisher

if pconf.DisablePublisherOverride != nil {
Expand Down
56 changes: 56 additions & 0 deletions internal/conf/record_format.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package conf

import (
"encoding/json"
"fmt"
)

// RecordFormat is the recordFormat parameter.
type RecordFormat int

// supported values.
const (
RecordFormatFMP4 RecordFormat = iota
RecordFormatMPEGTS
)

// MarshalJSON implements json.Marshaler.
func (d RecordFormat) MarshalJSON() ([]byte, error) {
var out string

switch d {
case RecordFormatMPEGTS:
out = "mpegts"

default:
out = "fmp4"
}

return json.Marshal(out)
}

// UnmarshalJSON implements json.Unmarshaler.
func (d *RecordFormat) UnmarshalJSON(b []byte) error {
var in string
if err := json.Unmarshal(b, &in); err != nil {
return err
}

switch in {
case "mpegts":
*d = RecordFormatMPEGTS

case "fmp4":
*d = RecordFormatFMP4

default:
return fmt.Errorf("invalid record format '%s'", in)
}

return nil
}

// UnmarshalEnv implements env.Unmarshaler.
func (d *RecordFormat) UnmarshalEnv(_ string, v string) error {
return d.UnmarshalJSON([]byte(`"` + v + `"`))
}
2 changes: 1 addition & 1 deletion internal/conf/rtsp_range_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
// RTSPRangeType is the type used in the Range header.
type RTSPRangeType int

// supported rtsp range types.
// supported values.
const (
RTSPRangeTypeUndefined RTSPRangeType = iota
RTSPRangeTypeClock
Expand Down
1 change: 1 addition & 0 deletions internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func gatherCleanerEntries(paths map[string]*conf.Path) []record.CleanerEntry {
if pa.Record {
entry := record.CleanerEntry{
RecordPath: pa.RecordPath,
RecordFormat: pa.RecordFormat,
RecordDeleteAfter: time.Duration(pa.RecordDeleteAfter),
}
out[entry] = struct{}{}
Expand Down
2 changes: 1 addition & 1 deletion internal/core/hls_muxer.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ func (m *hlsMuxer) runInner(innerCtx context.Context, innerReady chan struct{})
innerReady <- struct{}{}

m.Log(logger.Info, "is converting into HLS, %s",
sourceMediaInfo(medias))
mediaInfo(medias))

m.writer.Start()

Expand Down
Loading

0 comments on commit 95ab937

Please sign in to comment.