Differences in outcome between positioning of ss and t? - ffmpeg

What is the difference between
ffmpeg -y -ss 1 -i "test.MP4" -t 2 -c copy "test2.MP4"
and
ffmpeg -y -t 2 -i "test.MP4" -ss 1 -c copy "test2.MP4"
and
ffmpeg -y -ss 1 -t 2 -i "test.MP4" -c copy "test2.MP4"
and
ffmpeg -y -i "test.MP4" -ss 1 -t 2 -c copy "test2.MP4"

From the documentation on https://ffmpeg.org/ffmpeg.html:
-ss position (input/output)
When used as an input option (before -i), seeks in this input file to
position. [...] When used as an output option (before an output url),
decodes but discards input until the timestamps reach position.
and
-t duration (input/output)
When used as an input option (before -i), limit the duration of data
read from the input file. When used as an output option (before an
output url), stop writing the output after its duration reaches
duration.

Related

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.

Extract frames from video FFMPEG with frameskip and name it accordingly.\

I would like to extract every 5th frame from a video and rename it accordingly.
frame_0000.jpg
frame_0005.jpg
frame_0010.jpg
frame_0015.jpg
Are there any parameters in the ffmpeg command other than the framerate and FPS to do so. Current command generates output sequentially.
ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
Using a recent ffmpeg build, run
ffmpeg -i foo.avi -vf "setpts=N/TB,fps=1,select='not(mod(n\,5))',scale=WxH" -vsync 0 -frame_pts 1 -f image2 foo-%03d.jpeg

How to get the size of the first x minutes of a video using FFmpeg?

I would like to input a time range, and get the size in bytes of a video.
For example, if I would like to extract the first two minutes of a video, I would do:
ffmpeg -i in.mp4 -ss 0 -t 120 out.mp4
But I don't really want to extract it, I just want to fetch the size of it if I would have.
You would run, on Windows,
ffmpeg -i in.mov -ss 0 -t 120 -c copy -y -f mov NUL 2>&1 | grep -oP "(?<=Lsize=)\s*[0-9]+\w+" | sed s/\s//g
This remuxes two minutes of the source file and extracts the muxed size of the media.
For linux, replace NUL with /dev/null

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.

How to set a video's duration in FFMPEG?

How can I limit the video duration for a given video? For example, if we are uploading one video that should not exceed more than 5 minutes, I need a command in FFMPEG.
Use the -t option to specify a time limit:
`-t duration'
Restrict the transcoded/captured video sequence to the duration specified in seconds. hh:mm:ss[.xxx] syntax is also supported.
http://www.ffmpeg.org/ffmpeg.html
Just to elaborate a bit further for more detailed use and examples.
As Specified in the FFMpeg Docs
-t duration (input/output)
When used as an input option (before -i),
limit the duration of data read from the input file.
e.g. ffmpeg -t 5 -i input.mp3 testAsInput.mp3
Will stop writing automatically after 5 seconds
When used as an output option (before an output url),
stop writing the output after its duration reaches duration.
e.g. ffmpeg -i input.mp3 -t 5 testAsOutput.mp3
Will stop writing automatically after 5 seconds
Effectively, in this use case the result is the same. See below for a more extended use case.
-to position (input/output)
Stop writing the output or reading the input at position.
e.g. same as above but with to instead of t
duration or positionmust be a time duration specification, as specified in the ffmpeg-utils(1) manual.
[-][HH:]MM:SS[.m...] or [-]S+[.m...][s|ms|us]
-to and -t are mutually exclusive and -t has priority.
Example use as input option with multiple inputs
Note: -f pulse -i 1 is my system audio , -f pulse -i 2 is my micrphone input
Lets imagine I want to record both my microphone and speakers at the same time indefinetly.(until I force a stop with Ctrl+C)
I could use the amix filter for example.
ffmpeg \
-f pulse -i 1 \
-f pulse -i 2 \
-filter_complex "amix=inputs=2" \
testmix.mp3
Now lets imagine I only want to record the first 5 seconds of my system audio and always my microphone, again, until I kill the process with Ctrl+C).
ffmpeg \
-t 5 -f pulse -i 1 \
-f pulse -i 2 \
-filter_complex "amix=inputs=2:duration=longest" \
testmix.mp3
Note: :duration=longest amix option is the default anyway, so not really needed to specify explicitly
Now lets assume I want the same as above but limit the recording to 10 seconds. The following examples would satisfy that requirement:
ffmpeg \
-t 5 -f pulse -i 1 \
-t 10 -f pulse -i 2 \
-filter_complex "amix=inputs=2:duration=longest" \
testmix.mp3
ffmpeg \
-t 5 -f pulse -i 1 \
-f pulse -i 2 \
-filter_complex "amix=inputs=2:duration=longest" \
-t 10 testmix.mp3
Note: With regards to start position searching/seeking this answer with a bit of investigation I did, may also be of interest.
An example;
ffmpeg -f lavfi -i color=s=1920x1080 -loop 1 -i "input.png" -filter_complex "[1:v]scale=1920:-2[fg]; [0:v][fg]overlay=y=-'t*h*0.02'[v]" -map "[v]" -t 00:00:03 output.mp4
This sets the max time to 3 seconds. Note that the -t has to be just before the output file, if you set it at the start of this command, i.e. ffmpeg -t .... it will NOT work.

Resources