<p>According to @Gyan, the referenced command does an efficient job, and won't read through MP4s but use an index to jump to the inpoint. So there's no real need to optimize. </p>

CC BY-SA 4.0
2019-02-19T14:02:53.703Z
2019-02-19T14:02:53.703Z
John
<p>I've got a long video (2 hours at high resolution). We might as well assume it's in mp4 format, because it's in an AVCHD, and I'll have to extract and convert it to mp4 anyhow. </p>

<p>I'd like to extract from it about 40 clips, of varying lengths. I know the "start" and "stop" time for each. It might look like this:</p>

<pre><code>0:00:15 to 0:01:30 -&gt; clip1.mp4
0:01:55 to 0:03:10 -&gt; clip2.mp4
0:03:45 to 0:05:12 -&gt; clip2.mp4
 ... (many more lines)
1:55:45 to 1:57:11 -&gt; clip41.mp4
</code></pre>

<p>I can certainly write a script to extract each of these individually (via something like what's described <a href="https://video.stackexchange.com/questions/3274/what-is-a-good-efficient-way-to-isolate-clips-from-long-movies">here</a>), but that requires "reading through" the source forty times, which can be slow. Is there a way to get ffmpeg to do this in some sort of sequential fashion in a single pass? Or do I just resign myself to an overnight background process? </p>

CC BY-SA 4.0
2019-02-19T05:58:19.960Z
The referenced command does an efficient job, and won't read through MP4s but use an index to jump to the inpoint.
Gyan
CC BY-SA 4.0
2019-05-03T17:25:38.020Z
In my experience, using -ss, even with the newest versions of ffmpeg, does not give perfect frame accuracy. It gives frame accuracy 99% of the time, but that's not good enough in a production environment. The only thing that I've found to be perfectly accurate is ```
-vf select=between(n\,123\,456)
``` However, this has exactly the speed problem that you're trying to avoid.
Andrew Klaassen
CC BY-SA 4.0
2019-05-03T17:32:38.303Z
Can you share the command+file which doesn't give perfect accuracy?
Gyan
CC BY-SA 4.0
2019-05-03T17:41:41.290Z
Anything along the lines of "ffmpeg -ss <start> -i input.mp4 ....".  If you use "-vcodec copy", as in the link you suggested, you'll get cuts on keyframes, which can be a number of frames away from the frame you actually want to cut on.  Even if you re-encode, though, you'll often get off-by-one errors, presumably from floating point division mismatches.  Let's say you want to start at frame 23 of a 23.976fps movie.  Since -ss doesn't allow frame numbers, you'll have to specify something like "-ss 0.9592926259592927".  Sometimes that'll start you at frame 22 instead of frame 23.
Andrew Klaassen
CC BY-SA 4.0
2019-05-03T18:07:27.353Z
I made a change today morning that may improve seeking in MP4/MOVs. Try the latest builds.
Gyan
CC BY-SA 4.0
2019-05-03T18:24:53.367Z
@Gyan: Does it help with the problem that "-ss 0.9592926259592926" might start me at frame 22 while "-ss 0.9592926259592928" might start me at frame 23?  I.e., is there a way to seek to a specific frame rather than to a specific time, and not have to worry about floating point division mismatches?  Thanks.
Andrew Klaassen
CC BY-SA 4.0
2019-05-03T18:39:29.823Z
1) 23.976 is not the exact framerate, it's 24000/1001 2)The issue isn't with FP division (although in rare cases it may be) 3)Your video may not have frames exactly at the calculated timestamps either because of variable frame-rate or audio codec delay. 4)Timestamps are points, not regions - ffmpeg input ss will identify the packet *at* or *before* the argument, so once you calculate the exact timestamp, add a couple milliseconds to accommodate possible anomalies. There are still some cases, to do with multiple B-frames, where ffmpeg won't return the exact frame, but in other cases, it should.
Gyan
CC BY-SA 4.0
2019-05-03T18:41:57.183Z
Input ss iaccuracy s independent of whether streamcopying. However, further processing may be different whether output format supports negative timestamps and whether the consumer app can handle negative timestamps correctly.
Gyan
CC BY-SA 4.0
2019-05-03T18:49:57.483Z
Thanks for the correction on 23.976 vs. 24000/1001 - I hadn't realized the difference until you pointed it out, and perhaps that made a difference.  I did try a bunch of fudging - adding or subtracting a few milliseconds to the start time and the duration - but I was never able to achieve 100% frame accuracy with anything other than "select", and after a couple of weeks of trying everything I could I got very suspicious of any ffmpeg clip extraction methods which used seconds instead of frame numbers. :-)
Andrew Klaassen
CC BY-SA 4.0
2019-05-03T18:54:25.597Z
About the negative timestamps - unfortunately, I have to support a number of different processes after cutting the movie, some of which depend on software that seems to use old and flaky movie libraries.  That may have also contributed to my failures with -ss.
Andrew Klaassen
<video><ffmpeg>
(Efficiently) Extract multiple clips from a long video, possibly with ffmpeg
John
# (Efficiently) Extract multiple clips from a long video, possibly with ffmpeg

