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

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.

Related

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

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?

FFmpeg command to trim lavfi ignores start

Why doesn't this ffmpeg command generate 1 second video, but 5 seconds?
If I modify end parameter of trim filter, the length changes, but it looks like ffmpeg is ignoring the start parameter.
ffmpeg -f lavfi -i color=blue#1:640x480:d=60,format=rgba -filter_complex "[0]trim=start=4.0:end=5.0[s0]" -map "[s0]" -y trim.mp4
The output is correct. However, since timestamps aren't reset to start from zero, most apps will compute duration values based on the final timestamp value, and may even show a 'freeze' or black till the first timestamp.
Reset timestamp by using the setpts filter.
ffmpeg -f lavfi -i color=blue#1:640x480:d=60,format=rgba -filter_complex "[0]trim=start=4.0:end=5.0,setpts=PTS-STARTPTS[s0]" -map "[s0]" -y trim.mp4

How to apply any mask.png on a video with ffmpeg

I am adding a 1.mp4 on a video 2.mp4, and i want to add a mask on overlay video(1.mp4)
I want to apply this mask on 1.mp4
I'm using chrome key right now
ffmpeg -t 5 -r 30 -f lavfi -i color=c=black:s=640x360
-i 1.mp4
-i mask2.png
-i 2.mp4
-filter_complex "
[1:v]scale=500x281[v1];
[2]scale=500x281[mask];
[v1][mask]overlay, chromakey=0x00FF00:0.25:0.08 [v2];
[3:v]scale=640x360[v3];
[0][v3]overlay [out1];
[out1][v2]overlay=0:0"
-y output.mp4
But it also removes color from videos.
I'm not sure but i think it can be done by negate
also i don't need audio command, i already done that part
Thanks

ffmpeg -ss then apply filter then concat producing timestamp errors

Using ffmpeg, I have split a file into multiple parts using -ss. Then I apply a filter to some of the files, then concat the files back together. When I do that, I get: Non-monotonous DTS in output stream 0:0; previous: 341334, current: 340526; changing to 341335. This may result in incorrect timestamps in the output file. The output file plays, but there are noticeable skips where the files are joined.
Here's how I am splitting the file:
ffmpeg -i full_source.mp4 -ss 0 -to 14.264250 -c copy 01-plain.mp4
ffmpeg -i full_source.mp4 -ss 14.264250 -to 18.435083 -c copy 01-filtered.mp4
ffmpeg -i full_source.mp4 -ss 18.435083 -to 29.988292 -c copy 02-plain.mp4
ffmpeg -i full_source.mp4 -ss 29.988292 -to 31.865167 -c copy 02-filtered.mp4
...
ffmpeg -i full_source.mp4 -ss 0 -to 14.264250 -c copy 10-plain.mp4
ffmpeg -i full_source.mp4 -ss 234.484203 -to 300.000 -c copy 10-filtered.mp4
Then I apply a different drawtext filter on each of the 10 filtered files and save them with a new name, like:
ffmpeg -hide_banner -loglevel warning -y -i 01-filtered.mp4 -filter_complex "drawtext=fontfile=calibri.ttf:fontsize=24:fontcolor=white:x=300:y=500:text='hello world'" -crf 15 01-filtered-complete.mp4
Finally, I join all of the plain and complete files back together like this:
ffmpeg -f concat -safe 0 -i mylist.txt -c:a copy -c:v copy outfile.mp4
And that's where the timing error comes in. I've tried adding -vsync drop in the concat command, but that didn't really work either. Same version of ffmpeg does the split, the filter, and the concat. I've tried different versions, everything from 20170519 to one from May 2020 with the same result. Always making sure that all three steps are done by the same version of ffmpeg.
The only thing I can see is that ffprobe shows a duration of 14.27 for 01-plain.mp4 when it should be 14.264250. All of the other files show a similar rounding difference. The files are 23.98 fps. If I do all of my filters in really long command without splitting the file, I can use the more precise numbers with no problem. It just takes 10 times as long. This is all scripted, it happens a couple of hundred times a day and time is money, so I can't take 10 times as long to do each file.
Any ideas? Thanks in advance!

ffmpeg silencedetect -ss argument

I need to detect silence in a part of a sound file
ffmpeg -i 3.mp3 -ss 00:22:00 -to 00:23:30 -af "silencedetect=noise=-18dB:d=0.15,ametadata=mode=print:file=vol.txt" -f null -
This code detects silence from the beginning of the file to the value of -to.
Is it possible to print only lavfi.silence_end and lavfi.silence_start? How to pass it to
"silencedetect=noise=-18dB:d=0.15,ametadata=mode=print:file=vol.txt"
Use the select filter instead:
ffmpeg -i 3.mp3 -af "aselect='between(t,1320,1410)',silencedetect=noise=-18dB:d=0.15,ametadata=mode=print:file=vol.txt" -f null -

Resources