Answers.Body: <p>heavy scripting</p>
  <pre class="lang-bash prettyprint-override"><code>#!/bin/bash
  cd /tmp
  f=&quot;/mnt/public/upload/test/tg/2024-07-20_10꞉11꞉34.MOV&quot;
  # f=&quot;/mnt/public/upload/test/tg/2024-07-19_13꞉39꞉18.mp4&quot;
  t=&quot;tmp.mp4&quot;
  o=&quot;output.mp4&quot;
  
  IFS=, read vid wid hei sar fmt fps tbn &lt;&lt;&lt; $(ffprobe -v 0 -select_streams v:0 -show_entries stream=codec_name,width,height,sample_aspect_ratio,r_frame_rate,time_base,pix_fmt -of csv=p=0 &quot;$f&quot;)
  if [ &quot;$sar&quot; = &quot;N/A&quot; ]; then sar=1; fi
  tbn=${tbn#*/}
  echo $vid $wid $hei $sar $fmt $fps $tbn
  
  beg=4.3
  end=$( echo &quot;$beg + 10&quot; | bc -l )
  ofs=$(ffprobe -read_intervals ${beg}%${end} -skip_frame nokey -select_streams v:0 -show_entries frame=pts_time -of default=nw=1:nk=1 &quot;$f&quot; -v 16 | head -n 2 | tail -n 1)
  echo &quot;---&gt; convert from $beg to $ofs&quot;
  ffmpeg -noautorotate -ss $beg -to $ofs -i &quot;$f&quot; -c:v $vid -video_track_timescale $tbn -an &quot;$t&quot; -y -hide_banner
  
  echo &quot;file '$t'
  file '$f'
  inpoint $ofs&quot; &gt; 1.txt
  ffmpeg -f concat -safe 0 -i 1.txt -ss $beg -i &quot;$f&quot; -map 0:v:0 -map 1:a:0 -c copy &quot;$o&quot; -y -hide_banner
  mpv --no-config --keep-open &quot;$o&quot;
  </code></pre>
  <p>this ↑ variant doesn't work sometimes with mp4, so you can try variant with using temporary mkv segments ↓</p>
  <pre class="lang-bash prettyprint-override"><code>#!/bin/bash
  cd /tmp
  # f=&quot;/mnt/public/upload/test/tg/2024-07-20_10꞉11꞉34.MOV&quot;
  f=&quot;/mnt/public/upload/test/tg/2024-07-19_13꞉39꞉18.mp4&quot;
  t=&quot;tmp.mkv&quot;
  o=&quot;output.mp4&quot;
  beg=4.3
  ffmpeg -i &quot;$f&quot; -c copy -an -f segment -segment_times $beg -reset_timestamps 1 tmp_%d.mkv -hide_banner -y
  echo &quot;---&gt; convert tmp_0.mkv from $beg&quot;
  vid=$(ffprobe -v 0 -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 &quot;$f&quot;)
  ffmpeg -noautorotate -ss $beg -i &quot;tmp_0.mkv&quot; -c:v $vid &quot;$t&quot; -y -hide_banner
  echo &quot;file '$t'
  file 'tmp_1.mkv'
  &quot; &gt; 1.txt
  ffmpeg -f concat -i 1.txt -ss $beg -i &quot;$f&quot; -map 0:v:0 -map 1:a:0 -c copy &quot;$o&quot; -y -hide_banner
  mpv --no-config --keep-open &quot;$o&quot;
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-07-20T07:43:33.550Z
Answers.Text: Your scripting skill is awesome! Why doesn't ffmpeg implement this strategy by default? What is the drawback?
Answers.UserDisplayName: Gqqnbig
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-07-20T03:58:13.500Z
Answers.LastActivityDate: 2024-07-20T03:58:13.500Z
Answers.UserDisplayName: Баяр Гончикжапов
Body: <p>I am a really beginner in video editing. Sorry if this question is silly.</p>
  <p>I heard videos consist of key frames (I-frames) and inter-frames (P-frames and B-frames).</p>
  <p>Say I have a video of 10 seconds, and I ask ffmpeg to extract from 4.3 to 10.</p>
  <pre><code>ffmpeg -ss 4.3 -i input.mp4 output.mp4
  </code></pre>
  <p>From my observation, ffmpeg seems to reencode the whole output file.</p>
  <p><a href="https://i.sstatic.net/26sXXl1M.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/26sXXl1M.png" alt="enter image description here" /></a></p>
  <p>Assume the original video has I frames at 1, 3, 5, 7, 9 seconds. I think ffmpeg can just insert a keyframe at 4.3, reencode frames from 4.3 to 5, and leave all data afterwards intact.</p>
  <p>Is my idea realistic? Can ffmpeg do so?</p>
  <p>I ask this is because if my input video is very long, my method can cut the video very fast.</p>
  
Tags: <ffmpeg>
Title: Can ffmpeg encode only the beginning part of a video for cutting?
UserDisplayName: Gqqnbig
ThreadText: # Can ffmpeg encode only the beginning part of a video for cutting?
  
  (Asked by: username_0 on 2024-07-19)
  
  I am a really beginner in video editing. Sorry if this question is silly.
  
  I heard videos consist of key frames (I-frames) and inter-frames (P-frames and B-frames).
  
  Say I have a video of 10 seconds, and I ask ffmpeg to extract from 4.3 to 10.
  
  ```
  ffmpeg -ss 4.3 -i input.mp4 output.mp4
  
  ```
  
  From my observation, ffmpeg seems to reencode the whole output file.
  
  [![enter image description here](https://i.sstatic.net/26sXXl1M.png)](https://i.sstatic.net/26sXXl1M.png)
  
  Assume the original video has I frames at 1, 3, 5, 7, 9 seconds. I think ffmpeg can just insert a keyframe at 4.3, reencode frames from 4.3 to 5, and leave all data afterwards intact.
  
  Is my idea realistic? Can ffmpeg do so?
  
  I ask this is because if my input video is very long, my method can cut the video very fast.
  
  **Tags:** ffmpeg
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2024-07-20. Score: 2
  
  heavy scripting
  
  ```bash
  #!/bin/bash
  cd /tmp
  f="/mnt/public/upload/test/tg/2024-07-20_10꞉11꞉34.MOV"
  # f="/mnt/public/upload/test/tg/2024-07-19_13꞉39꞉18.mp4"
  t="tmp.mp4"
  o="output.mp4"
  
  IFS=, read vid wid hei sar fmt fps tbn <<< $(ffprobe -v 0 -select_streams v:0 -show_entries stream=codec_name,width,height,sample_aspect_ratio,r_frame_rate,time_base,pix_fmt -of csv=p=0 "$f")
  if [ "$sar" = "N/A" ]; then sar=1; fi
  tbn=${tbn#*/}
  echo $vid $wid $hei $sar $fmt $fps $tbn
  
  beg=4.3
  end=$( echo "$beg + 10" | bc -l )
  ofs=$(ffprobe -read_intervals ${beg}%${end} -skip_frame nokey -select_streams v:0 -show_entries frame=pts_time -of default=nw=1:nk=1 "$f" -v 16 | head -n 2 | tail -n 1)
  echo "---> convert from $beg to $ofs"
  ffmpeg -noautorotate -ss $beg -to $ofs -i "$f" -c:v $vid -video_track_timescale $tbn -an "$t" -y -hide_banner
  
  echo "file '$t'
  file '$f'
  inpoint $ofs" > 1.txt
  ffmpeg -f concat -safe 0 -i 1.txt -ss $beg -i "$f" -map 0:v:0 -map 1:a:0 -c copy "$o" -y -hide_banner
  mpv --no-config --keep-open "$o"
  
  ```
  
  this ↑ variant doesn't work sometimes with mp4, so you can try variant with using temporary mkv segments ↓
  
  ```bash
  #!/bin/bash
  cd /tmp
  # f="/mnt/public/upload/test/tg/2024-07-20_10꞉11꞉34.MOV"
  f="/mnt/public/upload/test/tg/2024-07-19_13꞉39꞉18.mp4"
  t="tmp.mkv"
  o="output.mp4"
  beg=4.3
  ffmpeg -i "$f" -c copy -an -f segment -segment_times $beg -reset_timestamps 1 tmp_%d.mkv -hide_banner -y
  echo "---> convert tmp_0.mkv from $beg"
  vid=$(ffprobe -v 0 -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 "$f")
  ffmpeg -noautorotate -ss $beg -i "tmp_0.mkv" -c:v $vid "$t" -y -hide_banner
  echo "file '$t'
  file 'tmp_1.mkv'
  " > 1.txt
  ffmpeg -f concat -i 1.txt -ss $beg -i "$f" -map 0:v:0 -map 1:a:0 -c copy "$o" -y -hide_banner
  mpv --no-config --keep-open "$o"
  
  ```
  
  > **Comments:**
  > **username_0**: Your scripting skill is awesome! Why doesn't ffmpeg implement this strategy by default? What is the drawback?  
  
  ---
  
  