(Asked by: username_0 on 2019-02-18)

I've got a long video (2 hours at high resolution). We might as well assume it's in mp4 format, because it's in an AVCHD, and I'll have to extract and convert it to mp4 anyhow. 
I'd like to extract from it about 40 clips, of varying lengths. I know the "start" and "stop" time for each. It might look like this:
0:00:15 to 0:01:30 -> clip1.mp4
0:01:55 to 0:03:10 -> clip2.mp4
0:03:45 to 0:05:12 -> clip2.mp4
 ... (many more lines)
1:55:45 to 1:57:11 -> clip41.mp4

I can certainly write a script to extract each of these individually (via something like what's described here), but that requires "reading through" the source forty times, which can be slow. Is there a way to get ffmpeg to do this in some sort of sequential fashion in a single pass? Or do I just resign myself to an overnight background process?

**Tags:** video, ffmpeg

> **Comments:**
> **username_1**: The referenced command does an efficient job, and won't read through MP4s but use an index to jump to the inpoint.  
> **username_2**: In my experience, using -ss, even with the newest versions of ffmpeg, does not give perfect frame accuracy. It gives frame accuracy 99% of the time, but that's not good enough in a production environment. The only thing that I've found to be perfectly accurate is ``` -vf select=between(n\,123\,456) ``` However, this has exactly the speed problem that you're trying to avoid.  
> **username_1**: Can you share the command+file which doesn't give perfect accuracy?  
> **username_2**: Anything along the lines of "ffmpeg -ss <start> -i input.mp4 ....".  If you use "-vcodec copy", as in the link you suggested, you'll get cuts on keyframes, which can be a number of frames away from the frame you actually want to cut on.  Even if you re-encode, though, you'll often get off-by-one errors, presumably from floating point division mismatches.  Let's say you want to start at frame 23 of a 23.976fps movie.  Since -ss doesn't allow frame numbers, you'll have to specify something like "-ss 0.9592926259592927".  Sometimes that'll start you at frame 22 instead of frame 23.  
> **username_1**: I made a change today morning that may improve seeking in MP4/MOVs. Try the latest builds.  
> **username_2**: @username_1: Does it help with the problem that "-ss 0.9592926259592926" might start me at frame 22 while "-ss 0.9592926259592928" might start me at frame 23?  I.e., is there a way to seek to a specific frame rather than to a specific time, and not have to worry about floating point division mismatches?  Thanks.  
> **username_1**: 1) 23.976 is not the exact framerate, it's 24000/1001 2)The issue isn't with FP division (although in rare cases it may be) 3)Your video may not have frames exactly at the calculated timestamps either because of variable frame-rate or audio codec delay. 4)Timestamps are points, not regions - ffmpeg input ss will identify the packet *at* or *before* the argument, so once you calculate the exact timestamp, add a couple milliseconds to accommodate possible anomalies. There are still some cases, to do with multiple B-frames, where ffmpeg won't return the exact frame, but in other cases, it should.  
> **username_1**: Input ss iaccuracy s independent of whether streamcopying. However, further processing may be different whether output format supports negative timestamps and whether the consumer app can handle negative timestamps correctly.  
> **username_2**: Thanks for the correction on 23.976 vs. 24000/1001 - I hadn't realized the difference until you pointed it out, and perhaps that made a difference.  I did try a bunch of fudging - adding or subtracting a few milliseconds to the start time and the duration - but I was never able to achieve 100% frame accuracy with anything other than "select", and after a couple of weeks of trying everything I could I got very suspicious of any ffmpeg clip extraction methods which used seconds instead of frame numbers. :-)  
> **username_2**: About the negative timestamps - unfortunately, I have to support a number of different processes after cutting the movie, some of which depend on software that seems to use old and flaky movie libraries.  That may have also contributed to my failures with -ss.  

---

## 1 answers

### Answer by username_0 on 2019-02-19. Score: 1

According to @username_1, the referenced command does an efficient job, and won't read through MP4s but use an index to jump to the inpoint. So there's no real need to optimize.


---

