ffmpeg_go

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 26, 2023 License: Apache-2.0 Imports: 20 Imported by: 0

README

ffmpeg-go

ffmpeg-go is golang port of https://github.com/kkroening/ffmpeg-python

check examples/example_test.go and ffmpeg_test.go for more examples.

Examples

split := Input(TestInputFile1).VFlip().Split()
	split0, split1 := split.Get("0"), split.Get("1")
	overlayFile := Input(TestOverlayFile).Crop(10, 10, 158, 112)
err := Concat([]*Stream{
    split0.Trim(KwArgs{"start_frame": 10, "end_frame": 20}),
    split1.Trim(KwArgs{"start_frame": 30, "end_frame": 40})}).
    Overlay(overlayFile.HFlip(), "").
    DrawBox(50, 50, 120, 120, "red", 5).
    Output(TestOutputFile1).
    OverWriteOutput().
    Run()

Transcoding From One Codec To Another

err := ffmpeg.Input("./sample_data/in1.mp4").
		Output("./sample_data/out1.mp4", ffmpeg.KwArgs{"c:v": "libx265"}).
		OverWriteOutput().ErrorToStdOut().Run()

Cut Video From Timestamp

err := ffmpeg.Input("./sample_data/in1.mp4", ffmpeg.KwArgs{"ss": 1}).
    Output("./sample_data/out1.mp4", ffmpeg.KwArgs{"t": 1}).OverWriteOutput().Run()
assert.Nil(t, err)

Add Watermark For Video

// show watermark with size 64:-1 in the top left corner after seconds 1
overlay := ffmpeg.Input("./sample_data/overlay.png").Filter("scale", ffmpeg.Args{"64:-1"})
err := ffmpeg.Filter(
    []*ffmpeg.Stream{
        ffmpeg.Input("./sample_data/in1.mp4"),
        overlay,
    }, "overlay", ffmpeg.Args{"10:10"}, ffmpeg.KwArgs{"enable": "gte(t,1)"}).
    Output("./sample_data/out1.mp4").OverWriteOutput().ErrorToStdOut().Run()

result:

img.png

Cut Video For Gif

err := ffmpeg.Input("./sample_data/in1.mp4", ffmpeg.KwArgs{"ss": "1"}).
    Output("./sample_data/out1.gif", ffmpeg.KwArgs{"s": "320x240", "pix_fmt": "rgb24", "t": "3", "r": "3"}).
    OverWriteOutput().ErrorToStdOut().Run()

result:

img.png

Task Frame From Video

func ExampleReadFrameAsJpeg(inFileName string, frameNum int) io.Reader {
	buf := bytes.NewBuffer(nil)
	err := ffmpeg.Input(inFileName).
		Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%d)", frameNum)}).
		Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg"}).
		WithOutput(buf, os.Stdout).
		Run()
	if err != nil {
		panic(err)
	}
	return buf
}

reader := ExampleReadFrameAsJpeg("./sample_data/in1.mp4", 5)
img, err := imaging.Decode(reader)
if err != nil {
    t.Fatal(err)
}
err = imaging.Save(img, "./sample_data/out1.jpeg")
if err != nil {
    t.Fatal(err)
}

result :

image

Get Multiple Output

// get multiple output with different size/bitrate
input := ffmpeg.Input("./sample_data/in1.mp4").Split()
out1 := input.Get("0").Filter("scale", ffmpeg.Args{"1920:-1"}).
Output("./sample_data/1920.mp4", ffmpeg.KwArgs{"b:v": "5000k"})
out2 := input.Get("1").Filter("scale", ffmpeg.Args{"1280:-1"}).
Output("./sample_data/1280.mp4", ffmpeg.KwArgs{"b:v": "2800k"})

err := ffmpeg.MergeOutputs(out1, out2).OverWriteOutput().ErrorToStdOut().Run()

Show FFmpeg Progress

see complete example at: showProgress

