mirror of
https://github.com/u2takey/ffmpeg-go.git
synced 2025-09-26 20:11:17 +08:00
99 lines
2.5 KiB
Go
99 lines
2.5 KiB
Go
package ffmpeg_go
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
)
|
|
|
|
type ViewType string
|
|
|
|
const (
|
|
// FlowChart the diagram type for output in flowchart style (https://mermaid-js.github.io/mermaid/#/flowchart) (including current state
|
|
ViewTypeFlowChart ViewType = "flowChart"
|
|
// StateDiagram the diagram type for output in stateDiagram style (https://mermaid-js.github.io/mermaid/#/stateDiagram)
|
|
ViewTypeStateDiagram ViewType = "stateDiagram"
|
|
)
|
|
|
|
func (s *Stream) View(viewType ViewType) (string, error) {
|
|
switch viewType {
|
|
case ViewTypeFlowChart:
|
|
return visualizeForMermaidAsFlowChart(s)
|
|
case ViewTypeStateDiagram:
|
|
return visualizeForMermaidAsStateDiagram(s)
|
|
default:
|
|
return "", fmt.Errorf("unknown ViewType: %s", viewType)
|
|
}
|
|
}
|
|
|
|
func visualizeForMermaidAsStateDiagram(s *Stream) (string, error) {
|
|
var buf bytes.Buffer
|
|
|
|
nodes := getStreamSpecNodes([]*Stream{s})
|
|
var dagNodes []DagNode
|
|
for i := range nodes {
|
|
dagNodes = append(dagNodes, nodes[i])
|
|
}
|
|
sorted, outGoingMap, err := TopSort(dagNodes)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
buf.WriteString("stateDiagram\n")
|
|
|
|
for _, node := range sorted {
|
|
next := outGoingMap[node.Hash()]
|
|
for k, v := range next {
|
|
for _, nextNode := range v {
|
|
label := string(k)
|
|
if label == "" {
|
|
label = "<>"
|
|
}
|
|
buf.WriteString(fmt.Sprintf(` %s --> %s: %s`, node.ShortRepr(), nextNode.Node.ShortRepr(), label))
|
|
buf.WriteString("\n")
|
|
}
|
|
}
|
|
}
|
|
return buf.String(), nil
|
|
}
|
|
|
|
// visualizeForMermaidAsFlowChart outputs a visualization of a FSM in Mermaid format (including highlighting of current state).
|
|
func visualizeForMermaidAsFlowChart(s *Stream) (string, error) {
|
|
var buf bytes.Buffer
|
|
|
|
nodes := getStreamSpecNodes([]*Stream{s})
|
|
var dagNodes []DagNode
|
|
for i := range nodes {
|
|
dagNodes = append(dagNodes, nodes[i])
|
|
}
|
|
sorted, outGoingMap, err := TopSort(dagNodes)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
buf.WriteString("graph LR\n")
|
|
|
|
for _, node := range sorted {
|
|
buf.WriteString(fmt.Sprintf(` %d[%s]`, node.Hash(), node.ShortRepr()))
|
|
buf.WriteString("\n")
|
|
}
|
|
buf.WriteString("\n")
|
|
|
|
for _, node := range sorted {
|
|
next := outGoingMap[node.Hash()]
|
|
for k, v := range next {
|
|
for _, nextNode := range v {
|
|
// todo ignore merged output
|
|
label := string(k)
|
|
if label == "" {
|
|
label = "<>"
|
|
}
|
|
buf.WriteString(fmt.Sprintf(` %d --> |%s| %d`, node.Hash(), fmt.Sprintf("%s:%s", nextNode.Label, label), nextNode.Node.Hash()))
|
|
buf.WriteString("\n")
|
|
}
|
|
}
|
|
}
|
|
|
|
buf.WriteString("\n")
|
|
|
|
return buf.String(), nil
|
|
}
|