Is it possible to reduce ffmpeg commands in a single file pass? - ffmpeg

I need to add the logo and telephone number on video, therefore I run the following command twice with different parameters:
ffmpeg -i input.mp4 -i ./assets/logo.png -filter_complex "[1][0]scale2ref=w='iw*1/5':h='ow/mdar'[wm][vid];[vid][wm]overlay=main_w-overlay_w-5:5" 'uploads/output.mp4' 2>&1
ffmpeg -i ./uploads/output.mp4 -i ./assets/telephone.png -filter_complex "[1][0]scale2ref=w='iw*9/10':h='ow/mdar'[wm][vid];[vid][wm]overlay=10:main_h-overlay_h-10" './uploads/output2.mp4'
I'm looking to optimize speed, maybe is possible to have a single file pass instead of 2?
Thank you very much!
I tried
ffmpeg -i input.mp4 -i ./assets/logo.png -filter_complex "[1][0]scale2ref=w='iw*1/5':h='ow/mdar'[wm][vid];[vid][wm]overlay=main_w-overlay_w-5:5" -i ./assets/telephone.png -filter_complex "[1][0]scale2ref=w='iw*9/10':h='ow/mdar'[wm][vid];[vid][wm]overlay=10:main_h-overlay_h-10" './uploads/output2.mp4'
but does not add the telephone number.