func ExampleShowProgress(inFileName, outFileName string) {
	a, err := ffmpeg.Probe(inFileName)
	if err != nil {
		panic(err)
	}
	totalDuration := gjson.Get(a, "format.duration").Float()

	err = ffmpeg.Input(inFileName).
		Output(outFileName, ffmpeg.KwArgs{"c:v": "libx264", "preset": "veryslow"}).
		GlobalArgs("-progress", "unix://"+TempSock(totalDuration)).
		OverWriteOutput().
		Run()
	if err != nil {
		panic(err)
	}
}
ExampleShowProgress("./sample_data/in1.mp4", "./sample_data/out2.mp4")

result

progress:  .0
progress:  0.72
progress:  1.00
progress:  done

Integrate FFmpeg-go With Open-CV (gocv) For Face-detect

see complete example at: opencv

result: image

Set Cpu limit/request For FFmpeg-go

e := ComplexFilterExample("./sample_data/in1.mp4", "./sample_data/overlay.png", "./sample_data/out2.mp4")
err := e.RunWithResource(0.1, 0.5)
if err != nil {
    assert.Nil(t, err)
}

result from command top: we will see ffmpeg used 0.5 core as expected.

> top 
PID    USER       PR  NI    VIRT    RES    SHR S  %CPU   %MEM     TIME+ COMMAND
1386105 root      20   0 2114152 273780  31672 R  50.2   1.7      0:16.79 ffmpeg

View Progress Graph

function view generate mermaid chart, which can be use in markdown or view online

split := Input(TestInputFile1).VFlip().Split()
	split0, split1 := split.Get("0"), split.Get("1")
	overlayFile := Input(TestOverlayFile).Crop(10, 10, 158, 112)
b, err := Concat([]*Stream{
    split0.Trim(KwArgs{"start_frame": 10, "end_frame": 20}),
    split1.Trim(KwArgs{"start_frame": 30, "end_frame": 40})}).
    Overlay(overlayFile.HFlip(), "").
    DrawBox(50, 50, 120, 120, "red", 5).
    Output(TestOutputFile1).
    OverWriteOutput().View(ViewTypeFlowChart)
fmt.Println(b)

image

Documentation

Index

Constants

This section is empty.

Variables

View Source
var GlobalCommandOptions = make([]CommandOption, 0)
View Source
var LogCompiledCommand bool = true

Functions

func AssertType

func AssertType(hasType, expectType string, action string)

func ConvertKwargsToCmdLineArgs

func ConvertKwargsToCmdLineArgs(kwargs KwArgs) []string

func DebugNodes

func DebugNodes(node []DagNode)

func DebugOutGoingMap

func DebugOutGoingMap(node []DagNode, m map[int]map[Label][]NodeInfo)

func Probe

func Probe(fileName string, kwargs ...KwArgs) (string, error)

Probe Run ffprobe on the specified file and return a JSON representation of the output.

func ProbeReader

func ProbeReader(r io.Reader, kwargs ...KwArgs) (string, error)

ProbeReader runs ffprobe passing given reader via stdin and return a JSON representation of the output.

func ProbeReaderWithTimeout

func ProbeReaderWithTimeout(r io.Reader, timeOut time.Duration, kwargs KwArgs) (string, error)

func ProbeReaderWithTimeoutExec

func ProbeReaderWithTimeoutExec(r io.Reader, timeOut time.Duration, kwargs KwArgs) (string, error)

func ProbeWithTimeout

func ProbeWithTimeout(fileName string, timeOut time.Duration, kwargs KwArgs) (string, error)

func ProbeWithTimeoutExec

func ProbeWithTimeoutExec(fileName string, timeOut time.Duration, kwargs KwArgs) (string, error)

Types

type Args

type Args []string

func (Args) EscapeWith

func (a Args) EscapeWith(chars string) Args

func (Args) Sorted

func (a Args) Sorted() Args

type CommandOption

type CommandOption func(cmd *exec.Cmd)

type CompilationOption

type CompilationOption func(s *Stream, cmd *exec.Cmd)

func SeparateProcessGroup

func SeparateProcessGroup() CompilationOption

SeparateProcessGroup ensures that the command is run in a separate process group. This is useful to enable handling of signals such as SIGINT without propagating them to the ffmpeg process.

type DagEdge

type DagEdge struct {
	DownStreamNode   DagNode
	DownStreamLabel  Label
	UpStreamNode     DagNode
	UpStreamLabel    Label
	UpStreamSelector Selector
}

