Giter VIP home page Giter VIP logo

ffmpeg-go's Introduction

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.

How to get and use

You can get this package via:

go get -u github.com/u2takey/ffmpeg-go

Note: ffmpeg-go makes no attempt to download/install FFmpeg, as ffmpeg-go is merely a pure-Go wrapper - whereas FFmpeg installation is platform-dependent/environment-specific, and is thus the responsibility of the user, as described below.

Installing FFmpeg

Before using ffmpeg-go, FFmpeg must be installed and accessible via the $PATH environment variable.

There are a variety of ways to install FFmpeg, such as the official download links, or using your package manager of choice (e.g. sudo apt install ffmpeg on Debian/Ubuntu, brew install ffmpeg on OS X, etc.).

Regardless of how FFmpeg is installed, you can check if your environment path is set correctly by running the ffmpeg command from the terminal, in which case the version information should appear, as in the following example (truncated for brevity):

$ ffmpeg
ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)

Note: The actual version information displayed here may vary from one system to another; but if a message such as ffmpeg: command not found appears instead of the version information, FFmpeg is not properly installed.

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

ffmpeg-go's People

Contributors

alexg-axis avatar alx-ef avatar andrewiankidd avatar arshamalh avatar bbars avatar bubbajoe avatar connorryanbaker avatar gabivlj avatar kirari04 avatar lixiang12407 avatar msansen avatar stombeur avatar testwill avatar u2takey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ffmpeg-go's Issues

Generated ffmpeg command is wrong!

Hi and thanks for this great go package.

I tried to run this block of code:

func TakeScreenshot(filePath string, destination string, timestamp int) error {
	err := ffmpeg.
		Input(filePath).
		OverWriteOutput().
		Output(destination).
		GlobalArgs("-y", "-ss 1", "-vframes 1", "-q:v 2", "-vf", "scale=1080:-1").
		Run()

	if err != nil {
		return err
	}

	return nil
}

And from the stdout of my code i saw that it was trying to run this command:
ffmpeg -i ./tmp/file.mp4 ./tmp/screenshot.jpg -y -ss 1 -vframes 1 -q:v 2 -vf scale=1080:-1

Which happened to not work at all, the correct command for creating a thumbnail is this one:
ffmpeg -i ./tmp/file.mp4 -y -ss 1 -vframes 1 -q:v 2 -vf scale=1080:-1 ./tmp/screenshot.jpg

Simply the position of the output file should not be in the middle. Am i doing something wrong here?

Stdin pipe not working

Hi! When you try to use an io.Reader input and specify 'pipe:' like this:

	fd, err := os.Open("./file.mp3")
	if err != nil {
		panic(err)
	}
	err = ffmpeg_go.Input("pipe:", ffmpeg_go.KwArgs{"format": "mp3"}).
		WithInput(fd).
		Output("./playlist.m3u8", ffmpeg_go.KwArgs{"c:a": "aac", "b:a": "320k", "hls_list_size": "0", "hls_time": "20"}).
		OverWriteOutput().ErrorToStdOut().Run()

It doesn't work as expected:
image

If you try to do the compiled command with a pipe

cat file.mp3 | ffmpeg -f mp3 -i pipe: -b:a 320k -c:a aac -hls_list_size 0 -hls_time 20 ./playlist.m3u8 -y

It should work.

As I can see, the library uses the 'Stdin' key on the context to save the io.Reader, but when it calls Output() it creates an output node, then calls Stream(), which is initialised with context.Background() as seen here:

ffmpeg-go/node.go

Lines 28 to 36 in 8af5c38

func NewStream(node *Node, streamType string, label Label, selector Selector) *Stream {
return &Stream{
Node: node,
Label: label,
Selector: selector,
Type: streamType,
Context: context.Background(),
}
}

This makes the previous keys like 'Stdin' to not exist anymore.

One solution would be setting somewhere the previous stream context to the next stream that output returns.
Maybe by doing it here?

ffmpeg-go/ffmpeg.go

Lines 81 to 91 in 8af5c38

