Objective

This article will guide you through the steps of creating a video slideshow based on a list of images. The process does not entail using any editing software, but using a PHP script allowing you to create videos programmatically. If you follow this article you will learn the basics for creating your image to video converter.

The objective of this tutorial is to turn these 5 images into a video:

london-01.jpg
london-02.jpg
london-03.jpg
london-04.jpg
london-05.jpg

I will propose 2 alternatives for this:

Why should I care where the video is created?

Video processing is a resource expensive task that consumes memory and CPU. Depending on your usage estimate you might need to consider upgrading your servers or creating a dedicated cluster of servers for video processing.

On the other hand, using a cloud-based video API solution allows you to have a scale-proof, pay-as-you-go platform you don't need to worry about. Depending on your volume, you may fall into the free-tier and you don't have any cost.

This means that you can now focus exclusively on writing reusable code without having to worry about managing infrastructure.

Read more about what you should take into consideration when editing video with PHP scripts.

Self-hosted solution with FFMPEG and PHP

Create video from images with FFMPEG + PHP

There are many ways to do this, but I went with the two I think are the easiest. As you may know, FFMPEG is a powerful set of tools that can convert and process videos. But such power comes with a step learning curve, sometimes cryptic parameters and some frustration by newbies.

The examples below work for turning JPEG, PNG and WEBP still images into a video slideshow. You just need to replace the JPG file in the example codes with your PNG file, to turn the ffmpeg images to video.

Option 1: with no transitions

I will pass each of the 5 input images to ffmpeg in this format:

-loop 1 -t 2 -i london-0X.jpg

Then, I'll tell ffmpeg to concat them all into a output stream:

-filter_complex "[0][1][2][3][4] concat=n=5 [out]"

And finally, I'll save the output stream into output.mp4:

-map "[out]" output.mp4 -y

All together now:

ffmpeg \
    -loop 1 -t 2 -i london-01.jpg \
    -loop 1 -t 3 -i london-02.jpg \
    -loop 1 -t 2 -i london-03.jpg \
    -loop 1 -t 3 -i london-04.jpg \
    -loop 1 -t 4 -i london-05.jpg \
    -filter_complex "[0][1][2][3][4] concat=n=5 [out]" \
    -map "[out]" output.mp4 -y

Now let's make the call from PHP:

<?php
    $cmd = "ffmpeg \
    -loop 1 -t 2 -i london-01.jpg \
    -loop 1 -t 3 -i london-02.jpg \
    -loop 1 -t 2 -i london-03.jpg \
    -loop 1 -t 3 -i london-04.jpg \
    -loop 1 -t 4 -i london-05.jpg \
    -filter_complex \"[0][1][2][3][4] concat=n=5 [out]\" \
    -map \"[out]\" output.mp4";

    $r = exec($cmd);

You must make sure ffmpeg is in the same folder than your script or it's in a directory included in the PATH.

The resulting video is a slideshow of images, each with slide with different durations (2, 3, 2, 3 and 4 seconds):

Option 2: with transitions

Adding transitions is a little bit more tricky because we must fade each image with the next one. I will use the xfade filter to apply the transition, in this format:

[input1][input2] xfade=transition={transition_name}:duration={duration}:offset={offset}

Because this encoding is a little bit more complex, we must tell FFMPEG what codec and format to use to make sure the output is compatible with most of the video players, for example with QuickTime:

-pix_fmt yuv420p -vcodec libx264

All together now:

ffmpeg \
    -loop 1 -t 5 -i london-01.jpg \
    -loop 1 -t 5 -i london-02.jpg \
    -loop 1 -t 5 -i london-03.jpg \
    -loop 1 -t 5 -i london-04.jpg \
    -loop 1 -t 5 -i london-05.jpg \
    -filter_complex " \
        [0][1] xfade=transition=slideup:duration=1:offset=4 [a]; \
        [a][2] xfade=transition=slideright:duration=1:offset=8 [b]; \
        [b][3] xfade=transition=slidedown:duration=1:offset=12 [c]; \
        [c][4] xfade=transition=slideleft:duration=1:offset=16 [out] \
        " \
    -pix_fmt yuv420p -vcodec libx264 \
    -map "[out]" output.mp4 -y

I used 4 different transitions, one for each slide. You can check the available transitions in the xfade FFMPEG documentation

Now let's make the call from PHP:

<?php
    $cmd = "ffmpeg \
    -loop 1 -t 5 -i london-01.jpg \
    -loop 1 -t 5 -i london-02.jpg \
    -loop 1 -t 5 -i london-03.jpg \
    -loop 1 -t 5 -i london-04.jpg \
    -loop 1 -t 5 -i london-05.jpg \
    -filter_complex \" \
        [0][1] xfade=transition=slideup:duration=1:offset=4 [a]; \
        [a][2] xfade=transition=slideright:duration=1:offset=8 [b]; \
        [b][3] xfade=transition=slidedown:duration=1:offset=12 [c]; \
        [c][4] xfade=transition=slideleft:duration=1:offset=16 [out] \
        \" \
    -pix_fmt yuv420p -vcodec libx264 \
    -map \"[out]\" output.mp4 -y";

    $r = exec($cmd);

The resulting video looks like this:

As a bonus, if you continue reading, at the end of the article, I will show you how you can add a background music.
😉

Cloud-hosted solution with JSON2Video and PHP

Now, let's do the same but serverless, fully-scalable and with maintainable code.

With JSON2Video you use an abstraction to make things much easier:

The best thing in terms of development is that you can easily describe your video programmatically without knowing cryptic parameters like -t 5, -pix_fmt yuv420p or concat=n=5. And one month later, you (or someone in your team) will still be able to understand the code.

Create video from images with PHP + JSON2Video