func GetInComingEdges

func GetInComingEdges(downStreamNode DagNode, inComingEdgeMap map[Label]NodeInfo) []DagEdge

func GetOutGoingEdges

func GetOutGoingEdges(upStreamNode DagNode, outOutingEdgeMap map[Label][]NodeInfo) []DagEdge

type DagNode

type DagNode interface {
	Hash() int
	// Compare two nodes
	Equal(other DagNode) bool
	// Return a full string representation of the node.
	String() string
	// Return a partial/concise representation of the node
	ShortRepr() string
	// Provides information about all incoming edges that connect to this node.
	//
	//        The edge map is a dictionary that maps an “incoming_label“ to “(outgoing_node, outgoing_label)“.  Note that
	//        implicity, “incoming_node“ is “self“.  See "Edges" section above.
	IncomingEdgeMap() map[Label]NodeInfo
}

Node in a directed-acyclic graph (DAG).

Edges: DagNodes are connected by edges. An edge connects two nodes with a label for each side: - “upstream_node“: upstream/parent node - “upstream_label“: label on the outgoing side of the upstream node - “downstream_node“: downstream/child node - “downstream_label“: label on the incoming side of the downstream node

For example, DagNode A may be connected to DagNode B with an edge labelled "foo" on A's side, and "bar" on B's side:

_____ _____ | | | | | A >[foo]---[bar]> B | |_____| |_____|

Edge labels may be integers or strings, and nodes cannot have more than one incoming edge with the same label.

DagNodes may have any number of incoming edges and any number of outgoing edges. DagNodes keep track only of their incoming edges, but the entire graph structure can be inferred by looking at the furthest downstream nodes and working backwards.

Hashing: DagNodes must be hashable, and two nodes are considered to be equivalent if they have the same hash value.

Nodes are immutable, and the hash should remain constant as a result. If a node with new contents is required, create a new node and throw the old one away.

String representation: In order for graph visualization tools to show useful information, nodes must be representable as strings. The “String“ operator should provide a more or less "full" representation of the node, and the “ShortRepr“ property should be a shortened, concise representation.

Again, because nodes are immutable, the string representations should remain constant.

func TopSort

func TopSort(downStreamNodes []DagNode) (sortedNodes []DagNode, outOutingEdgeMaps map[int]map[Label][]NodeInfo, err error)

type Graph

type Graph struct {
	OutputStream string       `json:"output_stream"`
	GraphOptions GraphOptions `json:"graph_options"`
	Nodes        []GraphNode  `json:"nodes"`
}

type GraphNode

type GraphNode struct {
	Name          string   `json:"name"`
	InputStreams  []string `json:"input_streams"`
	OutputStreams []string `json:"output_streams"`
	Args          Args     `json:"args"`
	KwArgs        KwArgs   `json:"kw_args"`
}

type GraphOptions

type GraphOptions struct {
	Timeout         time.Duration
	OverWriteOutput bool
}

type KwArgs

type KwArgs map[string]interface{}

func MergeKwArgs

func MergeKwArgs(args []KwArgs) KwArgs

func (KwArgs) Copy

func (a KwArgs) Copy() KwArgs

func (KwArgs) EscapeWith

func (a KwArgs) EscapeWith(chars string) KwArgs

func (KwArgs) GetDefault

func (a KwArgs) GetDefault(k string, defaultV interface{}) interface{}

func (KwArgs) GetString

func (a KwArgs) GetString(k string) string

func (KwArgs) HasKey

func (a KwArgs) HasKey(k string) bool

func (KwArgs) PopDefault

func (a KwArgs) PopDefault(k string, defaultV interface{}) interface{}

func (KwArgs) PopString

func (a KwArgs) PopString(k string) string

func (KwArgs) SortedKeys

func (a KwArgs) SortedKeys() []string

type Label

type Label string

type Node

type Node struct {
	// contains filtered or unexported fields
}

func FilterMultiOutput

func FilterMultiOutput(streamSpec []*Stream, filterName string, args Args, kwArgs ...KwArgs) *Node

func NewFilterNode

