Answers.Body: <p>A shorter method is</p>
  
  <pre><code>ffmpeg -i video.mp4 -vf 'select=eq(n,0)+between(n,310,930),setpts=if(eq(N,0),0,(N+260)/FRAME_RATE/TB)' -map [output] -vsync cfr -c:v libx264 -crf 18 -y output.mp4
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-04-01T17:03:44.860Z
Answers.Text: It seems that this method also does not waste space encoding frames 1–260. Only frame 0 is encoded and the waiting is done by timestamp manipulation, which is neat.
Answers.UserDisplayName: Witiko
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-03-31T04:38:04.120Z
Answers.LastActivityDate: 2019-03-31T04:38:04.120Z
Answers.UserDisplayName: Gyan
Answers.Body: <p>The <code>loop</code> filter produces the rest of the video after it has stopped looping. If this is undesirable, trim the resulting video as follows:</p>
  
  <pre><code>$ ffmpeg -i video.mp4 -i video.mp4 -filter_complex '
      [0:v]loop=loop=259:size=1:start=0,trim=start_frame=0:end_frame=259[first-frame];
      [1:v]trim=start_frame=310:end_frame=930,setpts=PTS-STARTPTS[rest];
      [first-frame][rest]concat=n=2:v=1:a=0[output]
  ' -map [output] -c:v libx264 -crf 18 -y output.mp4
  </code></pre>
  
  <p>This behavior is perhaps counterintuitive and poorly documented, but it covers the common case, when one wants to loop at the beginning of a video. This behavior also makes <code>loop=0</code> an identity filter that passes the video unchanged.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-03-31T04:42:33.373Z
Answers.Text: The loop filter is meant to pass through untouched portions of the input while looping the specified portion. If it dropped the remainder, then the size and start are unnecessary and users would need to always manually trim and then concat the various segments, like your command does.
Answers.UserDisplayName: Gyan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-03-31T03:36:46.513Z
Answers.LastActivityDate: 2019-03-31T04:00:39.670Z
Answers.LastEditDate: 2019-03-31T04:00:39.670Z
Answers.UserDisplayName: Witiko
Body: <p>I would like to to play the first frame of an input video for 260 frames and then play frames 310–930 of the input video:</p>
  
  <pre><code>$ ffmpeg -i video.mp4 -i video.mp4 -filter_complex '
      [0:v]loop=loop=259:size=1:start=0[first-frame];
      [1:v]trim=start_frame=310:end_frame=930,setpts=PTS-STARTPTS[rest];
      [first-frame][rest]concat=n=2:v=1:a=0[output]
  ' -map [output] -c:v libx264 -crf 18 -y output.mp4
  </code></pre>
  
  <p>The above command produces the first frame of the input video for 260 frames as expected, but then continues with frames 0-620 of the input video followed by frames 310–930 of the input video.</p>
  
  <p>When I drop the <code>[first-frame]</code> part, frames 310–930 of the input video are correctly produced:</p>
  
  <pre><code>$ ffmpeg -i video.mp4 -i video.mp4 -filter_complex '
      [1:v]trim=start_frame=310:end_frame=930,setpts=PTS-STARTPTS[rest];
      [rest]concat=n=1:v=1:a=0[output]
  ' -map [output] -c:v libx264 -crf 18 -y output.mp4
  </code></pre>
  
  <p>This is perhaps a timestamp problem, since the documentation for the <code>concat</code> filter clarifies that “for this filter to work correctly, all segments must start at timestamp 0.”</p>
  
  <p>I am using the following version of ffmpeg:</p>
  
  <pre><code>$ ffmpeg -version
  ffmpeg version 3.2.12-1~deb9u1 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
  configuration: --prefix=/usr --extra-version='1~deb9u1' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libebur128 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
  libavutil      55. 34.101 / 55. 34.101
  libavcodec     57. 64.101 / 57. 64.101
  libavformat    57. 56.101 / 57. 56.101
  libavdevice    57.  1.100 / 57.  1.100
  libavfilter     6. 65.100 /  6. 65.100
  libavresample   3.  1.  0 /  3.  1.  0
  libswscale      4.  2.100 /  4.  2.100
  libswresample   2.  3.100 /  2.  3.100
  libpostproc    54.  1.100 / 54.  1.100
  </code></pre>
  
