ffmpeg silencedetect -ss argument - ffmpeg

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 -

Related

add current video time with ffmpeg

I can add frame number to video with ffmpeg as below:
ffmpeg -y -i input.mp4 -an -vf drawtext=fontsize=36:fontcolor=yellow:text='%{frame_num}':x=20:y=20 -f mp4 output.mp4
How can I modify it to show HH:MM:SS instead of current frame number?
As #kesh pointed out pts:hms instead of frame_num does the job but your specific command line, will lead you astray, as you have omitted a set of encapsulating quotes.
Whilst omitting them, works with frame_num, it will not work with pts:hms
Use:
ffmpeg -y -i input.mp4 -an -vf "drawtext=fontsize=36:fontcolor=yellow:text='%{pts\:hms}':x=20:y=20" -f mp4 output.mp4
Here the entire drawtext filter is wrapped in quotation marks.
Edit:
To achieve pure HH:MM:SS format use gmtime rather than hms i.e.
ffmpeg -y -i input.mp4 -an -vf "drawtext=fontsize=36:fontcolor=yellow:text=' %{pts\:gmtime\:0\:%T}':x=20:y=20" -f mp4 output.mp4

Extract LUFS only from multiple file

ffmpeg -i input.mp4 -af ebur128=framelog=verbose -f null - 2>&1 | awk '/I:/{print $2}'
The above command extract only LUFS value from input.mp4 file. But If there are number of mp4 files, how to apply similar command to extract LUFS value only from multiple mp4 files?
Please help.
Adapting this answer from How do you convert an entire directory with ffmpeg?
for i in *.mp4; do echo "$i:"; ffmpeg -i "$i" -map 0:a -af ebur128=framelog=verbose -f null - 2>&1 | awk '/I:/{print $2}'; done
Example output:
video1.mp4:
-21.8
video2.mp4:
-21.1
video3.mp4:
-21.8
-8.3
Note that video3.mp4 contains 2 separate audio streams.
This is assuming you can use Bash shell.
-map 0:a was added to only process the audio so the video is ignored and therefore the command is faster. See FFmpeg Wiki: Map.

ffmpeg cut the video and output the audio additionally

I can cut and output a video with:
ffmpeg -y -ss 00:00:05 -t 240 -i input.mov -to 10 -qscale 0 > output.mov
Also I can additionally output the audio of the input file by adding output_audio.wav at the end like:
ffmpeg -y -ss 00:00:05 -t 240 -i input.mov -to 10 -qscale 0 output.mov output_audio.wav
BUT:
The video output is trimmed to the segment specified in the command. But the audio output contains the entire input video.
Is it possible to additionally output the audio of JUST the segment defined within the command-line?
ffmpeg -y -ss 00:00:05 -to 10 -i input.mov output.mov output_audio.wav
You can use -to as an input option. This will limit the input duration and therefore the outputs as well.
-qscale 0 is ignored by libx264.

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.

Reporting duplicated frames with FFmpeg

I am looking for a method to report (not just detect and remove) duplicated frames of video detected by FFmpeg - similar to how you can print out blackdetect, cropdetect, silencedetect, etc.
For example:
ffmpeg -i input.mp4 -vf blackdetect -an -f null - 2>&1 | grep blackdetect > output.txt
Outputs something like:
[blackdetect # 0x7f8032f03680] black_start:5.00501 black_end:7.00701 black_duration:2.002
But there's no "dupedetect" filter as far as I know, so I'm looking for any ideas/workarounds to get a read of where frames are duplicated.
Try -vp mpdecimate in the command line.
ffmpeg -i input.mp4 -vf mpdecimate -loglevel debug -an -f null - 2>&1 | grep 'drop_count:\d' > output.txt
Sample line of output:
[Parsed_mpdecimate_0 # 0x7fbbfa210380] lo:0<2653 lo:0<1326 lo:0<1326 drop pts:101101 pts_time:4.21254 drop_count:1

Resources