func NewFilterNode(name string, streamSpec []*Stream, maxInput int, args []string, kwargs KwArgs) *Node

func NewGlobalNode

func NewGlobalNode(name string, streamSpec []*Stream, args []string, kwargs KwArgs) *Node

func NewInputNode

func NewInputNode(name string, args []string, kwargs KwArgs) *Node

func NewMergeOutputsNode

func NewMergeOutputsNode(name string, streamSpec []*Stream) *Node

func NewNode

func NewNode(streamSpec []*Stream,
	name string,
	incomingStreamTypes sets.String,
	outgoingStreamType string,
	minInputs int,
	maxInputs int,
	args []string,
	kwargs KwArgs,
	nodeType string) *Node

func NewOutputNode

func NewOutputNode(name string, streamSpec []*Stream, args []string, kwargs KwArgs) *Node

func (*Node) Equal

func (n *Node) Equal(other DagNode) bool

func (*Node) Get

func (n *Node) Get(a string) *Stream

func (*Node) GetFilter

func (n *Node) GetFilter(outgoingEdges []DagEdge) string

func (*Node) GetInComingEdges

func (n *Node) GetInComingEdges() []DagEdge

func (*Node) Hash

func (n *Node) Hash() int

func (*Node) IncomingEdgeMap

func (n *Node) IncomingEdgeMap() map[Label]NodeInfo

func (*Node) ShortRepr

func (n *Node) ShortRepr() string

func (*Node) Stream

func (n *Node) Stream(label Label, selector Selector) *Stream

func (*Node) String

func (n *Node) String() string

type NodeInfo

type NodeInfo struct {
	Node     DagNode
	Label    Label
	Selector Selector
}

type RunHook

type RunHook struct {
	// contains filtered or unexported fields
}

type Selector

type Selector string

type Stream

type Stream struct {
	Node       *Node
	Label      Label
	Selector   Selector
	Type       string
	FfmpegPath string
	Context    context.Context
}

func Concat

func Concat(streams []*Stream, kwargs ...KwArgs) *Stream

func Filter

func Filter(streamSpec []*Stream, filterName string, args Args, kwArgs ...KwArgs) *Stream

func Input

func Input(filename string, kwargs ...KwArgs) *Stream

Input file URL (ffmpeg “-i“ option)

Any supplied kwargs are passed to ffmpeg verbatim (e.g. “t=20“, “f='mp4'“, “acodec='pcm'“, etc.).

To tell ffmpeg to read from stdin, use “pipe:“ as the filename.

Official documentation: `Main options <https://ffmpeg.org/ffmpeg.html#Main-options>`__

func MergeOutputs

func MergeOutputs(streams ...*Stream) *Stream

Include all given outputs in one ffmpeg command line

func NewStream

func NewStream(node *Node, streamType string, label Label, selector Selector) *Stream

func Output

func Output(streams []*Stream, fileName string, kwargs ...KwArgs) *Stream

Output file URL

Syntax:
    `ffmpeg.Output([]*Stream{stream1, stream2, stream3...}, filename, kwargs)`

Any supplied keyword arguments are passed to ffmpeg verbatim (e.g.
``t=20``, ``f='mp4'``, ``acodec='pcm'``, ``vcodec='rawvideo'``,
etc.).  Some keyword-arguments are handled specially, as shown below.

Args:
    video_bitrate: parameter for ``-b:v``, e.g. ``video_bitrate=1000``.
    audio_bitrate: parameter for ``-b:a``, e.g. ``audio_bitrate=200``.
    format: alias for ``-f`` parameter, e.g. ``format='mp4'``
        (equivalent to ``f='mp4'``).

If multiple streams are provided, they are mapped to the same
output.

To tell ffmpeg to write to stdout, use ``pipe:`` as the filename.