I found a way:
ffmpeg -i uploads/input.mp4 -i ./assets/logo.png -i ./assets/telefon.png -filter_complex "[1][0]scale2ref=w='iw*1/5':h='ow/mdar'[v1];[2][0]scale2ref=w='iw*9/10':h='ow/mdar'[v2];[0][v1]overlay=main_w-overlay_w-5:5[vid];[vid][v2]overlay=10:main_h-overlay_h-10" uploads/output.mp4
BUT
if input file type is an image
ffmpeg -i uploads/input.png -i ./assets/logo.png -i ./assets/telefon.png -filter_complex "[1][0]scale2ref=w='iw*1/5':h='ow/mdar'[v1];[2][0]scale2ref=w='iw*9/10':h='ow/mdar'[v2];[0][v1]overlay=main_w-overlay_w-5:5[vid];[vid][v2]overlay=10:main_h-overlay_h-10" uploads/output%d.png
without %d in the output file name I get this error:
[image2 # 0x55fff1a6af80] Could not get frame filename number 2 from pattern 'uploads/output.png'. Use '-frames:v 1' for a single image, or '-update' option, or use a pattern such as %03d within the filename.
Error writing trailer of uploads/output.png: Invalid argument
Now I have 3 output files but a single file pass, could you please give me an ideea to have only one output image file?

Related

merge audio and video with ffmpeg doesnt work correctly

I have ubuntu 20.04 and in past days I did this job(merge video and audio) well in terminal and with ffmpeg:
ffmpeg -i input.mp4 -i input2.mp3 -c copy output.mp4
so fast I have recived output.mp4, but now I tried this one and get output without any sound!
I try another ways to merge this ones(also with ffmpeg) but there are no diffrent...
ffmpeg -f concat -safe 0 -i <(for f in ./input*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
Note -f concat will select a demuxer. This alters the way -i nput files are read.
So instead video-files 'concat expects a txt-file listing the files to concatenate.
However we somehow omit the creation of that text file and use process substitution to generate and pass that list on the fly to demux.
For more details go here:
https://trac.ffmpeg.org/wiki/Concatenate#demuxer
If you want to merge several video files, you can use these command.
merge two video files.
ffmpeg -f concat -i 1.mp4 -1 2.mp4 -codec copy out.mp4
merge multiple video files.
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mpt -vcodec copy -acodec copy out.mp4

Invalid data found when processing input | ffmpeg

I'm trying to concat multiple videos with ffmpeg, im using a text file as input but im getting "Files.txt: Invalid data found when processing input".
My command:
ffmpeg -i Files.txt -filter_complex "[0:v]fps=25,format=yuv420p,setpts=PTS-STARTPTS[v0];[0:a]aformat=sample_rates=44100:channel_layouts=stereo,asetpts=PTS-STARTPTS[a0];[1:v]fps=25,format=yuv420p,setpts=PTS-STARTPTS[v1];[1:a]aformat=sample_rates=44100:channel_layouts=stereo,asetpts=PTS-STARTPTS[a1];[v0][a0][v1][a1]concat=n=2:v=1:a=1" -movflags +faststart output.mp4
My text file:
file '1.mp4'
file '2.mp4'
Only the concat demuxer accepts a text file list
Either use the concat demuxer:
ffmpeg -f concat -i input.txt output.mp4
Or list the inputs normally and use the concat filter:
ffmpeg -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]fps=25,format=yuv420p,setpts=PTS-STARTPTS[v0];[0:a]aformat=sample_rates=44100:channel_layouts=stereo,asetpts=PTS-STARTPTS[a0];[1:v]fps=25,format=yuv420p,setpts=PTS-STARTPTS[v1];[1:a]aformat=sample_rates=44100:channel_layouts=stereo,asetpts=PTS-STARTPTS[a1];[v0][a0][v1][a1]concat=n=2:v=1:a=1" -movflags +faststart output.mp4
You can't use a text file listing inputs unless you use the concat demuxer as shown above, or if you use some capability in your shell to interpret the list as inputs. ffmpeg has no such feature.
It's likely that you have your file is encoded in a non UTF-8 encoding. Try to save the file in UTF-8 encoding.

Scale and overlay in single command

I want to convert and resize a video and put a logo on it. I am doing this with 2 different command line like this.
Command 1:
D:\Logo\ffmpeg -i "D:\Logo\video.mxf" -vf scale=1280:720 "D:\Logo\video.mxf_fullHDtoHD.mp4"
Command 2:
D:\Logo\ffmpeg -i "D:\Logo\video.mxf_fullHDtoHD.mp4" -i D:\Logo\logo_720p.png -filter_complex "[0:v][1:v] overlay=60:50" "D:\Logo\output_720p_with_logo.mp4"
Can I do this in just one command?
Combined command:
ffmpeg -i "D:\Logo\video.mxf" -i D:\Logo\logo_720p.png -filter_complex "[0:v]scale=1280:720[bg];[bg][1:v]overlay=60:50" "D:\Logo\output_720p_with_logo.mp4"

FFMPEG is trim and -t ignored for the PSNR filter?

I wanted to run a PSNR check on a encoded segment but avoid extracting the segment in a lossless codec first for comparsion. I just wanted to trim the input, however it looks like this is disabled.
My command:
ffmpeg -i original.mp4 -i segment.mp4 -filter_complex "[0:v]trim=10:20,setpts=PTS-STARTPTS[0v];[1:v]setpts=PTS-STARTPTS[1v];[0v][1v]psnr" -f null -
This will run through the whole original input file and not trim the video in the filter.
If I try to trim the input with -ss and -t, only the input -ss flag is working. It will set the input correct but ignore the -t timestamp.
ffmpeg -ss 10 -i original.mp4 -t 10 -i segment.mp4 -filter_complex [0:v][1:v]psnr -f null -
Different placement of the -t will have no effect.
I also tried to set the duration in trim while keeping the -ss input which is working.
ffmpeg -ss 10 -i original.mp4 -i segment.mp4 -filter_complex "[0:v]trim=duration=10,setpts=PTS-STARTPTS[0v];[1:v]setpts=PTS-STARTPTS[1v];[0v][1v]psnr" -f null -
I did try this with end and end_frame but neither one worked.
The same applies if I use -lavfi instead of -filter_complex.
I did have a brief look at the sourcecode of the PSNR filter but could not find any refrences to trim or -t.
Is this function blocked or am I doing something wrong?
Would there be an alternative way to doing this without encoding a lossless version of the same segment to compare?
The original command is almost fine. However, the order of inputs should be swapped, and if there's any audio, that should be disabled.
ffmpeg -i original.mp4 -i segment.mp4 -filter_complex "[0:v]trim=10:20,setpts=PTS-STARTPTS[0v];[1:v]setpts=PTS-STARTPTS[1v];[1v][0v]psnr" -an -f null -
Also, in the snippet below
ffmpeg -ss 10 -i original.mp4 -t 10 -i segment.mp4
if you meant to limit the duration of original.mp4, then -t 10 should be placed before -i original.mp4.

Is it possible to create a ”timeline” using FFMPEG?

I know it’s possible to get a part of a file using the command:
ffmpeg -ss 00:02:00.000 -i input.mp4" -t 00:00:05.000 out.mp4
But is it possible to combine multiple videos with text and other effects?
I want to create a output from the following
File1.mp4:
Read from 00:02:00.000 to 00:02:05.000
File2.mp4
Read from 00:00:00.000 to 00:01:30.000
Insert overlay image “logo.png” for 20 seconds
File3.mp4
Insert the whole file
Insert text from 00:00:10.000 to 00:00:30.000
It can be done with FFmpeg, but it isn't really an 'editor' so the command will get long, unwieldy and prone to execution errors the more the number of input clips and effects you apply.
That said, one way to do this is using the concat filter.
ffmpeg -i file1.mp4 -i file2.mp4 -i file3.mp4 -loop 1 -t 20 -i logo.png \
-filter_complex "[0:v]trim=120:125,setpts=PTS-STARTPTS[v1];
[1:v]trim=duration=90,setpts=PTS-STARTPTS[vt2];
[vt2][3:v]overlay=eof_action=pass[v2];
[2:v]drawtext=enable='between(t,10,30)':fontfile=font.ttf:text='Hello World'[v3];
[0:a]atrim=120:125,asetpts=PTS-STARTPTS[a1];
[1:a]trim=duration=90,setpts=PTS-STARTPTS[a2];
[v1][a1][v2][a2][v3][2:a]concat=n=3:v=1:a=1[v][a]" -map "[v]" -map "[a]" output.mp4
I haven't specified any encoding parameters like codec or bitrate..etc. Assuming you're familiar with those. Also, haven't specified arguments for overlay or drawtext like position..etc. Consult the documentation for a guide to those.

Resources