Add two commands in ffmpeg - ffmpeg

I am using two commands, one to set size of frames and other to add water mark to left top corner
This command set size of frames to 720*1280
String[] complexCommandOne = {"-y" ,"-i", path,"-strict","experimental", "-vf", "scale=720:1280","-preset", "ultrafast", output};
Below command add watermark to above output file
String[] complexCommandTwo = {"-y" ,"-i", output,"-strict","experimental", "-vf", "movie="+pngpath+" [watermark]; [in][watermark] overlay=x=10:y=10 [out]","-s", "720x1280","-r", "30", "-b", "15496k", "-vcodec", "mpeg4","-ab", "48000", "-ac", "2", "-ar", "22050","-preset", "ultrafast", fileName};
Both these commands take 3-5 minutes on 20 seconds video
I want to merge these so that time can be reduced.
Any help. I am new i Ffgmeg

Never seen such thing, but looks like it basically just using regular FFmpeg CLI syntax.
So it would be this, I guess:
{"-y", "-i", input, "-strict", "experimental", "-vf", "movie="+pngpath+" [watermark]; [in] scale=720:1280 [scaled]; [scaled][watermark] overlay=x=10:y=10 [out]", "-s", "720x1280", "-r:v", "30", "-b:v", "15496k", "-c:v", "mpeg4", "-b:a", "48000", "-ac", "2", "-r:a", "22050", "-preset:v", "ultrafast", fileName}
which woud normally look like this:
ffmpeg -y -i INPUTFILE -strict experimental -vf "movie=LOGOFILE [watermark]; [in] scale=720:1280 [scaled]; [scaled][watermark] overlay=x=10:y=10 [out]" -s 720x1280 -r:v 30 -b:v 15496k -c:v mpeg4 -b:a 48000 -ac 2 -r:a 22050 -preset:v ultrafast OUTPUTFILE
What FFmpeg version do you have?
Because over 3.0 you can omit "-strict", "experimental" (it was needed to enable FFmpeg's own AAC audio codec when it was still considered as an experimental feature).

Related

ffmpeg xfade for (complex filter or select filter)

I need to trim and merge the video into one. I need to implement a cross fade or any smooth transitioning between each cut. Can I implement and how to implement the xfade or other ffmpeg smooth transition?
I did read this from multiple source.
Merging multiple video files with ffmpeg and xfade filter
But I still fail to generate a working code
Below is the example command and video section that I need to trim
ffmpeg -y -i example.mp4 -filter_complex
"[0:v]trim=start=0.1:end=0.7333333333333333,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=1.2333333333333334:end=4.8,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=4.966666666666667:end=10.466666666666667,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=10.6:end=13.066666666666666,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=13.733333333333333:end=17.333333333333332,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=39.9:end=40.56666666666667,setpts=PTS-STARTPTS[v0];
[0:a]atrim=start=0.1:end=0.7333333333333333,asetpts=PTS-STARTPTS[a0];
[0:a]atrim=start=1.2333333333333334:end=4.8,asetpts=PTS-STARTPTS[a1];
[0:a]atrim=start=4.966666666666667:end=10.466666666666667,asetpts=PTS-STARTPTS[a2];
[0:a]atrim=start=10.6:end=13.066666666666666,asetpts=PTS-STARTPTS[a3];
[0:a]atrim=start=13.733333333333333:end=17.333333333333332,asetpts=PTS-STARTPTS[a4];
[0:a]atrim=start=39.9:end=40.56666666666667,asetpts=PTS-STARTPTS[a5];
[v0] [a0] [v1] [a1] [v2] [a2] [v3] [a3] [v4] [a4] [v5] [a5] [a0] [a1] [a2] [a3] [a4] [a5]concat=n=6:v=1:a=1 [out]"
-map "[out]" example_COMPLEX.mp4
I generate this script file with xfade effect
ffmpeg -y -i example.mp4 -filter_complex
"[0:v]trim=start=0.1:end=0.7333333333333333,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=1.2333333333333334:end=4.8,setpts=PTS-STARTPTS[v1];
[0:v]trim=start=4.966666666666667:end=10.466666666666667,setpts=PTS-STARTPTS[v2];
[0:v]trim=start=10.6:end=13.066666666666666,setpts=PTS-STARTPTS[v3];
[0:v]trim=start=13.733333333333333:end=17.333333333333332,setpts=PTS-STARTPTS[v4];
[0:v]trim=start=39.9:end=40.56666666666667,setpts=PTS-STARTPTS[v5];
[0:a]atrim=start=0.1:end=0.7333333333333333,asetpts=PTS-STARTPTS[a0];
[0:a]atrim=start=1.2333333333333334:end=4.8,asetpts=PTS-STARTPTS[a1];
[0:a]atrim=start=4.966666666666667:end=10.466666666666667,asetpts=PTS-STARTPTS[a2];
[0:a]atrim=start=10.6:end=13.066666666666666,asetpts=PTS-STARTPTS[a3];
[0:a]atrim=start=13.733333333333333:end=17.333333333333332,asetpts=PTS-STARTPTS[a4];
[0:a]atrim=start=39.9:end=40.56666666666667,asetpts=PTS-STARTPTS[a5];
[v0][v1]xfade=transition=fade:duration=0.5:offset=8.2[x1];
[x1][v2]xfade=transition=fade:duration=0.5:offset=8.2[x2];
[x2][v3]xfade=transition=fade:duration=0.5:offset=10.166666666666666[x3];
[x3][v4]xfade=transition=fade:duration=0.5:offset=13.266666666666666[x4];
[x4][v5]xfade=transition=fade:duration=0.5:offset=13.433333333333337,format=yuv420p[video];
[a0] [a1] [a2] [a3] [a4] [a5]concat=n=6:v=1:a=1 [out]"
-map "[video]" -map "[out]" example_COMPLEX.mp4
But there is an error message
[Parsed_asetpts_13 # 0000014db55ea140] Media type mismatch between the 'Parsed_asetpts_13' filter output pad 0 (audio) and the 'Parsed_concat_30' filter input pad 0 (video)
[AVFilterGraph # 0000014db5414580] Cannot create the link asetpts:0 -> concat:0
Error initializing complex filters.
Invalid argument

Can I have a rawvideo stream in a MPEG TS container

I receive an MPEG TS container over network (UDP). It contains two streams: an mpeg2video vidoe stream with yuv420p pixel format and a data stream encoded using a propitiatory KLV format.
My receiver program must be in Python. So, I can't use FFMPEG library (like AVFormat, AVCodec) directly.
Now my problem is as follows:
I need to receive video frames and save them as RGB image as raw numpy array. I also need for each frame to parse the corresponding KLV data. There is a one to one relationship between video frames and KLV data units.
I thought I use ffprobe to output the packets including their payload data from incoming container and then parse the output of ffprobe to get the images and metadata:
$ ffprobe -show_packets -show_data -print_format json udp://127.0.0.1:12345 > test_video.packets.data.json
This gives me an output (in test_video.packets.data.json file) like:
{
"codec_type": "video",
"stream_index": 0,
"pts": 140400,
"pts_time": "1.560000",
"dts": 136800,
"dts_time": "1.520000",
"duration": 3600,
"duration_time": "0.040000",
"size": "21301",
"pos": "3788012",
"flags": "K_",
"side_data_list": [
{
"side_data_type": "MPEGTS Stream ID"
}
],
"data": "... "
},
{
"codec_type": "data",
"stream_index": 1,
"pts": 140400,
"pts_time": "1.560000",
"dts": 140400,
"dts_time": "1.560000",
"size": "850",
"pos": "3817904",
"flags": "K_",
"side_data_list": [
{
"side_data_type": "MPEGTS Stream ID"
}
],
"data": ".... "
}
I can extract the KLV data from the data packets and parse it. However the data from the video packets in encoded as mpeg2video video with yuv420p pixel format.
My Questions:
How can I get the raw pixel values from that mpeg2 encoded payload?
Is it possible to use ffmpeg to receive the original container and copy it (with both streams) into a new container, but with raw video instead of mpeg2 video? if yes, how? what should be the command? I tried for example: ffmpeg -i udp://127.0.0.1:12345 -map 0:0 -codec rawvideo -pix_fmt rgb24 -map 0:1 -codec copy -f mpegts udp://127.0.0.1:11112, but it gives me again mpeg2 encoded video data in payload of video packets
MPEG-TS supports a limited number of video codecs. However, ffmpeg's muxer will silently mux even unsupported streams as private data streams.
To mux a raw RGB stream, convert to rgb24 pixel format and code using rawvideo codec.
ffmpeg -i udp://127.0.0.1:12345 -map 0:0 -map 0:1 -c copy -c:v rawvideo -pix_fmt rgb24 -f mpegts udp://127.0.0.1:11112

batch convert videos to gifs in ffmpeg [duplicate]

I'm trying to batch concat a outro video to multiple videos.
I am just tetsing it using the following command:
ffmpeg -i test.mp4 -i hello.mp4 -filter comp
lex “[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]” -map “[v]” -map “[a]” outpu
t_video.mp4
However I get the following Error:
[NULL # 04fc2c00] Unable to find a suitable output format for '[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]'
[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]: Invalid argument
Change -filter complex to -filter_complex
Replace the “smart / fancy” quotes with normal double quotes (").

ffmpeg.js filter command without quotes

I want to use a filter in an ffmpeg version compiled for Javascript (ffmpeg.js). But the parser doesn't seem to handle quotes, so I need to write the full command without quotes.
How can I write the following command without quotes?
ffmpeg -i video.mp4 -i image.jpg -filter_complex "[1][0]scale2ref[i][v];[v][i]overlay=10:10:enable=\'between(t,1,2)\'" -c:a copy output.mp4
In javascript I specify the command as follows:
worker.postMessage({
type: 'command',
arguments: "-i video.mp4 -i image.jpg -filter_complex '[1][0]scale2ref[i][v];[v][i]overlay=10:10' -c:a copy output.mp4".split(' '),
files: [
{
data: new Uint8Array(videofile),
name: 'video.mp4'
},
{
data: new Uint8Array(imagefile),
name: 'image.jpg'
},
]
});
Which however results in:
[AVFilterGraph # 0xdf4c30] No such filter:
'[1][0]scale2ref[i][v];[v][i]overlay=10:10'
I checked and the overlay filter works in simpler version without quotes, for example this command works:
arguments: "-i video.mp4 -i image.jpg -filter_complex overlay=10:10 -c:a copy output.mp4".split(' '),
I think the problem is that the ' will still be around after the split which makes ffmpeg confused. If this was a real shell the argument parser would split and parse the quotes properly.
Try to remove the ' in the original string like this:
arguments: "-i video.mp4 -i image.jpg -filter_complex [1][0]scale2ref[i][v];[v][i]overlay=10:10 -c:a copy output.mp4".split(' ')
Or maybe even skip doing split and pass a list of arguments directly instead:
arguments: ["-i", "video.mp4", "-i", "image.jpg", "-filter_complex", "[1][0]scale2ref[i][v];[v][i]overlay=10:10", "-c:a", "copy", "output.mp4"]

Running FFMPEG command through Golang exec

I need to run an ffmpeg command to create a video from images with a crossfade between images as the transition. The command is derived from this post. I need to run it through the Golang os/exec package. The command I need to run is:
ffmpeg -loop 1 -t 5 -i img-0.png -loop 1 -t 5 -i img-1.png -loop 1 -t 5 -i img-2.png -filter_complex "[1:v][0:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b1v];[2:v][1:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b2v];[0:v][b1v][1:v][b2v][2:v]concat=n=5:v=1:a=0,format=yuv420p[v]" -map '[v]' -c:v libx264 -pix_fmt yuv420p -r 30 -s 1280x720 -aspect 16:9 -crf 1 -preset ultrafast output.mp4
If you run this command directly in the terminal, it works just fine. However, it does not work through my code. This is my code that takes a string command and runs it through the os/exec package:
command := "ffmpeg -loop 1 -t 5 -i img-0.png -loop 1 -t 5 -i img-1.png -loop 1 -t 5 -i img-2.png -filter_complex "[1:v][0:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b1v];[2:v][1:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b2v];[0:v][b1v][1:v][b2v][2:v]concat=n=5:v=1:a=0,format=yuv420p[v]" -map '[v]' -c:v libx264 -pix_fmt yuv420p -r 30 -s 1280x720 -aspect 16:9 -crf 1 -preset ultrafast output.mp4"
lastQuote := rune(0)
f := func(c rune) bool {
switch {
case c == lastQuote:
lastQuote = rune(0)
return false
case lastQuote != rune(0):
return false
case unicode.In(c, unicode.Quotation_Mark):
lastQuote = c
return false
default:
return unicode.IsSpace(c)
}
}
parts := strings.FieldsFunc(command, f)
cmd := exec.Command(parts[0], parts[1:]...)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
return err
}
When I run this, I get the ffmpeg error: No such filter: '"', Error configuring filters. I know it has something to do with the quotes that HAVE to be in the video filters, but I have tried everything to get it to work and I can't figure it out.
Any help is greatly appreciated!
This actually does work correctly :
exec.Command("ffmpeg", "-loop", "1", "-t", "5", "-i", "img-0.png", "-loop", "1", "-t", "5", "-i", "img-1.png", "-loop", "1", "-t", "5", "-i", "img-2.png", "-filter_complex", "[1:v][0:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b1v];[2:v][1:v]blend=all_expr='A*(if(gte(T,0.5),1,T/0.5))+B*(1-(if(gte(T,0.5),1,T/0.5)))'[b2v];[0:v][b1v][1:v][b2v][2:v]concat=n=5:v=1:a=0,format=yuv420p[v]", "-map", "[v]", "-c:v", "libx264", "-pix_fmt", "yuv420p", "-r", "30", "-s", "1280x720", "-aspect", "16:9", "-crf", "1", "-preset", "ultrafast", "output.mp4")
Notice that I did remove start and end double quotes from the -filter_complex parameters and two single quotes from the -map parameters.
Did it by hand, though, not sure of a strings function that could do it automagically.

Resources