Official documentation: `Synopsis <https://ffmpeg.org/ffmpeg.html#Synopsis>`__
"""

func (*Stream) ASplit

func (s *Stream) ASplit() *Node

func (*Stream) Audio

func (s *Stream) Audio() *Stream

func (*Stream) ColorChannelMixer

func (s *Stream) ColorChannelMixer(kwargs ...KwArgs) *Stream

todo fix this

func (*Stream) Compile

func (s *Stream) Compile(options ...CompilationOption) *exec.Cmd

func (*Stream) Concat

func (s *Stream) Concat(streams []*Stream, kwargs ...KwArgs) *Stream

func (*Stream) Crop

func (s *Stream) Crop(x, y, w, h int, kwargs ...KwArgs) *Stream

func (*Stream) DrawBox

func (s *Stream) DrawBox(x, y, w, h int, color string, thickness int, kwargs ...KwArgs) *Stream

func (*Stream) Drawtext

func (s *Stream) Drawtext(text string, x, y int, escape bool, kwargs ...KwArgs) *Stream

func (*Stream) Equal

func (s *Stream) Equal(other Stream) bool

func (*Stream) ErrorToStdOut

func (s *Stream) ErrorToStdOut() *Stream

func (*Stream) Filter

func (s *Stream) Filter(filterName string, args Args, kwArgs ...KwArgs) *Stream

func (*Stream) Get

func (s *Stream) Get(index string) *Stream

func (*Stream) GetArgs

func (s *Stream) GetArgs() []string

func (*Stream) GlobalArgs

func (s *Stream) GlobalArgs(args ...string) *Stream

Add extra global command-line argument(s), e.g. “-progress“.

func (*Stream) HFlip

func (s *Stream) HFlip(kwargs ...KwArgs) *Stream

func (*Stream) Hash

func (s *Stream) Hash() int

func (*Stream) Hue

func (s *Stream) Hue(kwargs ...KwArgs) *Stream

func (*Stream) Output

func (s *Stream) Output(fileName string, kwargs ...KwArgs) *Stream

func (*Stream) OverWriteOutput

func (s *Stream) OverWriteOutput() *Stream

func (*Stream) Overlay

func (s *Stream) Overlay(overlayParentNode *Stream, eofAction string, kwargs ...KwArgs) *Stream

func (*Stream) OverwriteOutput

func (s *Stream) OverwriteOutput(stream *Stream) *Stream

Overwrite output files without asking (ffmpeg “-y“ option)

Official documentation: `Main options <https://ffmpeg.org/ffmpeg.html#Main-options>`_

func (*Stream) Run

func (s *Stream) Run(options ...CompilationOption) error

func (*Stream) RunLinux

func (s *Stream) RunLinux() error

func (*Stream) RunWithResource

func (s *Stream) RunWithResource(cpuRequest, cpuLimit float32) error

func (*Stream) SetFfmpegPath

func (s *Stream) SetFfmpegPath(path string) *Stream

func (*Stream) SetPts

func (s *Stream) SetPts(expr string) *Node

func (*Stream) Silent

func (s *Stream) Silent(isSilent bool) *Stream

func (*Stream) Split

func (s *Stream) Split() *Node

func (*Stream) String

func (s *Stream) String() string

func (*Stream) Trim

func (s *Stream) Trim(kwargs ...KwArgs) *Stream

func (*Stream) VFlip

func (s *Stream) VFlip(kwargs ...KwArgs) *Stream

func (*Stream) Video

func (s *Stream) Video() *Stream

func (*Stream) View

func (s *Stream) View(viewType ViewType) (string, error)

func (*Stream) WithCpuCoreLimit

func (s *Stream) WithCpuCoreLimit(n float32) *Stream

func (*Stream) WithCpuCoreRequest

func (s *Stream) WithCpuCoreRequest(n float32) *Stream

func (*Stream) WithCpuSet

func (s *Stream) WithCpuSet(n string) *Stream

func (*Stream) WithErrorOutput

func (s *Stream) WithErrorOutput(out io.Writer) *Stream

func (*Stream) WithInput

func (s *Stream) WithInput(reader io.Reader) *Stream

func (*Stream) WithMemSet

func (s *Stream) WithMemSet(n string) *Stream

func (*Stream) WithOutput

func (s *Stream) WithOutput(out ...io.Writer) *Stream

func (*Stream) WithTimeout

func (s *Stream) WithTimeout(timeOut time.Duration) *Stream

func (*Stream) ZoomPan

func (s *Stream) ZoomPan(kwargs ...KwArgs) *Stream

type ViewType

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"
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL