Answers.Body: <p>To avoid transcoding, ffmpeg requires cutting the movie at i-frames,
  since that's where it has a full image.
  If you put the time with <code>-ss</code> into ffmpeg, it will start from the
  latest i-frame before or equal to the requested time.</p>
  <p>This suggests the strategy:</p>
  <ul>
  <li>Find i-frames</li>
  <li>Cut out segment videos</li>
  <li>Concat segment videos</li>
  </ul>
  <p>To find the i-frames, you can use the Python script</p>
  <pre><code># ffprobe -read_intervals 1:00:00%1:00:05 -show_frames vid.mkv 2&gt;&amp;1 | ./iframe_pts.py
  
  import datetime
  import sys
  
  pts = '0'
  pts_prefix = 'pts_time='
  for line in sys.stdin:
    line = line.strip()
    if line.startswith(pts_prefix):
      pts = line[len(pts_prefix):]
      continue
    if line == 'pict_type=I':
      print('%s %s' % (pts, datetime.timedelta(seconds=float(pts))))
  </code></pre>
  <p>Running this with short intervals will tell you where the i-frames are
  and you can pick whichever one is appropriate for what you're working on.
  Note that you should start on an i-frame and then stop right before an
  i-frame since ffmpeg might try to pad the video otherwise.</p>
  <p>To cut out the selected segments,</p>
  <pre><code>ffmpeg -i vid.mkv -ss 00:15:00 -t 01:38:00 -c:a copy -c:v copy s0.mkv
  </code></pre>
  <p>where <code>-ss</code> is the start time and <code>-t</code> is the duration.</p>
  <p>Then, you can join the segments together with the concat filter.
  First, make <code>input.txt</code>.</p>
  <pre><code>file 's0.mkv'
  file 's1.mkv'
  </code></pre>
  <p>Then run ffmpeg to join the segments together.</p>
  <pre><code>ffmpeg -f concat -i input.txt -c:a copy -c:v copy condensed.mkv
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-11-17T07:19:46.330Z
Answers.LastActivityDate: 2024-11-17T07:19:46.330Z
Answers.UserDisplayName: scubed
Body: <p>I have a long video with idle sections that I want to remove.
  Because it is long, I don't want to have
  to reecode the video, but to use stream copy.
  For example if I have vid.mkv I might want to take
  00:15:00 to 01:37:00 and 01:53:00 to 02:07:00
  and keep only those in the resulting movie.</p>
  <p>(I've found the parts of this in separate places
  but thought it would be useful to have a record
  of the entire process here, so answering my own question.)</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-11-17T14:40:12.953Z
Comments.Text: Avidemux nicely displays IPB frames. I have used it to losslessly cut and trim movies to the I frames and save with its MP4v2 Muxer (occasionally I have had to revert to its MP4 Muxer if the former for some reason did not work).
Comments.UserDisplayName: wywh
Tags: <ffmpeg>
Title: How to condense a video without reencoding with ffmpeg
UserDisplayName: scubed
ThreadText: # How to condense a video without reencoding with ffmpeg
  
  (Asked by: username_0 on 2024-11-17)
  
  I have a long video with idle sections that I want to remove.
  Because it is long, I don't want to have
  to reecode the video, but to use stream copy.
  For example if I have vid.mkv I might want to take
  00:15:00 to 01:37:00 and 01:53:00 to 02:07:00
  and keep only those in the resulting movie.
  
  (I've found the parts of this in separate places
  but thought it would be useful to have a record
  of the entire process here, so answering my own question.)
  
  **Tags:** ffmpeg
  
  > **Comments:**
  > **username_1**: Avidemux nicely displays IPB frames. I have used it to losslessly cut and trim movies to the I frames and save with its MP4v2 Muxer (occasionally I have had to revert to its MP4 Muxer if the former for some reason did not work).  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2024-11-17. Score: 0
  
  To avoid transcoding, ffmpeg requires cutting the movie at i-frames,
  since that's where it has a full image.
  If you put the time with `-ss` into ffmpeg, it will start from the
  latest i-frame before or equal to the requested time.
  
  This suggests the strategy:
  
  * Find i-frames
  * Cut out segment videos
  * Concat segment videos
  
  To find the i-frames, you can use the Python script
  
  ```
  # ffprobe -read_intervals 1:00:00%1:00:05 -show_frames vid.mkv 2>&1 | ./iframe_pts.py
  
  import datetime
  import sys
  
  pts = '0'
  pts_prefix = 'pts_time='
  for line in sys.stdin:
    line = line.strip()
    if line.startswith(pts_prefix):
      pts = line[len(pts_prefix):]
      continue
    if line == 'pict_type=I':
      print('%s %s' % (pts, datetime.timedelta(seconds=float(pts))))
  
  ```
  
  Running this with short intervals will tell you where the i-frames are
  and you can pick whichever one is appropriate for what you're working on.
  Note that you should start on an i-frame and then stop right before an
  i-frame since ffmpeg might try to pad the video otherwise.
  
  To cut out the selected segments,
  
  ```
  ffmpeg -i vid.mkv -ss 00:15:00 -t 01:38:00 -c:a copy -c:v copy s0.mkv
  
  ```
  
  where `-ss` is the start time and `-t` is the duration.
  
  Then, you can join the segments together with the concat filter.
  First, make `input.txt`.
  
  ```
  file 's0.mkv'
  file 's1.mkv'
  
  ```
  
  Then run ffmpeg to join the segments together.
  
  ```
  ffmpeg -f concat -i input.txt -c:a copy -c:v copy condensed.mkv
  
  ```
  
  
  ---
  
  