Tags: <ffmpeg>
Title: Loop the first frame of a video and then play a selected portion of the video
UserDisplayName: Witiko
ThreadText: # Loop the first frame of a video and then play a selected portion of the video
  
  (Asked by: username_0 on 2019-03-31)
  
  I would like to to play the first frame of an input video for 260 frames and then play frames 310–930 of the input video:
  
  ```
  $ ffmpeg -i video.mp4 -i video.mp4 -filter_complex '
      [0:v]loop=loop=259:size=1:start=0[first-frame];
      [1:v]trim=start_frame=310:end_frame=930,setpts=PTS-STARTPTS[rest];
      [first-frame][rest]concat=n=2:v=1:a=0[output]
  ' -map [output] -c:v libx264 -crf 18 -y output.mp4
  
  ```
  
  The above command produces the first frame of the input video for 260 frames as expected, but then continues with frames 0-620 of the input video followed by frames 310–930 of the input video.
  
  When I drop the `[first-frame]` part, frames 310–930 of the input video are correctly produced:
  
  ```
  $ ffmpeg -i video.mp4 -i video.mp4 -filter_complex '
      [1:v]trim=start_frame=310:end_frame=930,setpts=PTS-STARTPTS[rest];
      [rest]concat=n=1:v=1:a=0[output]
  ' -map [output] -c:v libx264 -crf 18 -y output.mp4
  
  ```
  
  This is perhaps a timestamp problem, since the documentation for the `concat` filter clarifies that “for this filter to work correctly, all segments must start at timestamp 0.”
  
  I am using the following version of ffmpeg:
  
  ```
  $ ffmpeg -version
  ffmpeg version 3.2.12-1~deb9u1 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
  configuration: --prefix=/usr --extra-version='1~deb9u1' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libebur128 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
  libavutil      55. 34.101 / 55. 34.101
  libavcodec     57. 64.101 / 57. 64.101
  libavformat    57. 56.101 / 57. 56.101
  libavdevice    57.  1.100 / 57.  1.100
  libavfilter     6. 65.100 /  6. 65.100
  libavresample   3.  1.  0 /  3.  1.  0
  libswscale      4.  2.100 /  4.  2.100
  libswresample   2.  3.100 /  2.  3.100
  libpostproc    54.  1.100 / 54.  1.100
  
  ```
  
  **Tags:** ffmpeg
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2019-03-31. Score: 2 | Accepted answer
  
  A shorter method is
  
  ```
  ffmpeg -i video.mp4 -vf 'select=eq(n,0)+between(n,310,930),setpts=if(eq(N,0),0,(N+260)/FRAME_RATE/TB)' -map [output] -vsync cfr -c:v libx264 -crf 18 -y output.mp4
  
  ```
  
  > **Comments:**
  > **username_0**: It seems that this method also does not waste space encoding frames 1–260. Only frame 0 is encoded and the waiting is done by timestamp manipulation, which is neat.  
  
  ---
  
  ### Answer by username_0 on 2019-03-31. Score: 1
  
  The `loop` filter produces the rest of the video after it has stopped looping. If this is undesirable, trim the resulting video as follows:
  
  ```
  $ ffmpeg -i video.mp4 -i video.mp4 -filter_complex '
      [0:v]loop=loop=259:size=1:start=0,trim=start_frame=0:end_frame=259[first-frame];
      [1:v]trim=start_frame=310:end_frame=930,setpts=PTS-STARTPTS[rest];
      [first-frame][rest]concat=n=2:v=1:a=0[output]
  ' -map [output] -c:v libx264 -crf 18 -y output.mp4
  
  ```
  
  This behavior is perhaps counterintuitive and poorly documented, but it covers the common case, when one wants to loop at the beginning of a video. This behavior also makes `loop=0` an identity filter that passes the video unchanged.
  
  > **Comments:**
  > **username_1**: The loop filter is meant to pass through untouched portions of the input while looping the specified portion. If it dropped the remainder, then the size and start are unnecessary and users would need to always manually trim and then concat the various segments, like your command does.  
  
  ---
  
  