func Output(streams []*Stream, fileName string, kwargs ...KwArgs) *Stream {
args := MergeKwArgs(kwargs)
if !args.HasKey("filename") {
if fileName == "" {
panic("filename must be provided")
}
args["filename"] = fileName
}
return NewOutputNode("output", streams, nil, args).Stream("", "")
}

It happens on github.com/u2takey/ffmpeg-go v0.4.1

Error handling

Hi quick question. In a very specific env I keep getting exit status 1 and I have no idea how to go about troubleshooting this.

For context:
docker image with alpine linux on my arch linux development machine works fine
same docker image on a digital ocean vps returns exit status one from ffmpeg

enhance opencv example

what if I need to do
ffmpeg capture camera -> opencv image process -> ffmpeg to file or stream

what would be the code look like with this lib.

Stop playing a stream

Hello,

I would like to use this library to play an endless stream. Is there an option to stop playing the stream? Like executing stream.Stop() in another goroutine or by passing a context.Context, which can be cancelled?

how can i view only the stats

how can i replicate this command

ffmpeg -v quiet -stats -i  vid -i aud output.mp4

i currently have this

	in1 := ffmpeg.Input(vid)
	in2 := ffmpeg.Input(aud)

	err = ffmpeg.Concat([]*ffmpeg.Stream{in1, in2}, ffmpeg.KwArgs{"v": 1, "a": 1}).
		Output(filename, ffmpeg.KwArgs{"v": "quiet"}).
		OverWriteOutput().ErrorToStdOut().Run()

	if err != nil {
		fmt.Println(err)
	}

but i dont know where i'm supposed to add ffmpeg.Args{"stats"}

