<p>It took me quite a while of Googling and trial-and-error but I finally figured out how to actually do this. Thanks to Gyan for pointing me in the right direction.</p>

<p>I tried to do more of the process as one-liners but it always turned into a non-functional, undebuggable mess. If you think you could script this, please do so, <em>test it</em>, and then post it as a new answer.</p>

<hr>

<p>Print <code>pkt_duration_time</code> line and save it into a file:</p>

<p><code>ffprobe -show_frames input.gif | grep pkt_duration_time= &gt;frames.txt</code></p>

<p>Modify the line to the format that FFmpeg's concat filter requires:</p>

<p><code>sed 's/pkt_duration_time=/duration /g' frametimes.txt &gt;frametimes.txt</code></p>

<p>Print a list of your input files (frames) located in <code>folder/</code> and modify the list to be the format FFmpeg's concat filter requires:</p>

<p><code>ls --quoting-style=shell folder/ &gt;filenames.txt &amp;&amp; sed -i -e 's/^/file /' filenames.txt</code></p>

<p>Combine your frame-time file and filenames file to a concat file that FFmpeg accepts:</p>

<p><code>paste -d \\n filenames.txt frametimes.txt &gt; folder/concatfile.txt</code></p>

<p>We saved the concat file to where the input files are located because otherwise FFmpeg won't accept it. One more thing before we can encode the video: the data for the last frame needs to be present in the concat file twice for some reason. I don't have a CLI for that so just copy-paste it manually.</p>

<p>Now we can use FFmpeg to turn the image files to an animated video with correct frame times:</p>

<p><code>cd folder/</code></p>

<p><code>ffmpeg -f concat -safe 0 -i concatfile.txt -pix_fmt yuv420p -c:v libvpx-vp9 -b:v 0 -cpu-used 0 -tile-columns 2 -row-mt 1 -lag-in-frames 25 -threads 16 -crf 35 ../output.webm</code></p>

<ul>
<li><p>The <code>-safe 0</code> switch is required because otherwise FFmpeg complains about unsafe file names. At least it did in my case, possibly because the file names contained square brackets.</p></li>
<li><p>The <code>-pix_fmt yuv420p</code> ensures the correct color space is used. If you omit this, a color space that isn't standard for web video will be used and in the case of VP9 the resulting file will use Profile 1 which doesn't have as wide hardware decoding support as Profile 0. You could use <code>-profile:v 0</code> to make sure that this doesn't happen without you noticing.</p></li>
</ul>

<p>The rest of the parameters are quality and rate control features for libvpx-vp9. Remember to at least use <code>-b:v 0</code>, otherwise CRF won't behave as you'd expect. Also note that setting <code>-tile-columns</code> and <code>-threads</code> manually is required, otherwise encoding is limited to a single thread.</p>

CC BY-SA 4.0
2018-10-15T13:11:19.307Z
2018-10-15T19:50:02.123Z
2018-10-15T19:50:02.123Z
veikk0
<p>I have a set of images that I extracted from a GIF animation for the purpose of enhancement (which I have done), but now that it's time to convert the still images into a video (I'm going to use webm for higher quality output) I've run into a problem. The GIF format allows individual frames to be displayed for an artificial amount of time and this specific GIF animation makes use that feature, with most frames being displayed for 125 milliseconds but some remaining on the screen for as long as 3000 milliseconds. So just generating a video with a set frame rate isn't going to work as that would break the flow of the animation; I need a way import the frame duration data from the original GIF file and encode the extracted, modified frames into a video using that data.</p>

<p>Is there a way to do this with FFmpeg or maybe a combination of FFprobe and FFmpeg? I ran the GIF through <code>ffprobe -show_frames</code> and it would seem that the information I need is <code>pkt_duration_time</code> which shows the duration the frame is displayed.</p>

CC BY-SA 4.0
2018-10-11T13:24:20.370Z
See https://superuser.com/a/1320358/114058
Gyan
CC BY-SA 4.0
2018-10-15T13:12:21.260Z
@Gyan Thanks for pointing me in the right direction. I posted an answer to my question below.
veikk0
<ffmpeg><framerate>
Set display time of individual frames in FFmpeg
veikk0
# Set display time of individual frames in FFmpeg

(Asked by: username_0 on 2018-10-11)

I have a set of images that I extracted from a GIF animation for the purpose of enhancement (which I have done), but now that it's time to convert the still images into a video (I'm going to use webm for higher quality output) I've run into a problem. The GIF format allows individual frames to be displayed for an artificial amount of time and this specific GIF animation makes use that feature, with most frames being displayed for 125 milliseconds but some remaining on the screen for as long as 3000 milliseconds. So just generating a video with a set frame rate isn't going to work as that would break the flow of the animation; I need a way import the frame duration data from the original GIF file and encode the extracted, modified frames into a video using that data.

Is there a way to do this with FFmpeg or maybe a combination of FFprobe and FFmpeg? I ran the GIF through `ffprobe -show_frames` and it would seem that the information I need is `pkt_duration_time` which shows the duration the frame is displayed.

**Tags:** ffmpeg, framerate

> **Comments:**
> **username_1**: See https://superuser.com/a/1320358/114058  
> **username_0**: @username_1 Thanks for pointing me in the right direction. I posted an answer to my question below.  

---

## 1 answers

### Answer by username_0 on 2018-10-15. Score: 1 | Accepted answer

It took me quite a while of Googling and trial-and-error but I finally figured out how to actually do this. Thanks to username_1 for pointing me in the right direction.

I tried to do more of the process as one-liners but it always turned into a non-functional, undebuggable mess. If you think you could script this, please do so, *test it*, and then post it as a new answer.

---

Print `pkt_duration_time` line and save it into a file:

`ffprobe -show_frames input.gif | grep pkt_duration_time= >frames.txt`

Modify the line to the format that FFmpeg's concat filter requires:

`sed 's/pkt_duration_time=/duration /g' frametimes.txt >frametimes.txt`

Print a list of your input files (frames) located in `folder/` and modify the list to be the format FFmpeg's concat filter requires:

`ls --quoting-style=shell folder/ >filenames.txt && sed -i -e 's/^/file /' filenames.txt`

Combine your frame-time file and filenames file to a concat file that FFmpeg accepts:

`paste -d \\n filenames.txt frametimes.txt > folder/concatfile.txt`

We saved the concat file to where the input files are located because otherwise FFmpeg won't accept it. One more thing before we can encode the video: the data for the last frame needs to be present in the concat file twice for some reason. I don't have a CLI for that so just copy-paste it manually.

Now we can use FFmpeg to turn the image files to an animated video with correct frame times:

`cd folder/`

`ffmpeg -f concat -safe 0 -i concatfile.txt -pix_fmt yuv420p -c:v libvpx-vp9 -b:v 0 -cpu-used 0 -tile-columns 2 -row-mt 1 -lag-in-frames 25 -threads 16 -crf 35 ../output.webm`

* The `-safe 0` switch is required because otherwise FFmpeg complains about unsafe file names. At least it did in my case, possibly because the file names contained square brackets.
* The `-pix_fmt yuv420p` ensures the correct color space is used. If you omit this, a color space that isn't standard for web video will be used and in the case of VP9 the resulting file will use Profile 1 which doesn't have as wide hardware decoding support as Profile 0. You could use `-profile:v 0` to make sure that this doesn't happen without you noticing.

The rest of the parameters are quality and rate control features for libvpx-vp9. Remember to at least use `-b:v 0`, otherwise CRF won't behave as you'd expect. Also note that setting `-tile-columns` and `-threads` manually is required, otherwise encoding is limited to a single thread.


---

