diff --git a/docs/docs.go b/docs/docs.go index 1acb83ef..d7279c9b 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -5656,6 +5656,75 @@ const docTemplate = `{ } } }, + "api.GraphElement": { + "type": "object", + "properties": { + "dst_filter": { + "type": "string" + }, + "dst_name": { + "type": "string" + }, + "format": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "index": { + "type": "integer" + }, + "inpad": { + "type": "string" + }, + "layout": { + "type": "string" + }, + "outpad": { + "type": "string" + }, + "sampling": { + "description": "Hz", + "type": "integer" + }, + "src_filter": { + "type": "string" + }, + "src_name": { + "type": "string" + }, + "timebase": { + "type": "string" + }, + "type": { + "description": "audio or video", + "type": "string" + }, + "width": { + "type": "integer" + } + } + }, + "api.GraphMapping": { + "type": "object", + "properties": { + "copy": { + "type": "boolean" + }, + "index": { + "type": "integer" + }, + "input": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "output": { + "type": "integer" + } + } + }, "api.GraphQuery": { "type": "object", "properties": { @@ -6510,6 +6579,9 @@ const docTemplate = `{ "$ref": "#/definitions/api.ProgressIO" } }, + "mapping": { + "$ref": "#/definitions/api.StreamMapping" + }, "outputs": { "type": "array", "items": { @@ -8009,6 +8081,23 @@ const docTemplate = `{ } } }, + "api.StreamMapping": { + "type": "object", + "properties": { + "graphs": { + "type": "array", + "items": { + "$ref": "#/definitions/api.GraphElement" + } + }, + "mapping": { + "type": "array", + "items": { + "$ref": "#/definitions/api.GraphMapping" + } + } + } + }, "api.Version": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index 7addd5a7..a1ba41b2 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -5648,6 +5648,75 @@ } } }, + "api.GraphElement": { + "type": "object", + "properties": { + "dst_filter": { + "type": "string" + }, + "dst_name": { + "type": "string" + }, + "format": { + "type": "string" + }, + "height": { + "type": "integer" + }, + "index": { + "type": "integer" + }, + "inpad": { + "type": "string" + }, + "layout": { + "type": "string" + }, + "outpad": { + "type": "string" + }, + "sampling": { + "description": "Hz", + "type": "integer" + }, + "src_filter": { + "type": "string" + }, + "src_name": { + "type": "string" + }, + "timebase": { + "type": "string" + }, + "type": { + "description": "audio or video", + "type": "string" + }, + "width": { + "type": "integer" + } + } + }, + "api.GraphMapping": { + "type": "object", + "properties": { + "copy": { + "type": "boolean" + }, + "index": { + "type": "integer" + }, + "input": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "output": { + "type": "integer" + } + } + }, "api.GraphQuery": { "type": "object", "properties": { @@ -6502,6 +6571,9 @@ "$ref": "#/definitions/api.ProgressIO" } }, + "mapping": { + "$ref": "#/definitions/api.StreamMapping" + }, "outputs": { "type": "array", "items": { @@ -8001,6 +8073,23 @@ } } }, + "api.StreamMapping": { + "type": "object", + "properties": { + "graphs": { + "type": "array", + "items": { + "$ref": "#/definitions/api.GraphElement" + } + }, + "mapping": { + "type": "array", + "items": { + "$ref": "#/definitions/api.GraphMapping" + } + } + } + }, "api.Version": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 8e86be80..5a85588c 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -747,6 +747,52 @@ definitions: updated_at: type: string type: object + api.GraphElement: + properties: + dst_filter: + type: string + dst_name: + type: string + format: + type: string + height: + type: integer + index: + type: integer + inpad: + type: string + layout: + type: string + outpad: + type: string + sampling: + description: Hz + type: integer + src_filter: + type: string + src_name: + type: string + timebase: + type: string + type: + description: audio or video + type: string + width: + type: integer + type: object + api.GraphMapping: + properties: + copy: + type: boolean + index: + type: integer + input: + type: integer + name: + type: string + output: + type: integer + type: object api.GraphQuery: properties: query: @@ -1326,6 +1372,8 @@ definitions: items: $ref: '#/definitions/api.ProgressIO' type: array + mapping: + $ref: '#/definitions/api.StreamMapping' outputs: items: $ref: '#/definitions/api.ProgressIO' @@ -2399,6 +2447,17 @@ definitions: name: type: string type: object + api.StreamMapping: + properties: + graphs: + items: + $ref: '#/definitions/api.GraphElement' + type: array + mapping: + items: + $ref: '#/definitions/api.GraphMapping' + type: array + type: object api.Version: properties: arch: diff --git a/ffmpeg/parse/parser.go b/ffmpeg/parse/parser.go index 9ad3f4c4..59ea7387 100644 --- a/ffmpeg/parse/parser.go +++ b/ffmpeg/parse/parser.go @@ -252,6 +252,8 @@ func (p *parser) Parse(line string) uint64 { "error": err, }).Error().Log("Failed parsing HSL stream mapping") } + + return 0 } if isFFmpegOutputs { diff --git a/ffmpeg/parse/parser_test.go b/ffmpeg/parse/parser_test.go index 88890288..526fd27e 100644 --- a/ffmpeg/parse/parser_test.go +++ b/ffmpeg/parse/parser_test.go @@ -939,95 +939,68 @@ func TestParserStreamMapping(t *testing.T) { require.Equal(t, 4, len(progress.Output)) require.Equal(t, StreamMapping{ - Graphs: []Graph{ - { - Index: 0, - Graph: []GraphElement{ - {SrcName: "Parsed_null_0", SrcFilter: "null", DstName: "format", DstFilter: "format", Inpad: "default", Outpad: "default", Timebase: "1/90000", Type: "video", Format: "yuvj420p", Sampling: 0, Layout: "", Width: 1280, Height: 720}, - {SrcName: "graph 0 input from stream 0:0", SrcFilter: "buffer", DstName: "Parsed_null_0", DstFilter: "null", Inpad: "default", Outpad: "default", Timebase: "1/90000", Type: "video", Format: "yuvj420p", Sampling: 0, Layout: "", Width: 1280, Height: 720}, - {SrcName: "format", SrcFilter: "format", DstName: "out_0_0", DstFilter: "buffersink", Inpad: "default", Outpad: "default", Timebase: "1/90000", Type: "video", Format: "yuvj420p", Sampling: 0, Layout: "", Width: 1280, Height: 720}, - }, - }, { - Index: 1, - Graph: []GraphElement{ - {SrcName: "Parsed_anull_0", SrcFilter: "anull", DstName: "auto_aresample_0", DstFilter: "aresample", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "u8", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, - {SrcName: "graph_1_in_2_0", SrcFilter: "abuffer", DstName: "Parsed_anull_0", DstFilter: "anull", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "u8", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, - {SrcName: "format_out_0_2", SrcFilter: "aformat", DstName: "out_0_2", DstFilter: "abuffersink", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "fltp", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, - {SrcName: "auto_aresample_0", SrcFilter: "aresample", DstName: "format_out_0_2", DstFilter: "aformat", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "fltp", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, - }, - }, { - Index: 2, - Graph: []GraphElement{ - {SrcName: "Parsed_anull_0", SrcFilter: "anull", DstName: "auto_aresample_0", DstFilter: "aresample", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "u8", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, - {SrcName: "graph_2_in_2_0", SrcFilter: "abuffer", DstName: "Parsed_anull_0", DstFilter: "anull", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "u8", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, - {SrcName: "format_out_0_3", SrcFilter: "aformat", DstName: "out_0_3", DstFilter: "abuffersink", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "fltp", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, - {SrcName: "auto_aresample_0", SrcFilter: "aresample", DstName: "format_out_0_3", DstFilter: "aformat", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "fltp", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, - }, - }, + Graphs: []GraphElement{ + {Index: 0, Name: "Parsed_null_0", Filter: "null", DstName: "format", DstFilter: "format", Inpad: "default", Outpad: "default", Timebase: "1/90000", Type: "video", Format: "yuvj420p", Sampling: 0, Layout: "", Width: 1280, Height: 720}, + {Index: 0, Name: "graph 0 input from stream 0:0", Filter: "buffer", DstName: "Parsed_null_0", DstFilter: "null", Inpad: "default", Outpad: "default", Timebase: "1/90000", Type: "video", Format: "yuvj420p", Sampling: 0, Layout: "", Width: 1280, Height: 720}, + {Index: 0, Name: "format", Filter: "format", DstName: "out_0_0", DstFilter: "buffersink", Inpad: "default", Outpad: "default", Timebase: "1/90000", Type: "video", Format: "yuvj420p", Sampling: 0, Layout: "", Width: 1280, Height: 720}, + {Index: 1, Name: "Parsed_anull_0", Filter: "anull", DstName: "auto_aresample_0", DstFilter: "aresample", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "u8", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, + {Index: 1, Name: "graph_1_in_2_0", Filter: "abuffer", DstName: "Parsed_anull_0", DstFilter: "anull", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "u8", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, + {Index: 1, Name: "format_out_0_2", Filter: "aformat", DstName: "out_0_2", DstFilter: "abuffersink", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "fltp", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, + {Index: 1, Name: "auto_aresample_0", Filter: "aresample", DstName: "format_out_0_2", DstFilter: "aformat", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "fltp", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, + {Index: 2, Name: "Parsed_anull_0", Filter: "anull", DstName: "auto_aresample_0", DstFilter: "aresample", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "u8", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, + {Index: 2, Name: "graph_2_in_2_0", Filter: "abuffer", DstName: "Parsed_anull_0", DstFilter: "anull", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "u8", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, + {Index: 2, Name: "format_out_0_3", Filter: "aformat", DstName: "out_0_3", DstFilter: "abuffersink", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "fltp", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, + {Index: 2, Name: "auto_aresample_0", Filter: "aresample", DstName: "format_out_0_3", DstFilter: "aformat", Inpad: "default", Outpad: "default", Timebase: "1/44100", Type: "audio", Format: "fltp", Sampling: 44100, Layout: "mono", Width: 0, Height: 0}, }, - Mapping: []Mapping{ + Mapping: []GraphMapping{ { Input: 0, Output: -1, - Graph: MappingGraph{ - Index: 0, - Name: "graph 0 input from stream 0:0", - }, - Copy: false, + Index: 0, + Name: "graph 0 input from stream 0:0", + Copy: false, }, { Input: 2, Output: -1, - Graph: MappingGraph{ - Index: 1, - Name: "graph_1_in_2_0", - }, - Copy: false, + Index: 1, + Name: "graph_1_in_2_0", + Copy: false, }, { Input: 2, Output: -1, - Graph: MappingGraph{ - Index: 2, - Name: "graph_2_in_2_0", - }, - Copy: false, + Index: 2, + Name: "graph_2_in_2_0", + Copy: false, }, { Input: -1, Output: 0, - Graph: MappingGraph{ - Index: 0, - Name: "out_0_0", - }, - Copy: false, + Index: 0, + Name: "out_0_0", + Copy: false, }, { Input: 1, Output: 1, - Graph: MappingGraph{ - Index: -1, - Name: "", - }, - Copy: true, + Index: -1, + Name: "", + Copy: true, }, { Input: -1, Output: 2, - Graph: MappingGraph{ - Index: 1, - Name: "out_0_2", - }, - Copy: false, + Index: 1, + Name: "out_0_2", + Copy: false, }, { Input: -1, Output: 3, - Graph: MappingGraph{ - Index: 2, - Name: "out_0_3", - }, - Copy: false, + Index: 2, + Name: "out_0_3", + Copy: false, }, }, }, progress.Mapping) diff --git a/ffmpeg/parse/types.go b/ffmpeg/parse/types.go index 9ea7d40d..db73bd4c 100644 --- a/ffmpeg/parse/types.go +++ b/ffmpeg/parse/types.go @@ -242,46 +242,16 @@ type ffmpegGraphElement struct { Height uint64 `json:"height"` } -func (f *ffmpegGraphElement) Export() GraphElement { - return GraphElement{ - SrcName: f.SrcName, - SrcFilter: f.SrcFilter, - DstName: f.DstName, - DstFilter: f.DstFilter, - Inpad: f.Inpad, - Outpad: f.Outpad, - Timebase: f.Timebase, - Type: f.Type, - Format: f.Format, - Sampling: f.Sampling, - Layout: f.Layout, - Width: f.Width, - Height: f.Height, - } -} - type ffmpegGraph struct { - Index uint64 `json:"index"` + Index int `json:"index"` Graph []ffmpegGraphElement `json:"graph"` } -func (f *ffmpegGraph) Export() Graph { - g := Graph{ - Index: f.Index, - } - - for _, e := range f.Graph { - g.Graph = append(g.Graph, e.Export()) - } - - return g -} - -type ffmpegMapping struct { +type ffmpegGraphMapping struct { Input *ffmpegMappingIO `json:"input"` Output *ffmpegMappingIO `json:"output"` Graph struct { - Index uint64 `json:"index"` + Index int `json:"index"` Name string `json:"name"` } `json:"graph"` Copy bool `json:"copy"` @@ -293,8 +263,8 @@ type ffmpegMappingIO struct { } type ffmpegStreamMapping struct { - Graphs []ffmpegGraph `json:"graphs"` - Mapping []ffmpegMapping `json:"mapping"` + Graphs []ffmpegGraph `json:"graphs"` + Mapping []ffmpegGraphMapping `json:"mapping"` } type ffmpegProcess struct { @@ -307,23 +277,40 @@ type ffmpegProcess struct { func (f *ffmpegProcess) ExportMapping() StreamMapping { sm := StreamMapping{} - for _, g := range f.mapping.Graphs { - sm.Graphs = append(sm.Graphs, g.Export()) + for _, graph := range f.mapping.Graphs { + for _, g := range graph.Graph { + e := GraphElement{ + Index: graph.Index, + Name: g.SrcName, + Filter: g.SrcFilter, + DstName: g.DstName, + DstFilter: g.DstFilter, + Inpad: g.Inpad, + Outpad: g.Outpad, + Timebase: g.Timebase, + Type: g.Type, + Format: g.Format, + Sampling: g.Sampling, + Layout: g.Layout, + Width: g.Width, + Height: g.Height, + } + + sm.Graphs = append(sm.Graphs, e) + } } for _, fm := range f.mapping.Mapping { - m := Mapping{ + m := GraphMapping{ Input: -1, Output: -1, - Graph: MappingGraph{ - Index: int(fm.Graph.Index), - Name: fm.Graph.Name, - }, - Copy: fm.Copy, + Index: fm.Graph.Index, + Name: fm.Graph.Name, + Copy: fm.Copy, } - if len(m.Graph.Name) == 0 { - m.Graph.Index = -1 + if len(m.Name) == 0 { + m.Index = -1 } if fm.Input != nil { @@ -496,8 +483,9 @@ type Usage struct { } type GraphElement struct { - SrcName string - SrcFilter string + Index int + Name string + Filter string DstName string DstFilter string Inpad string @@ -511,24 +499,15 @@ type GraphElement struct { Height uint64 } -type Graph struct { - Index uint64 - Graph []GraphElement -} - -type MappingGraph struct { - Index int - Name string -} - -type Mapping struct { +type GraphMapping struct { Input int Output int - Graph MappingGraph + Index int + Name string Copy bool } type StreamMapping struct { - Graphs []Graph - Mapping []Mapping + Graphs []GraphElement + Mapping []GraphMapping } diff --git a/go.mod b/go.mod index 0699b42b..c9bab459 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/atrox/haikunatorgo/v2 v2.0.1 github.com/caddyserver/certmagic v0.19.2 github.com/casbin/casbin/v2 v2.77.2 - github.com/datarhei/core-client-go/v16 v16.11.1-0.20230920220938-7a37b8ea80ef + github.com/datarhei/core-client-go/v16 v16.11.1-0.20230926123431-2fdbec157292 github.com/datarhei/gosrt v0.5.4 github.com/datarhei/joy4 v0.0.0-20230505074825-fde05957445a github.com/fujiwara/shapeio v1.0.0 diff --git a/go.sum b/go.sum index 10d2d7de..e891ff68 100644 --- a/go.sum +++ b/go.sum @@ -46,8 +46,8 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/datarhei/core-client-go/v16 v16.11.1-0.20230920220938-7a37b8ea80ef h1:6uBGPAbVZpg6/BxJQ/5sM35YbyXVKI+6oD30eEX0V2k= -github.com/datarhei/core-client-go/v16 v16.11.1-0.20230920220938-7a37b8ea80ef/go.mod h1:3eKfwhPKoW7faTn+luShRVNMqcIskvlIKjRJ7ShjyL8= +github.com/datarhei/core-client-go/v16 v16.11.1-0.20230926123431-2fdbec157292 h1:/GV5wClf40U23jhwMIyoq0hgyCqmN2kRWPyRZe6Lf+Y= +github.com/datarhei/core-client-go/v16 v16.11.1-0.20230926123431-2fdbec157292/go.mod h1:3eKfwhPKoW7faTn+luShRVNMqcIskvlIKjRJ7ShjyL8= github.com/datarhei/gosrt v0.5.4 h1:dE3mmSB+n1GeviGM8xQAW3+UD3mKeFmd84iefDul5Vs= github.com/datarhei/gosrt v0.5.4/go.mod h1:MiUCwCG+LzFMzLM/kTA+3wiTtlnkVvGbW/F0XzyhtG8= github.com/datarhei/joy4 v0.0.0-20230505074825-fde05957445a h1:Tf4DSHY1xruBglr+yYP5Wct7czM86GKMYgbXH8a7OFo= diff --git a/http/api/progress.go b/http/api/progress.go index 20ce8cd8..b8072670 100644 --- a/http/api/progress.go +++ b/http/api/progress.go @@ -91,18 +91,19 @@ func (i *ProgressIO) Unmarshal(io *app.ProgressIO) { // Progress represents the progress of an ffmpeg process type Progress struct { - Input []ProgressIO `json:"inputs"` - Output []ProgressIO `json:"outputs"` - Frame uint64 `json:"frame" format:"uint64"` - Packet uint64 `json:"packet" format:"uint64"` - FPS json.Number `json:"fps" swaggertype:"number" jsonschema:"type=number"` - Quantizer json.Number `json:"q" swaggertype:"number" jsonschema:"type=number"` - Size uint64 `json:"size_kb" format:"uint64"` // kbytes - Time json.Number `json:"time" swaggertype:"number" jsonschema:"type=number"` - Bitrate json.Number `json:"bitrate_kbit" swaggertype:"number" jsonschema:"type=number"` // kbit/s - Speed json.Number `json:"speed" swaggertype:"number" jsonschema:"type=number"` - Drop uint64 `json:"drop" format:"uint64"` - Dup uint64 `json:"dup" format:"uint64"` + Input []ProgressIO `json:"inputs"` + Output []ProgressIO `json:"outputs"` + Mapping StreamMapping `json:"mapping"` + Frame uint64 `json:"frame" format:"uint64"` + Packet uint64 `json:"packet" format:"uint64"` + FPS json.Number `json:"fps" swaggertype:"number" jsonschema:"type=number"` + Quantizer json.Number `json:"q" swaggertype:"number" jsonschema:"type=number"` + Size uint64 `json:"size_kb" format:"uint64"` // kbytes + Time json.Number `json:"time" swaggertype:"number" jsonschema:"type=number"` + Bitrate json.Number `json:"bitrate_kbit" swaggertype:"number" jsonschema:"type=number"` // kbit/s + Speed json.Number `json:"speed" swaggertype:"number" jsonschema:"type=number"` + Drop uint64 `json:"drop" format:"uint64"` + Dup uint64 `json:"dup" format:"uint64"` } // Unmarshal converts a restreamer Progress to a Progress in API representation @@ -134,4 +135,74 @@ func (progress *Progress) Unmarshal(p *app.Progress) { for i, io := range p.Output { progress.Output[i].Unmarshal(&io) } + + progress.Mapping.Unmarshal(&p.Mapping) +} + +type GraphElement struct { + Index int `json:"index"` + Name string `json:"name"` + Filter string `json:"filter"` + DstName string `json:"dst_name"` + DstFilter string `json:"dst_filter"` + Inpad string `json:"inpad"` + Outpad string `json:"outpad"` + Timebase string `json:"timebase"` + Type string `json:"type"` // audio or video + Format string `json:"format"` + Sampling uint64 `json:"sampling"` // Hz + Layout string `json:"layout"` + Width uint64 `json:"width"` + Height uint64 `json:"height"` +} + +type GraphMapping struct { + Input int `json:"input"` + Output int `json:"output"` + Index int `json:"index"` + Name string `json:"name"` + Copy bool `json:"copy"` +} + +type StreamMapping struct { + Graphs []GraphElement `json:"graphs"` + Mapping []GraphMapping `json:"mapping"` +} + +// Unmarshal converts a restreamer StreamMapping to a StreamMapping in API representation +func (s *StreamMapping) Unmarshal(m *app.StreamMapping) { + s.Graphs = make([]GraphElement, 0, len(m.Graphs)) + for _, mge := range m.Graphs { + ge := GraphElement{ + Index: mge.Index, + Name: mge.Name, + Filter: mge.Filter, + DstName: mge.DstName, + DstFilter: mge.DstFilter, + Inpad: mge.Inpad, + Outpad: mge.Outpad, + Timebase: mge.Timebase, + Type: mge.Type, + Format: mge.Format, + Sampling: mge.Sampling, + Layout: mge.Layout, + Width: mge.Width, + Height: mge.Height, + } + + s.Graphs = append(s.Graphs, ge) + } + + s.Mapping = make([]GraphMapping, 0, len(m.Mapping)) + for _, mmapping := range m.Mapping { + mapping := GraphMapping{ + Input: mmapping.Input, + Output: mmapping.Output, + Index: mmapping.Index, + Name: mmapping.Name, + Copy: mmapping.Copy, + } + + s.Mapping = append(s.Mapping, mapping) + } } diff --git a/restream/app/progress.go b/restream/app/progress.go index 675bf007..9f0862f8 100644 --- a/restream/app/progress.go +++ b/restream/app/progress.go @@ -43,6 +43,7 @@ type ProgressIO struct { type Progress struct { Input []ProgressIO Output []ProgressIO + Mapping StreamMapping Frame uint64 // counter Packet uint64 // counter FPS float64 // rate, frames per second @@ -55,3 +56,33 @@ type Progress struct { Drop uint64 // counter Dup uint64 // counter } + +type GraphElement struct { + Index int + Name string + Filter string + DstName string + DstFilter string + Inpad string + Outpad string + Timebase string + Type string // audio or video + Format string + Sampling uint64 // Hz + Layout string + Width uint64 + Height uint64 +} + +type GraphMapping struct { + Input int // Index of input stream, negative if output element + Output int // Index of output stream, negative if input element + Index int // Index of the graph, negative if streamcopy + Name string // Name of the source resp. destination, empty if streamcopy + Copy bool // Whether it's a streamcopy i.e. there's no graph +} + +type StreamMapping struct { + Graphs []GraphElement + Mapping []GraphMapping +} diff --git a/restream/restream.go b/restream/restream.go index 714e3d7e..031f825b 100644 --- a/restream/restream.go +++ b/restream/restream.go @@ -1713,6 +1713,39 @@ func convertProgressFromParser(progress *app.Progress, pprogress parse.Progress) progress.Output = append(progress.Output, output) } + + for _, pgraph := range pprogress.Mapping.Graphs { + graph := app.GraphElement{ + Index: pgraph.Index, + Name: pgraph.Name, + Filter: pgraph.Filter, + DstName: pgraph.DstName, + DstFilter: pgraph.DstFilter, + Inpad: pgraph.Inpad, + Outpad: pgraph.Outpad, + Timebase: pgraph.Timebase, + Type: pgraph.Type, + Format: pgraph.Format, + Sampling: pgraph.Sampling, + Layout: pgraph.Layout, + Width: pgraph.Width, + Height: pgraph.Height, + } + + progress.Mapping.Graphs = append(progress.Mapping.Graphs, graph) + } + + for _, pmapping := range pprogress.Mapping.Mapping { + mapping := app.GraphMapping{ + Input: pmapping.Input, + Output: pmapping.Output, + Index: pmapping.Index, + Name: pmapping.Name, + Copy: pmapping.Copy, + } + + progress.Mapping.Mapping = append(progress.Mapping.Mapping, mapping) + } } func (r *restream) GetProcessLog(id app.ProcessID) (*app.Log, error) { diff --git a/vendor/github.com/datarhei/core-client-go/v16/api/progress.go b/vendor/github.com/datarhei/core-client-go/v16/api/progress.go index bf13fb1e..10d0cb0e 100644 --- a/vendor/github.com/datarhei/core-client-go/v16/api/progress.go +++ b/vendor/github.com/datarhei/core-client-go/v16/api/progress.go @@ -45,16 +45,47 @@ type ProgressIO struct { // Progress represents the progress of an ffmpeg process type Progress struct { - Input []ProgressIO `json:"inputs"` - Output []ProgressIO `json:"outputs"` - Frame uint64 `json:"frame" format:"uint64"` - Packet uint64 `json:"packet" format:"uint64"` - FPS float64 `json:"fps" swaggertype:"number" jsonschema:"type=number"` - Quantizer float64 `json:"q" swaggertype:"number" jsonschema:"type=number"` - Size uint64 `json:"size_kb" format:"uint64"` // kbytes - Time float64 `json:"time" swaggertype:"number" jsonschema:"type=number"` - Bitrate float64 `json:"bitrate_kbit" swaggertype:"number" jsonschema:"type=number"` // kbit/s - Speed float64 `json:"speed" swaggertype:"number" jsonschema:"type=number"` - Drop uint64 `json:"drop" format:"uint64"` - Dup uint64 `json:"dup" format:"uint64"` + Input []ProgressIO `json:"inputs"` + Output []ProgressIO `json:"outputs"` + Mapping StreamMapping `json:"mapping"` + Frame uint64 `json:"frame" format:"uint64"` + Packet uint64 `json:"packet" format:"uint64"` + FPS float64 `json:"fps" swaggertype:"number" jsonschema:"type=number"` + Quantizer float64 `json:"q" swaggertype:"number" jsonschema:"type=number"` + Size uint64 `json:"size_kb" format:"uint64"` // kbytes + Time float64 `json:"time" swaggertype:"number" jsonschema:"type=number"` + Bitrate float64 `json:"bitrate_kbit" swaggertype:"number" jsonschema:"type=number"` // kbit/s + Speed float64 `json:"speed" swaggertype:"number" jsonschema:"type=number"` + Drop uint64 `json:"drop" format:"uint64"` + Dup uint64 `json:"dup" format:"uint64"` +} + +type GraphElement struct { + Index int `json:"index"` + Name string `json:"name"` + Filter string `json:"filter"` + DstName string `json:"dst_name"` + DstFilter string `json:"dst_filter"` + Inpad string `json:"inpad"` + Outpad string `json:"outpad"` + Timebase string `json:"timebase"` + Type string `json:"type"` // audio or video + Format string `json:"format"` + Sampling uint64 `json:"sampling"` // Hz + Layout string `json:"layout"` + Width uint64 `json:"width"` + Height uint64 `json:"height"` +} + +type GraphMapping struct { + Input int `json:"input"` + Output int `json:"output"` + Index int `json:"index"` + Name string `json:"name"` + Copy bool `json:"copy"` +} + +type StreamMapping struct { + Graphs []GraphElement `json:"graphs"` + Mapping []GraphMapping `json:"mapping"` } diff --git a/vendor/modules.txt b/vendor/modules.txt index 42d44cab..d1246e63 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -78,7 +78,7 @@ github.com/cespare/xxhash/v2 # github.com/cpuguy83/go-md2man/v2 v2.0.2 ## explicit; go 1.11 github.com/cpuguy83/go-md2man/v2/md2man -# github.com/datarhei/core-client-go/v16 v16.11.1-0.20230920220938-7a37b8ea80ef +# github.com/datarhei/core-client-go/v16 v16.11.1-0.20230926123431-2fdbec157292 ## explicit; go 1.18 github.com/datarhei/core-client-go/v16 github.com/datarhei/core-client-go/v16/api