Create a GIF Converter Using React

Create a GIF Converter Using React

Looking through my GitHub repos looking for post ideas, I found one called 'gifmaker'. I made it quite some time ago, and I think that I was following some sort of YouTube tutorial. I checked the code, and to my surprise, it's really simple, short, and works great.

Let's start by creating our React app along with webpack:

npx create-snowpack-app [name-dir] --template @snowpack/app-template-react

(Remember to change [name-dir])

Once we have our React app created, we need to install ffmpeg, the tool we are going to use to convert our videos to GIF. We can do that by using this command:

npm install @ffmpeg/ffmpeg @ffmpeg/core

yarn add @ffmpeg/ffmpeg

Now, we can start coding.

import React, { useState, useEffect } from 'react';
import './App.css';

import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';
const ffmpeg = createFFmpeg({ log: true });

function App() {
  const [ready, isReady] = useState(false);
  const [video, setVideo] = useState();
  const [gif, setGif] = useState();

  const load = async () => {
    await ffmpeg.load();
    isReady(true);
  };

  useEffect(() => {
    load();
  }, []);

So what's going on here? Ok, first, we import ffmpeg initialize it, declare some variables that we are going to use later (trust me) and since ffmpeg takes some time to load, we make create an async function and call it inside a 'useEffect' hook. Nothing too fancy right? Let's keep going.

This is the method we are going to use to convert our videos to GIF:

  const convertToGif = async () => {
    ffmpeg.FS('writeFile', 'giphy.mp4', await fetchFile(video));

    await ffmpeg.run('-i', 'giphy.mp4', '-f', 'gif', 'out.gif');

    const data = ffmpeg.FS('readFile', 'out.gif');

    const url = URL.createObjectURL(
      new Blob([data.buffer], { type: 'image/gif' }),
    );

    setGif(url);
  };

Here, what we do is tell ffmpeg that we are writing a file (the GIF), reading a video, and converting the video to a GIF. There is a lot of interesting stuff we can create playing this the args from the methods, we could try that another day!

But that's basically it, now all we have to do is show it to the world:

return ready ? (
    <div className="App">
      {video && (
        <video controls width="250" src={URL.createObjectURL(video)}></video>
      )}
      <br />
      <input type="file" onChange={(e) => setVideo(e.target.files?.item(0))} />

      <h3>Result</h3>

      <button onClick={convertToGif}>Convert to GIF</button>
      <br />
      {gif && <img src={gif} width="250"></img>}
    </div>
  ) : (
    <p>Please wait...</p>
  );

(For some reason this didn't work on Safari, try it on another browser if that's your case)

If ffmpeg is loaded, we should see a file input, if not, a loading screen. Once we select a video, we see it loaded with controls, and a button to convert it to a GIF. Let's try it!

converter preview

It works! This is the kind of stuff that we probably are never going to use but at least we can say 'I know how to make a program to convert a video to a GIF' 😅

I hope you liked it, and if you have any questions, let me know! ALSO:

(I can't remember which tutorial it was, so if somebody knows which one it is let me know to give credit)


See more at: blog.daviddiazh.dev

Check out my first React App: guessthesubredd.it