diff --git a/CHANGELOG.md b/CHANGELOG.md index be1720c1..9baa0480 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,18 @@ - Add support for date placeholder in process config - Add support for creating directories for output files to be written on disk - Add GET /api/v3/report/process endpoint -- Fix S3 storage credential parsing from ENV +- Add updated_at field in process infos +- Add preserve process log history when updating a process +- Add support for input framerate data from jsonstats patch +- Add number of keyframes and extradata size to process progress data - Fix placeholder parameter parsing - Fix better naming for storage endpoint documentation - Fix freeing up S3 mounts - Fix URL validation if the path contains FFmpeg specific placeholders - Fix purging default file from HTTP cache +- Fix parsing S3 storage definition from environment variable +- Fix checking length of CPU time array ([#10](https://github.com/datarhei/core/issues/10)) +- Deprecate ENV names that do not correspond to JSON name ### Core v16.11.0 > v16.12.0 diff --git a/ffmpeg/parse/parser.go b/ffmpeg/parse/parser.go index 9633c954..b0d671e3 100644 --- a/ffmpeg/parse/parser.go +++ b/ffmpeg/parse/parser.go @@ -39,6 +39,9 @@ type Parser interface { // LastLogline returns the last parsed log line LastLogline() string + + // TransferReportHistory transfers the report history to another parser + TransferReportHistory(Parser) error } // Config is the config for the Parser implementation @@ -918,3 +921,21 @@ func (p *parser) ReportHistory() []ReportHistoryEntry { return history } + +func (p *parser) TransferReportHistory(dst Parser) error { + pp, ok := dst.(*parser) + if !ok { + return fmt.Errorf("the target parser is not of the required type") + } + + p.logHistory.Do(func(l interface{}) { + if l == nil { + return + } + + pp.logHistory.Value = l + pp.logHistory = pp.logHistory.Next() + }) + + return nil +} diff --git a/http/api/process.go b/http/api/process.go index 942f293b..6853f02a 100644 --- a/http/api/process.go +++ b/http/api/process.go @@ -14,6 +14,7 @@ type Process struct { Type string `json:"type" jsonschema:"enum=ffmpeg"` Reference string `json:"reference"` CreatedAt int64 `json:"created_at" jsonschema:"minimum=0" format:"int64"` + UpdatedAt int64 `json:"updated_at" jsonschema:"minimum=0" format:"int64"` Config *ProcessConfig `json:"config,omitempty"` State *ProcessState `json:"state,omitempty"` Report *ProcessReport `json:"report,omitempty"` diff --git a/http/handler/api/restream.go b/http/handler/api/restream.go index 6dc2e6a3..afceff8f 100644 --- a/http/handler/api/restream.go +++ b/http/handler/api/restream.go @@ -676,6 +676,7 @@ func (h *RestreamHandler) getProcess(id, filterString string) (api.Process, erro Reference: process.Reference, Type: "ffmpeg", CreatedAt: process.CreatedAt, + UpdatedAt: process.UpdatedAt, } if wants["config"] { diff --git a/restream/app/process.go b/restream/app/process.go index 830e20f7..25d354f6 100644 --- a/restream/app/process.go +++ b/restream/app/process.go @@ -114,6 +114,7 @@ type Process struct { Reference string `json:"reference"` Config *Config `json:"config"` CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` Order string `json:"order"` } @@ -123,6 +124,7 @@ func (process *Process) Clone() *Process { Reference: process.Reference, Config: process.Config.Clone(), CreatedAt: process.CreatedAt, + UpdatedAt: process.UpdatedAt, Order: process.Order, } diff --git a/restream/restream.go b/restream/restream.go index 04868995..50ed5df5 100644 --- a/restream/restream.go +++ b/restream/restream.go @@ -469,6 +469,8 @@ func (r *restream) createTask(config *app.Config) (*task, error) { CreatedAt: time.Now().Unix(), } + process.UpdatedAt = process.CreatedAt + if config.Autostart { process.Order = "start" } @@ -918,6 +920,10 @@ func (r *restream) UpdateProcess(id string, config *app.Config) error { return ErrUnknownProcess } + // This would require a major version jump + //t.process.CreatedAt = task.process.CreatedAt + t.process.UpdatedAt = time.Now().Unix() + task.parser.TransferReportHistory(t.parser) t.process.Order = task.process.Order if id != t.id { diff --git a/restream/restream_test.go b/restream/restream_test.go index 43e07fc7..8a584342 100644 --- a/restream/restream_test.go +++ b/restream/restream_test.go @@ -26,10 +26,10 @@ func getDummyRestreamer(portrange net.Portranger, validatorIn, validatorOut ffmp ffmpeg, err := ffmpeg.New(ffmpeg.Config{ Binary: binary, + LogHistoryLength: 3, Portrange: portrange, ValidatorInput: validatorIn, ValidatorOutput: validatorOut, - LogHistoryLength: 3, }) if err != nil { return nil, err @@ -226,6 +226,14 @@ func TestUpdateProcess(t *testing.T) { err = rs.AddProcess(process2) require.Equal(t, nil, err) + process, err := rs.GetProcess(process2.ID) + require.NoError(t, err) + + //createdAt := process.CreatedAt + updatedAt := process.UpdatedAt + + time.Sleep(2 * time.Second) + process3 := getDummyProcess() require.NotNil(t, process3) process3.ID = "process2" @@ -240,8 +248,11 @@ func TestUpdateProcess(t *testing.T) { _, err = rs.GetProcess(process1.ID) require.Error(t, err) - _, err = rs.GetProcess(process3.ID) + process, err = rs.GetProcess(process3.ID) require.NoError(t, err) + + //require.Equal(t, createdAt, process.CreatedAt) + require.NotEqual(t, updatedAt, process.UpdatedAt) } func TestGetProcess(t *testing.T) { @@ -498,6 +509,31 @@ func TestLog(t *testing.T) { require.Equal(t, 1, len(log.History)) } +func TestLogTransfer(t *testing.T) { + rs, err := getDummyRestreamer(nil, nil, nil, nil) + require.NoError(t, err) + + process := getDummyProcess() + + err = rs.AddProcess(process) + require.NoError(t, err) + + rs.StartProcess(process.ID) + time.Sleep(3 * time.Second) + rs.StopProcess(process.ID) + + log, _ := rs.GetProcessLog(process.ID) + + require.Equal(t, 1, len(log.History)) + + err = rs.UpdateProcess(process.ID, process) + require.NoError(t, err) + + log, _ = rs.GetProcessLog(process.ID) + + require.Equal(t, 1, len(log.History)) +} + func TestPlayoutNoRange(t *testing.T) { rs, err := getDummyRestreamer(nil, nil, nil, nil) require.NoError(t, err)