Converting Video into Animated Images (and Other Videos) With FFmpeg (For The Most Part)
Published: 2021-04-15 17:08:08

---
title: Converting Video into Animated Images (and Other Videos) With FFmpeg (For The Most Part)
published: true
date: 2021-04-15 17:07:31 UTC
tags: 
canonical_url: https://codelab.farai.xyz/snippets/ffmpeg-animated-images/
---

_[Converting Video into Animated Images (and Other Videos) With FFmpeg (For The Most Part)](https://codelab.farai.xyz/snippets/ffmpeg-animated-images/) was first published on [Farai's Codelab](https://codelab.farai.xyz/)._
* * *

This post will supplement an upcoming post on why you should stop using GIFs in favor of newer image and video formats. Here’s how to generate animated images in various media formats using [FFMpeg](https://ffmpeg.org/download.html).

## Table of Contents
<nav id="TableOfContents">
  <ul>
    <li><a href="#preparing-the-source-clip-for-further-conversion">Preparing The Source Clip For Further Conversion</a></li>
    <li>
<a href="#images">Images</a>
      <ul>
        <li><a href="#gif">GIF</a></li>
        <li><a href="#webp">WebP</a></li>
        <li><a href="#sequenced-avif-chrome-for-now">Sequenced AVIF (Chrome For Now)</a></li>
      </ul>
    </li>
    <li>
<a href="#videos">Videos</a>
      <ul>
        <li><a href="#avch264-mp4-widest-support">AVC/h.264 MP4 (widest support)</a></li>
        <li><a href="#hevch265-webkit">HEVC/h.265 (WebKit)</a></li>
        <li><a href="#vp8vp9-android">VP8/VP9 (Android)</a></li>
        <li><a href="#av1-video-chrome-and-firefox">AV1 Video (Chrome and Firefox)</a></li>
      </ul>
    </li>
  </ul>
</nav>

## Preparing The Source Clip For Further Conversion

First thing to do is convert it to an uncompressed `y4m` video, slicing it up and setting the framerate as necessary:

```
ffmpeg -ss <start_point> -t <duration_from_start> -i <source_media> -an -vf 'scale=<width>:<height>,setpts=<stretch_factor>*PTS,fps=<framerate>' -pix_fmt yuv420p <raw_input>.y4m
```

What the option flags mean:

| Option | Description |
| --- | --- |
| `-ss` | Marks the start position of the video stream as a [time duration](http://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax) |
| `-t` | Specifies the duration of the datastream from `-ss` (or 0) as a [time duration](http://ffmpeg.org/ffmpeg-utils.html#time-duration-syntax). Use both `-ss` and `-t` before `-i` to limit the video input. |
| `-an` | Removes audio |
| `-vf` | The [video filters](https://ffmpeg.org/ffmpeg-filters.html#Video-Filters) |
| `scale` | Sets the **w** idth and **h** eight of the video |
| `setpts` | Sets the presentation timestamps (PTS) for the video. Used to [speed up and slow down video](https://trac.ffmpeg.org/wiki/How%20to%20speed%20up%20/%20slow%20down%20a%20video) |
| `fps` | Specifies the framerate for the video. |
| `pix_fmt` | Sets the color format. Not necessary and the only reason I specified it is because I had issues in an earlier draft |

Note, if you are going to set a framerate for a GIF, it [has a delay between frames](https://superuser.com/a/1449370) in hundreths of a second (<var>fps</var>=100/<var>delay</var>). So:

| Delay | Framerate |
| --- | --- |
| 1 | 10pfs |
| 2 | 50fps |
| 3 | 33fps |
| 4 | 25fps |
| 5 | 20fps |
| 6 | 15fps |

## Images

### GIF

```
ffmpeg -i <source_input>.y4m -filter_complex "[0:v] split [a][b];[a] palettegen [p];[b][p] paletteuse" -loop 0 <output>.gif
```

Simply put the `-filter_complex` flag in this case generates a color palette to use in the GIF. See [GIPHY’s Engineering blog on how to make GIFs](https://engineering.giphy.com/how-to-make-gifs-with-ffmpeg/) to explain the flag.

You can leave it out, resulting in a much smaller GIF (at the expense of quality).

### WebP

```
ffmpeg -i <raw_input>.y4m -loop 0 -q:v 100 -compression_level 6 <output>.webp
```

`q:v` is the image quality, from 0 to 100. It’ll be much smaller, but WebP can get blocky if you push the quality too hard.

### Sequenced AVIF (Chrome For Now)

ffmpeg doesn’t support writing to AVIF containers when I wrote this, so you nee to use [avifenc](https://github.com/AOMediaCodec/libavif/releases) to do this.

```
avifenc <raw_input>.y4m <output>.avif
```

## Videos

From here on out, I won’t go over the options too much since there’s a lot to consider, most of which I don’t understand so I’ll link to the respective encoding guide if you want more options.

### AVC/h.264 MP4 (widest support)

```
ffmpeg -i <raw_input.y4m -c:v libx264 -preset veryslow .<output>.mp4
```

The [`preset`](https://trac.ffmpeg.org/wiki/Encode/H.264#Preset) flag tries to find the best tradeoff between quality and compression at a given bitrate and file size.

[H.264 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.264)

### HEVC/h.265 (WebKit)

```
ffmpeg -i <raw_input>.y4m -c:v libx265 -preset veryslow -tag:v hvc1 <output>.mp4
```

You need the `-tag:v hvc1` for the video to play in Safari. [Thanks Aaron!](https://aaron.cc/ffmpeg-hevc-apple-devices/).

`preset` is the same as in AVC.

[H.265 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.265)

### VP8/VP9 (Android)

Switch the `vp8` for `vp9` depending on which one you choose. `vp9` is newer so better, although it doesn’t have the support of `vp8` (although it’s reasonable).

```
ffmpeg -i <raw_input>.y4m -c:v vp8 <output>.webm
```

[VP8 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/VP8)/[VP9 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/VP9)

### AV1 Video (Chrome and Firefox)

Encoding AV1 will use a lot of CPU and it takes a very long time; more so on my shitty laptop encoding at 0.1fps.

```
ffmpeg -i <raw_input>.y4m -strict -2 -c:v libaom-av1 .<raw_input>.webm
```

[AV1 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/AV1).

* * *

Thanks for reading! If you liked this post, consider [supporting my work](https://codelab.farai.xyz/support/) by:

- sharing my work,
- refering me for a job (or hire me for freelance work),
- sponsoring me on [Patreon](https://patreon.com/faraixyz),
- [buying Me A Coffee](https://www.buymeacoffee.com/faraixyz),
- [buying Me A Ko-Fi](https://ko-fi.com/faraixyz),
- [sending me a tip on Paypal](https://paypal.me/fgandiya),
- ~~[buy something on Amazon with my affiliate link](https://amazon.com/?tag=faraixyz03-20) (I’ll earn a commision on this as an amazon affiliate)~~,
- or [buy a domain on Namecheap with my affiliate link](https://shareasale.com/r.cfm?b=467188&u=2110247&m=46483&urllink=www%2Enamecheap%2Ecom%2F&afftrack=).

You can also [subscribe to my newsletter](https://buttondown.email/faraiscodelab).

Have feedback? Send an email to [gandiyafarai+feedback at gmail dot com](mailto:gandiyafarai+feedback@gmail.com?body%3dHey%2bI%2bread%2bthat%2bpost%2band%2bI%2bthought%2bit%2bwas%2bamazing%2521%2bAnd%2byet%252C%2bI%2breally%2bthink%2bthat%25E2%2580%2594I%2btotally%2bdidn%2527t%2buse%2bthe%2bprepopulated%2bemail.%26subject%3dFeedback%2bon%2bConverting%2bVideo%2binto%2bAnimated%2bImages%2b%2528and%2bOther%2bVideos%2529%2bWith%2bFFmpeg%2b%2528For%2bThe%2bMost%2bPart%2529)