u2takey / ffmpeg-go Goto Github PK
View Code? Open in Web Editor NEWgolang binding for ffmpeg
License: Apache License 2.0
golang binding for ffmpeg
License: Apache License 2.0
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()
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 😄
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)
}
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()
where is github.com/u2takey/go-utils/sets
i can not find them
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)
}
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())
}
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!
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
as ffmpeg i 1.jpg i 2.jpg -filter_comple ''''' 【1:v】?how to use????
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.
@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
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?
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
for ffmpeg are lgpl license
ffmpeg binary cli tool may not be distributed. However shared lib are legal.
could build ffmpeg main() as a share lib.
this tool link those libs
it is very useful for client
Hi.
Does the library support TTS, can I convert text to audio file?
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)
}
cannot use go get.
the error:
go: golang.org/x/[email protected]: invalid version: unknown revision 33a8303e98df
I want to get output(stdout,stderr) from a log file
I need to to have two inputs in order to manipulate audio and video as shown in the first example here https://newbedev.com/adding-silent-audio-in-ffmpeg . Right now there is only one input per ffmpeg command. Could this be added?
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?
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()
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:
Lines 28 to 36 in 8af5c38
One solution would be setting somewhere the previous stream context to the next stream that output returns.
Maybe by doing it here?
Lines 81 to 91 in 8af5c38
It happens on github.com/u2takey/ffmpeg-go v0.4.1
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!
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(???????)
}
Please change "ffmepg" to "ffmpeg".
Lines 252 to 269 in f39088d
Is there a version of this that would suppress "compiled command" log?
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.
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.
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
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?
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()
`
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.
Hi.
How to add -movflags +faststart -c:a copy
flags to ffmpeg compiled command?
Thanks
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?
I want to read image from s3 and convert it.
Is there way to pass []byte
to Input
func?
pls print out the command line of ffmpeg which will be executed.
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
[vwave];[0:v][vwave]overlay
to [s0];[s0][0:v]overlay
[s0];[0:v][s0]overlay
I'm not very knowledgable in ffmpeg so I'm not sure how to re-use the library functions to get what I want.
Transcoding From One Codec To Another example.
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
Line 330 in 8af5c38
Either as a string
or as a version struct, that would be a nice little addition.
It would also allow programs to check if the ffmpeg
binary is there or not.
The labels are lexically sorted so the conversion from int to string should contain a left pad otherwise when the labels get sorted, it goes 0, 1, 10, 11, 12, ... , 2, 3, 4, ... :
Line 204 in 8af5c38
I would recommend changing this from %v
to %02d
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.