# FFMPEG tutorial - movies from a sequence of images

Note: all commands below are assumed to be executed from the `ffmpeg_tutorial` directory.
If not, please change the image paths as required.

Author: Pierre DERIAN - 2025-03-26.

## Basic example: using a filename pattern

This example encodes the movie from an image file pattern. The options are my default for a "fairly good quality, widely playable" movie when filesize is out of the question. 

```bash
ffmpeg -y -r 6 -pattern_type glob -i '../images/scans/202308/20230818/scan_REAL.20230818_2[0-2]*.png' -c:v h264 -crf 12 -pix_fmt yuv420p -movflags faststart output_pattern.mp4
```

where the options mean:
* `-y`: assume the answer "yes" to any question, e.g. "overwrite existing output file?".
* `-r 6`: input framerate in frame per second (fps). Here 6 means 6 images per second.
* `-pattern_type glob`: indicates that the input (-i) is to be understood as a "glob pattern" - mode info on that below.
* `-i '../images/scans/202308/20230818/scan_REAL.20230818_2[0-2]*.png'`: input files, here a pattern - more on that below.
* `-c:v h264`: the video codec is h264.
* `-crf 12`: the quality profile, in [0..51]. The lower the better (but also bigger output movie files!).
* `-pix_fmt yuv420p`: the way the pixel color is encoded. This specific value ensures a good playback on different platforms (linux, mac, windows...).
* `-movflags faststart`: this option makes the movies start faster when streaming.
* `output.mp4`: this is the output filename.

How the does the pattern work?
You will have to read on Unix's [glob](https://en.wikipedia.org/wiki/Glob_(programming)) for the details.
Basically you can specify things such as ranges (here the [0-2] means any number between 0 and 2 , included) or wildcard * (any number of any character, including none).
So, the pattern describes a list of (image) files which are then used in alphanumerical order to generate the movie.
FYI - glob is available in [Python](https://docs.python.org/3/library/glob.html) as well!

There are other types of patterns, as seen in [FFMPEG documentation](https://ffmpeg.org/ffmpeg-formats.html#image2-1).

## Advanced example: generating a list of frames 

The glob pattern is quite powerful, but there are times when it is not enough.
For instance, you may want to make a movie with frames spanning 09:30 to 18:35 precisely (that would be a pretty long movie though, please don't try it :).
How to write the glob pattern that would exactly generate the files in that interval?

In such situations I break down the process in two steps:
1. generate a file containing the list of input image files, wathever they may be.
2. build the movie from that list.

Assuming that you have a `framelist.txt` file from step 1, here's what step 2 looks like:

```bash
cat $(cat framelist.txt) | ffmpeg -y -r 6 -f image2pipe -i - -c:v h264 -crf 12 -pix_fmt yuv420p -movflags faststart output_list.mp4
```
 
You will recognize that most of the FFMPEG options are the same as above, only the ones related to the input change. 
The first part of the command is a way to feed the content of `framelist.txt` to FFMPEG.

So, all that is left is generating the list of file.
The method to do it is entirely up to you, and the best approach likely depend on what exactly you are trying to achieve.
To give a complete working example, I have provided a small Python script, [make_framelist.py](make_framelist.py), which uses several _glob_ (yes!) to generate the list.
You can try it out with `python make_framelist.txt`. 

## Ultimate example: automation

The previous approach is cool, but what happens when one has many, many movies to make? They may be (rightfully) tempted to automate things. 
Again, there are many ways to do so.
Given that we used Python to generate the frame list, why not continue with the movie?
As an example, I have provided another script, [`make_movie.py`](make_movie.py), which illustrates how to reproduce the previous combination of "cat" and "ffmpeg".
Simply run `python make_movie.py` and watch the magic unfold.

The next step is to find how to generate the patterns and the movie filenames.
My educated guess is that you may be interested in using dates and time intervals.
To do so, I suggest you to take a look at Python's [datetime](https://docs.python.org/3/library/datetime.html), and more particularly the `datetime` and `timedelta` classes, and the `strftime` method.


## Bonus tips

- Feel free to experiment with the quality setting (`crf`) a bit, to find the best compromise between quality and size.
  From [FFMPEG doc](https://trac.ffmpeg.org/wiki/Encode/H.264): "Consider 17 or 18 to be visually lossless or nearly so".
- Also with the framerate (`r`).
  You want it fast enough so our brain "rebuilds the motion", but not too fast so we can actually see what is going on.
  Also, changing this has a direct impact on the duration of the movie.
  In the real world there are about 3.5 scans per minute, to give you an idea of the playback speed.

 