i need to see only the stats(the progress of the files it's merging)

i.e.

frame=  234 fps=155 q=-1.0 Lsize=     554kB time=00:00:07.80 bitrate= 581.2kbits/s speed=5.18x 

[SOLVED] by using GlobalArgs("-stats")
i.e.

err = ffmpeg.Concat([]*ffmpeg.Stream{in1, in2}, ffmpeg.KwArgs{"v": 1, "a": 1}).
		Output(filename, ffmpeg.KwArgs{"v": "quiet"}).
		GlobalArgs("-stats").
		OverWriteOutput().ErrorToStdOut().Run()

How to use MergeKwArgs

args := ffmpeg.KwArgs{"c:v": "libx264", "threads": "2"}
	if videoLen > 240 {
		args = ffmpeg.KwArgs{"c:v": "libx264",  "threads": "2" ,"ss": "00:00:10"}
		ffmpeg.MergeKwArgs(???????)
	}

"Imaging" not declared

The sample code Task Frames of Video do not work, "imaging" and "t" are not declared.

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

No sound after concat operation

Hello,

I want to concatenate two videos "1.mp4" and "2.mp4" using ffmpeg.Concat(streams) function, it gives me the concatenation of the videos without sound wich is problematic.

After some research, I found out that the following command works:

ffmpeg -i 1.mp4 -i 2.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" ./results/final.mp4 -y

However impossible for me to figure out how to create this command with this library.
Here is my code:

	files, err := ioutil.ReadDir("./videos")
	if err != nil {
		log.Fatalln(err)
	}
	//Mix them !
	log.Println(files)

	var files_stream []*ffmpeg.Stream

	for _, file := range files {
		files_stream = append(files_stream, ffmpeg.Input("./videos/"+file.Name()))
	}

	err = ffmpeg.Concat(files_stream).Output("./results/final.mp4").OverWriteOutput().ErrorToStdOut().Run()

	if err != nil {
		log.Fatalln(err)
	}

	log.Println("Done ! check here: ./results/final.mp4")

In the ffmpeg output I can clearly see both Audio and Video stream for both inputs + the top command managed to handle them so I don't think the problem come from the videos.

Thank you for your help 😄

CPU limits and RunWithResource

In README there's a whole section dedicated to Set Cpu limit/request For FFmpeg-go,
but RunWithResource is not available in the code.

What is that function and how to use it?

how to use nullsrc

hello ,
i want to use

  -re  -i  1.mp4
  -re  -i  2.mp4
  -re  -i  3.mp4
  -re  -i  4.mp4
 -filter_complex
"nullsrc=size=640x480 [base]; <br>[0:v] setpts=PTS-STARTPTS,scale=320x240 [upperleft];  <br>[1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright];
[2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft];
[3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright];
[base][upperleft] overlay=shortest=1[tmp1];
[tmp1][upperright] overlay=shortest=1:x=320 [tmp2];
[tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3];
[tmp3][lowerright] overlay=shortest=1:x=320:y=240"
 -c:v libx264 out.mp4

How to use nullsrc?
thanks

Overwrite audio at offset

I'm trying to overwrite the audio at a specific offset to provide commentary. I've been struggling with the correct way to do this with ffmpeg, but found some use of atrim:

ffmpeg -y -i original.flac -i replacement.flac \
  -filter_complex "[0]atrim=0:2[Apre];[0]atrim=5,asetpts=PTS-STARTPTS[Apost];\
                   [Apre][1][Apost]concat=n=3:v=0:a=1" out.flac
                   
I was wondering if you could help me find a way to do this with this or if perhaps there is a better way.

How would you run a screen capture ffmpeg command

This is for doing a screen capture on a mac but it is a universal screen capture problem.

So I have this command:

ffmpeg -f avfoundation -i "2" -c:v h264 -crf 15 -vf "scale=1920:1280,fps=60,format=yuv420p" output.mp4

How would it get the avfoundation into the input stream?

I am trying to use this:

`
input := ffmpeg_go.Input(""2"", ffmpeg_go.KwArgs{"f": "avfoundation", "c:v": "h264", "crf": "15", "vf": ""scale=1920:1280,fps=60,format=yuv420p""})

output := input.Output("output.mp4")

output.Run()
`

TTS

Hi.
Does the library support TTS, can I convert text to audio file?

Pls,need Help! How to merge video clip?

i want to merger some video clip which like "a.mp4", "b.mp4" , But i don't know how to use ffmpeg-go to merge them, ( on command line i use ffmpeg -i "concat:a.mp4|b.mp4" -c copy output10.mp4)
How to merge video clip?
Can u offer some demo , thanks!
Pls,need Help!

MergeKwArgs; same key overlaps because it is map

Hello, I wanted to pass same name parameter, so I wanted to use KwArgs's same key, but as it is just map, I cannot do it.

So I assume MergeKwArgs should not actually merge into one KwArgs which backs to just Golang's map as it is not allowed to have multiple same key.

Concat + Audio missing.

@u2takey For some reason, the audio is getting lost during concat.

I tried the example you mentioned here and lost the audio completely on the concat.mp4 even though I had perfect audio on the two files.

Here is my version of the code, still the audio is not working - note the Video is completely fine:

// Lets concate everything.
finalFiles := []*ffmpeg.Stream{}
for _, file := range listFiles() {
	finalFiles = append(finalFiles, ffmpeg.Input(file.Name()))
}

ffmpeg.Concat(finalFiles).
	Output("w_final.mp4").
	OverWriteOutput().
	ErrorToStdOut().
	Run()

If I modify the command output (by adding :a=1) & execute on command line it works perfectly fine:
ffmpeg -i ./w_one.mp4 -i ./w_two.mp4 -i ./w_three.mp4 -filter_complex "[0][1][2]concat=n=3[s0]" -map "[s0]" ./concat.mp4 -y
to
ffmpeg -i ./w_one.mp4 -i ./w_two.mp4 -i ./w_three.mp4 -filter_complex "[0][1][2]concat=n=3:a=1[s0]" -map "[s0]" ./concat.mp4 -y

Please let me know where to add these parameter to make it work? Though I tried this below and it doesn't work, instead it throws an error

ffmpeg.Concat(finalFiles, ffmpeg.KwArgs{"a": "1"}).

Error:

panic: interface conversion: interface {} is string, not int

goroutine 1 [running]:
github.com/u2takey/ffmpeg-go.Concat({0x140000d2ea0, 0x3, 0x4}, {0x1400019fdf0, 0x1, 0x100e84ee8?})
        /Users/kishore/go/pkg/mod/github.com/u2takey/[email protected]/filters.go:108 +0x2d0
main.main()
        /Users/kishore/proj/github.com/kishorevaishnav/hotbrain/main.go:120 +0x158
exit status 2

Wrong input order after concat() for more than 10 inputs

Overview

When using the Concat() function for more than 10 inputs, the original ordering of those input files are not correctly preserved.

In the following small case below, 16 input streams are created (0, 1, 2, 3, ..., 14, 15), but the final output command has the order (0, 1, 10, 11, 12, 13, 14, 15, 2, 3, 4, ... 8, 9) as if the indices were sorted lexicographically.

Minimal reproducible case

Source code:

package main

import (
	"fmt"

	ffmpeg "github.com/u2takey/ffmpeg-go"
)

func main() {
	filelist := []string{}
	for i := 0; i < 16; i++ {
		filelist = append(filelist, fmt.Sprintf("test%d.mp4", i))
	}

	inputs := make([]*ffmpeg.Stream, 0, len(filelist))
	for _, v := range filelist {
		inputs = append(inputs, ffmpeg.Input(v))
	}
	ff_task := ffmpeg.Concat(inputs).Output("output.mp4").OverWriteOutput()
	println(ff_task.Compile())
	mermaid_view, _ := ff_task.View(ffmpeg.ViewTypeFlowChart)
	println(mermaid_view)
}

Compiled command:

ffmpeg -i test0.mp4 -i test1.mp4 -i test10.mp4 -i test11.mp4 -i test12.mp4 -i test13.mp4 
-i test14.mp4 -i test15.mp4 -i test2.mp4 -i test3.mp4 -i test4.mp4 -i test5.mp4 -i test6.mp4 
-i test7.mp4 -i test8.mp4 -i test9.mp4 
-filter_complex [0][1][2][3][4][5][6][7][8][9][10][11][12][13][14][15]concat=n=16[s0] 
-map [s0] output.mp4 -y

Mermaid dependency graph:

graph LR
    3941257213206123015[input]
    -6530390412756632220[input]
    7552133026329416720[input]
    -1796561310369158781[input]
    -4899040177159599726[input]
    4198974375479273573[input]
    -6574418899481965596[input]
    3897228726480789639[input]
    5418486196261043753[input]
    -473457997601007962[input]
    -1752532823643825405[input]
    7596161513054750096[input]
    4243002862204606949[input]
    -4855011690434266350[input]
    -2903915435716980545[input]
    6444814085353697628[input]
    -8934247347040772720[concat]
    -8268504780477368488[output]

    3941257213206123015 --> |0:<>| -8934247347040772720
    -6530390412756632220 --> |1:<>| -8934247347040772720
    7552133026329416720 --> |10:<>| -8934247347040772720
    -1796561310369158781 --> |11:<>| -8934247347040772720
    -4899040177159599726 --> |12:<>| -8934247347040772720
    4198974375479273573 --> |13:<>| -8934247347040772720
    -6574418899481965596 --> |14:<>| -8934247347040772720
    3897228726480789639 --> |15:<>| -8934247347040772720
    5418486196261043753 --> |2:<>| -8934247347040772720
    -473457997601007962 --> |3:<>| -8934247347040772720
    -1752532823643825405 --> |4:<>| -8934247347040772720
    7596161513054750096 --> |5:<>| -8934247347040772720
    4243002862204606949 --> |6:<>| -8934247347040772720
    -4855011690434266350 --> |7:<>| -8934247347040772720
    -2903915435716980545 --> |8:<>| -8934247347040772720
    6444814085353697628 --> |9:<>| -8934247347040772720
    -8934247347040772720 --> |0:<>| -8268504780477368488
Loading

take audio from mp4 video using ffmpeg

I'm trying to take audio from an mp4 video. I don't want to create extra local files, but I can't pass the input otherwise.

I transfer the created file and return the audio to io.Reader(audio var):

telegramFile, err := r.bot.GetFile(&msg.VideoNote.File)
if err != nil {
    // handling error
}
fileBytes, err := io.ReadAll(telegramFile)
if err != nil {
    // handling error
}

inputFile := fmt.Sprintf("%s.mp4", msg.VideoNote.File.FileID)
err = ioutil.WriteFile(inputFile, fileBytes, 0o600)
if err != nil {
    // handling error
}

audio := bytes.NewBuffer(nil)
err = ffmpeg.Input(
    inputFile,
).
    Output("pipe:1", ffmpeg.KwArgs{"format": "wav"}).WithOutput(audio).Run()
if err != nil {
    // handling error
}

I am sending io.Reader(telegramFile var) and get io.Reader(audio var):

telegramFile, err := r.bot.GetFile(&msg.VideoNote.File)
if err != nil {
    // handling error
}

audio := bytes.NewBuffer(nil)
err = ffmpeg.Input(
    "pipe:0", ffmpeg.KwArgs{"format": "mp4"},
).
    Output("pipe:1", ffmpeg.KwArgs{"format": "wav"}).WithInput(telegramFile).WithOutput(audio).Run()
if err != nil {
    // handling error
}

the first code works, but I need the second one. The conversion is performed, but the audio is invalid. Too few bytes.

here is an example of using input -> output

err := out.WithInput(inBuf).WithOutput(outBuf).Run()

Using a specific ffmpeg binary

Hello,

I'm trying to use the library with a statically compiled ffmpeg binary that does not appear in the system PATH and is not guaranteed to have the exact name "ffmpeg" (although the name (and path) is known at runtime via a string variable).

Is there any possibility of choosing which binary is being used by ffmpeg-go?

Suppress compiled command

ffmpeg-go/run.go

Lines 252 to 269 in f39088d

func (s *Stream) Compile(options ...CompilationOption) *exec.Cmd {
args := s.GetArgs()
cmd := exec.CommandContext(s.Context, "ffmpeg", args...)
if a, ok := s.Context.Value("Stdin").(io.Reader); ok {
cmd.Stdin = a
}
if a, ok := s.Context.Value("Stdout").(io.Writer); ok {
cmd.Stdout = a
}
if a, ok := s.Context.Value("Stderr").(io.Writer); ok {
cmd.Stderr = a
}
for _, option := range options {
option(s, cmd)
}
log.Printf("compiled command: ffmpeg %s\n", strings.Join(args, " "))
return cmd
}

Is there a version of this that would suppress "compiled command" log?

Document the interface to FFmpeg

Hey there,

How exactly does this library interface with FFmpeg? Does it run a CLI binary? Does it use CGo to link to libffmpeg?

Might be something to put into the README.md, as it has a rather big impact on build- and run-time requirements of the application that uses ffmpeg-go.

Thanks for any info!

Audio missing on adding a watermark to the video

tried to add watermark by using the sample code given in the document, watermark is being added but the output video is missing the audio

overlay := ffmpeg.Input("watermark.png").Filter("scale", ffmpeg.Args{"100:100"})
	err := ffmpeg.Filter(
		[]*ffmpeg.Stream{
			ffmpeg.Input("v3.mp4"),
			overlay,
		}, "overlay", ffmpeg.Args{"10:10"}, ffmpeg.KwArgs{"enable": "gte(t,1)"}).
		Output("./out1.mp4").OverWriteOutput().ErrorToStdOut().Run()
	if err != nil {
		println("error watermark", err.Error())
	}

Audio Visualization filter problem

I’m trying to translate the following command line which works.
Merging mp4 and mp3 and adding audio visualization.

ffmpeg -stream_loop -1 -i cassette-edit.mp4 -i test-audio.mp3 -filter_complex "[1:a]showwaves=s=720x700:mode=line:colors=black[vwave];[0:v][vwave]overlay=format=auto[out]" -shortest -map "[out]" -pix_fmt yuv420p -map 1:a 'Cassette Dreams - w visualizer.mp4' -y

When trying to convert using ffmpeg-go, I'm losing hair

func MergeAudioWithVideoAndVisualizer(renderedVideo string, track_path string, videoOutput string,
	filter_complex string) error {
  in1 := ffmpeg.Input(renderedVideo, ffmpeg.KwArgs{"stream_loop": -1}).Video()
  in2 := ffmpeg.Input(track_path, ffmpeg.KwArgs{}).Audio().Filter("showwaves", ffmpeg.Args{
		"s=720x700",
		"mode=line",
		"colors=black",
	}).Overlay(in1, "", ffmpeg.KwArgs{"format": "auto"})
  
  err := ffmpeg.Output(
     []*ffmpeg.Stream{in1, in2},
     videoOutput,
     ffmpeg.KwArgs{
        "shortest": "",
        "map":      "1:a",
        "pix_fmt":  "yuv420p",
     }).OverWriteOutput().ErrorToStdOut().Run()
  return err
}

Here is the compiled command
ffmpeg -stream_loop -1 -i cassette-edit.mp4 -i test-audio.mp3 -filter_complex [1:a]showwaves=s=720x700:mode=line:colors=black[s0];[s0][0:v]overlay=eof_action=repeat:format=auto[s1] -map 0:v -map [s1] -map 1:a -pix_fmt yuv420p -shortest Cassette_Dreams_w_visualizer.mp4 -y

This results in a video with audio but no visualization

I've tracked it down to 2 things

  • the reorder of [vwave];[0:v][vwave]overlay to [s0];[s0][0:v]overlay
    • If i attempt to make the compiled command work, I end up switching to [s0];[0:v][s0]overlay
  • the adding of -map [0:v]
    • How do I omit this

I'm not very knowledgable in ffmpeg so I'm not sure how to re-use the library functions to get what I want.

no sound. when i use, how i get the sound

overlay := ffmpeg.Input("./123.png")
err := ffmpeg.Filter(
	[]*ffmpeg.Stream{
		ffmpeg.Input("./1.mp4"),
		overlay,
	}, "overlay", ffmpeg.Args{"0:0"}).
	Output("./2.mp4").OverWriteOutput().ErrorToStdOut().Run()

if err != nil {
	log.Println(err)
}

The data of the video file transmitted through MultipartFile cannot be passed in through the pipe, and an error is reported as invalid input, and then it is changed to a local file and then transferred to the buff when outputting.

The data of the video file transmitted through MultipartFile cannot be passed in through the pipeline, and an error is reported as invalid input, then it is converted to a local file, and it is converted to buff when outputting. In this way, the call can be completed, but after the buff is input, the parameters of the video cannot be obtained. such as playback time

pipeline:
newByte := new(bytes.Buffer)
err = ffmpeg.Input("pipe:",ffmpeg.KwArgs{}).
Output("pipe:", ffmpeg.KwArgs{"c:v": "copy", "f": "flv"}).
OverWriteOutput().
WithInput(reader).
WithOutput(newByte, os.Stdout).
Run()
local:
newByte := new(bytes.Buffer)
err := ffmpeg.Input(Name,ffmpeg.KwArgs{}).
Output("pipe:", ffmpeg.KwArgs{"c:v": "copy", "f": "flv"}).
WithOutput(newByte, os.Stdout).
Run()

"pipe:" Picture size 0x0 is invalid pipe:0: Invalid argument

I use http in the background to get the file and input pipe: call WithInput to convert io processing into io stream output and report an error

code:
reader, err := header.Open()
if err != nil {
return
}
err = ffmpeg.Input("pipe:").WithInput(reader).
Overlay(ffmpeg.Input("./logo/logo.png"), "").
Output("lucene.m3u8", ffmpeg.KwArgs{"c:v": "libx265", "hls_time": "12", "hls_list_size": "0", "hls_segment_filename": "file%d.ts"}).
ErrorToStdOut().
OverWriteOutput().
Run()
log.Println("ffmpeg process1 done")
if err != nil {
panic(err)
}

KwArgs with multiple `-map` arguments

Hi, great library!

I'm trying to figure out how/whether multiple -map arguments are supported. E.g., in order to add artwork to a file, I'd do

ffmpeg -i "input_file.mp4" -i "Input_file.jpg" --map 1 -map 0  -acodec copy -vcodec copy "output_file.mp4"

(source: https://stackoverflow.com/a/53950948/4453524). However, KwArgs obviously complains that I use the -map key twice. Is there something I'm overlooking?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.