Instead of using
-to seeking parameters, which seem not very accurate, can I cut videos for given frame numbers?
ffmpeg -i video.webm -startingframe 80 -endingframe 560 output.webm
[80th frame and 560th frame included. So, as total it makes (560 - 80 +1) frames]
After the answers and a bit search, I have tried some commands. But so far I couldn't find an acceptable way.
If someone wants to cut video stream between 250th and 750th frames, this is the way to go. It will give 501 frames as output:
Note: movie.mp4 has 25 fps, and its audio sample rate 48k
ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm
As expected, the output is 20 seconds long, exactly.
Using the same method for audio:
ffmpeg -i movie.mp4 -vn -af "aselect=between(n\,480\,1440),setpts=PTS-STARTPTS" a_stream.webm
Unexpectedly, this one has very poor accuracy. It should have given me 960001 (960k+1) samples which equal 20 seconds audio. But instead, the output was 20.505 seconds long and has 984240 samples. Also, if I increase the duration, error increases as well.
Then I tried to use -ss -to parameters for cutting audio stream:
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm
The old classic way works much better. Output was 20.003 seconds long and has 960144 samples. Plus, increasing duration does not increase the error, the error is constant, there is always 144 samples surplus with that input file.
select filter works well most of the time but a select is not. The classic
-ss parameters work better for audio but not sample-accurate. Also, it is not possible to use
-vf select and
-ss parameters together, because
-ss will affect both audio and video streams while we want it only affect audio.
So, to precisely cut a media file I have to do these 3 steps:
ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm ffmpeg -i v_stream.webm -i a_stream.webm -c:v copy -c:a copy movie-between_10th_and 20th_seconds.webm
This gives the most accurate results.
Video is 20.000 seconds long and frame-acurate
Audio is 20.003 seconds long and has 960144 sample. Not exactly matches with the video stream, but it is OK. There is only 144 samples surplus.
The biggest downside is, whenever I want to cut a file, I have to send 3 commands for a simple job and it creates two unnecessary files: a_stream.webm and v_stream.webm. And the
select filter is not working on some input files I have tried. It does the job successfully (?) but never stops the encoding process, so I have to close command prompt every time.