Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-02-19T14:02:53.703Z
Answers.LastActivityDate: 2019-02-19T14:02:53.703Z
Answers.UserDisplayName: John
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-02-19T05:58:19.960Z
Comments.Text: The referenced command does an efficient job, and won't read through MP4s but use an index to jump to the inpoint.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T17:25:38.020Z
Comments.Text: 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.
Comments.UserDisplayName: Andrew Klaassen
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T17:32:38.303Z
Comments.Text: Can you share the command+file which doesn't give perfect accuracy?
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T17:41:41.290Z
Comments.Text: 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.
Comments.UserDisplayName: Andrew Klaassen
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T18:07:27.353Z
Comments.Text: I made a change today morning that may improve seeking in MP4/MOVs. Try the latest builds.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T18:24:53.367Z
Comments.Text: @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.
Comments.UserDisplayName: Andrew Klaassen
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T18:39:29.823Z
Comments.Text: 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.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T18:41:57.183Z
Comments.Text: 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.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T18:49:57.483Z
Comments.Text: 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. :-)
Comments.UserDisplayName: Andrew Klaassen
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-05-03T18:54:25.597Z
Comments.Text: 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.
Comments.UserDisplayName: Andrew Klaassen
Tags: <video><ffmpeg>
Title: (Efficiently) Extract multiple clips from a long video, possibly with ffmpeg
UserDisplayName: John
ThreadText: # (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](https://video.stackexchange.com/questions/3274/what-is-a-good-efficient-way-to-isolate-clips-from-long-movies)), 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.
  
  
  ---
  
  