📜  如何使用 ReactJS 创建视频到 GIF 转换器?

📅  最后修改于: 2022-05-13 01:56:30.774000             🧑  作者: Mango

如何使用 ReactJS 创建视频到 GIF 转换器?

当您考虑 GIF 图像时,必须将视频转换为 .gif 格式的图像。对于这个项目,我们使用的是用 C 编程语言编写的FFMPEG库实用程序。在 web Assembly 的支持下,它可以在浏览器中轻松运行,无需任何服务器,这里我们使用 ReactJS 库使其简单易懂。

您可以通过以下链接了解 Web Assembly:

  • WebAssembly – 下一件大事!

此外,您还可以了解 FFMPEG,它是一个免费的开源软件项目,包含大量用于处理视频、音频和其他多媒体文件和流的库和程序,您可以从 https://ffmpeg.org 查看/ 关联。

FFMPEG: FFmpeg.wasm 是 FFmpeg 的 WebAssembly 端口,您可以通过 npm 安装它并在 Node 或浏览器中使用,就像任何其他 JavaScript 模块一样。创建一个简单的客户端转码器,将数据流式传输到视频元素中。

在开始做这个项目之前,你有一个 ReactJS 的实践经验,因为我们使用的是 useState 的反应钩子。因此,可以使用该概念进一步并为项目创建目录。

  • 按照以下命令使用 snowpack 创建我们的 React 应用程序:
  • 安装上述命令后,然后通过以下命令安装另一个名为 FFMPEG 的包:
    npm install @ffmpeg/ffmpeg  @ffmpeg/core
  • 出于我们的样式目的,您可以通过以下命令安装样式组件。它很可能是 CSS,但是当我们使用 JavaScript 时,它会创建用户定义的变量,在该变量中,我们可以编写 CSS 属性,它也用于制作组件而无需制作新的 JSX 文件。
    npm i styled-components

项目结构:项目的所有安装已经完成,我们现在正在开发我们的目标项目。现在您可以看到项目目录如下所示,并且您所有的依赖项都安装成功了。

现在,您打开命令提示符并键入以下命令,通过运行以下命令来启动服务器。然后您的浏览器在您的应用程序运行的端口号8080中打开,如果您的浏览器看起来像这样,那么您来对地方了。

cd gifconverter
npm start

现在在您的代码编辑器中打开您的项目文件夹,并在src目录中创建一个名为 components 的文件夹,并在此文件夹下创建各种 JSX 组件文件,如下所示

源/组件:

  • 按钮.jsx
  • Dbutton.jsx
  • 页眉.jsx
  • 输入文件.jsx
  • 输入视频.jsx
  • 结果img.jsx            

创建上述 JSX 组件后,让我们为我们的项目添加代码:

Filename- Button.jsx:这个组件是一个转换按钮,当你点击它时,它会自动将.mp4文件转换为.gif文件。

Javascript
import React from "react";
import styled from "styled-components";
  
const Btn = styled.button`
  background-color: #000;
  color: #fff;
  border-radius: 18px;
  border: 1px solid #000;
  outline: none;
  font-weight: 700;
  cursor: pointer;
  font-size: 1.2em;
  padding: 10px;
  min-width: 20%;
  transition: all 0.2s ease-in-out;
  :hover {
    background-color: #3f3f3f;
    color: #efefef;
  }
`;
  
export const Button = ({ convertToGif }) => {
  return Convert;
};


Javascript
import React from "react";
import styled from "styled-components";
  
const Btn = styled.a`
  display: flex;
  left: 0;
  right: 0;
  margin: 20px auto;
  margin-top: -20px;
  background-color: #000;
  color: #fff;
  border-radius: 35.5px;
  border: 1px solid #000;
  outline: none;
  font-weight: 700;
  cursor: pointer;
  font-size: 1.2em;
  padding: 10px;
  padding-left: 50px;
  max-width: 10%;
  text-decoration: none;
  transition: all 0.2s ease-in-out;
  :hover {
    background-color: #3f3f3f;
    color: #efefef;
  }
`;
  
export const Dbutton = ({ gif, download }) => {
  return (
     download(e)}>
      Download
    
  );
};


Javascript
import React from "react";
import styled from "styled-components";
  
const H1 = styled.h1`
  margin: 0;
  padding: 12px;
  background-color: #000;
  color: #fff;
  font-family: sans-serif;
  font-size: 3em;
`;
  
export const Header = () => {
  return (
    
      

video to gif converter

    
  ); };


Javascript
import React from "react";
import styled from "styled-components";
  
const Section = styled.div`
  display: flex;
  left: 0;
  right: 0;
  margin: 50px auto;
  width: 30%;
  border: 2px dashed #000;
  border-radius: 18px;
  padding: 10px;
`;
  
export const Inputfile = ({ setVideo }) => {
  return (
    
       setVideo(e.target.files?.item(0))} />     
  ); };


Javascript
import React from "react";
import styled from "styled-components";
  
const Video = styled.video`
  width: 40%;
  margin: 20px;
  border: 1px dashed #045ca3;
`;
  
export const Inputvideo = ({ video }) => {
  return 


Javascript
import React from "react";
import styled from "styled-components";
  
const Img = styled.img`
  width: 50%;
  height: 100%;
  border: 4px solid #000;
  margin: 40px auto;
`;
  
export const Resultimg = ({ gif }) => {
  return ;
};


Javascript
import React, { useState, useEffect } from "react";
import "./App.css";
import { createFFmpeg, fetchFile } from "@ffmpeg/ffmpeg";
import { Button } from "./components/Button";
import { Inputfile } from "./components/Inputfile";
import { Header } from "./components/Header";
import { Resultimg } from "./components/Resultimage";
import { Inputvideo } from "./components/Inputvideo";
import { Dbutton } from "./components/Dbutton";
  
// Create the FFmpeg instance and load it
const ffmpeg = createFFmpeg({ log: true });
  
function App() {
  const [ready, setReady] = useState(false);
  const [video, setVideo] = useState();
  const [gif, setGif] = useState();
  
  const load = async () => {
    await ffmpeg.load();
    setReady(true);
  };
  
  useEffect(() => {
    load();
  }, []);
  
  const convertToGif = async () => {
    // Write the .mp4 to the FFmpeg file system
    ffmpeg.FS("writeFile", "video1.mp4", await fetchFile(video));
      
    // Run the FFmpeg command-line tool, converting 
    // the .mp4 into .gif file
    await ffmpeg.run(
      "-i",
      "video1.mp4",
      "-t",
      "2.5",
      "-ss",
      "2.0",
      "-f",
      "gif",
      "out.gif"
    );
    // Read the .gif file back from the FFmpeg file system
    const data = ffmpeg.FS("readFile", "out.gif");
    const url = URL.createObjectURL(
      new Blob([data.buffer], { type: "image/gif" })
    );
    setGif(url);
  };
  
  const download = (e) => {
    console.log(e.target.href);
    fetch(e.target.href, {
      method: "GET",
      headers: {},
    })
      .then((response) => {
        response.arrayBuffer().then(function (buffer) {
          const url = window.URL.createObjectURL(new Blob([buffer]));
          const link = document.createElement("a");
          link.href = url;
          link.setAttribute("download", "image.gif");
          document.body.appendChild(link);
          link.click();
        });
      })
      .catch((err) => {
        console.log(err);
      });
  };
  
  return ready ? (
    
      
      {video && }              
  ) : (       

Loading...

     ); }    export default App;


Filename- Dbutton.jsx:该组件是一个下载按钮,您可以在其中下载从 .mp4 文件转换后的 .gif 图像。

Javascript

import React from "react";
import styled from "styled-components";
  
const Btn = styled.a`
  display: flex;
  left: 0;
  right: 0;
  margin: 20px auto;
  margin-top: -20px;
  background-color: #000;
  color: #fff;
  border-radius: 35.5px;
  border: 1px solid #000;
  outline: none;
  font-weight: 700;
  cursor: pointer;
  font-size: 1.2em;
  padding: 10px;
  padding-left: 50px;
  max-width: 10%;
  text-decoration: none;
  transition: all 0.2s ease-in-out;
  :hover {
    background-color: #3f3f3f;
    color: #efefef;
  }
`;
  
export const Dbutton = ({ gif, download }) => {
  return (
     download(e)}>
      Download
    
  );
};

文件名 - Header.jsx:

Javascript

import React from "react";
import styled from "styled-components";
  
const H1 = styled.h1`
  margin: 0;
  padding: 12px;
  background-color: #000;
  color: #fff;
  font-family: sans-serif;
  font-size: 3em;
`;
  
export const Header = () => {
  return (
    
      

video to gif converter

    
  ); };

Filename- Inputfile.jsx:该组件用于获取用户输入的视频文件(.mp4 文件)

Javascript

import React from "react";
import styled from "styled-components";
  
const Section = styled.div`
  display: flex;
  left: 0;
  right: 0;
  margin: 50px auto;
  width: 30%;
  border: 2px dashed #000;
  border-radius: 18px;
  padding: 10px;
`;
  
export const Inputfile = ({ setVideo }) => {
  return (
    
       setVideo(e.target.files?.item(0))} />     
  ); };

文件名 - Inputvideo.jsx:

Javascript

import React from "react";
import styled from "styled-components";
  
const Video = styled.video`
  width: 40%;
  margin: 20px;
  border: 1px dashed #045ca3;
`;
  
export const Inputvideo = ({ video }) => {
  return 

文件名 - Resultimage.jsx:该组件显示从视频文件转换而来的 .gif 图像。

Javascript

import React from "react";
import styled from "styled-components";
  
const Img = styled.img`
  width: 50%;
  height: 100%;
  border: 4px solid #000;
  margin: 40px auto;
`;
  
export const Resultimg = ({ gif }) => {
  return ;
};

从上面的单个组件中你可以看到有很多 useState props 是使用大括号在箭头函数中传递的,不用担心你可以在 App.jsx 中找到那个 state。我更喜欢考虑 App.jsx 中的所有钩子。

因此,我们正在为项目中使用的所需组件添加所有代码。添加完所有代码后,我们必须将组件文件导入App.jsx

文件名- App.jsx:这是我们的 应用程序.jsx 代码。让我们将我们的组件导入这个文件。在下面的 App.jsx 中,我们正在导入一个如前所述的库,即 FFmpeg 作为 createFFmpeg 和 fetchFile。

我们正处于项目的最后阶段,以完成我们的项目是否运行良好?:) 然后刷新后,您可以在下图中看到您的 GIF 转换器的样子。

Javascript

import React, { useState, useEffect } from "react";
import "./App.css";
import { createFFmpeg, fetchFile } from "@ffmpeg/ffmpeg";
import { Button } from "./components/Button";
import { Inputfile } from "./components/Inputfile";
import { Header } from "./components/Header";
import { Resultimg } from "./components/Resultimage";
import { Inputvideo } from "./components/Inputvideo";
import { Dbutton } from "./components/Dbutton";
  
// Create the FFmpeg instance and load it
const ffmpeg = createFFmpeg({ log: true });
  
function App() {
  const [ready, setReady] = useState(false);
  const [video, setVideo] = useState();
  const [gif, setGif] = useState();
  
  const load = async () => {
    await ffmpeg.load();
    setReady(true);
  };
  
  useEffect(() => {
    load();
  }, []);
  
  const convertToGif = async () => {
    // Write the .mp4 to the FFmpeg file system
    ffmpeg.FS("writeFile", "video1.mp4", await fetchFile(video));
      
    // Run the FFmpeg command-line tool, converting 
    // the .mp4 into .gif file
    await ffmpeg.run(
      "-i",
      "video1.mp4",
      "-t",
      "2.5",
      "-ss",
      "2.0",
      "-f",
      "gif",
      "out.gif"
    );
    // Read the .gif file back from the FFmpeg file system
    const data = ffmpeg.FS("readFile", "out.gif");
    const url = URL.createObjectURL(
      new Blob([data.buffer], { type: "image/gif" })
    );
    setGif(url);
  };
  
  const download = (e) => {
    console.log(e.target.href);
    fetch(e.target.href, {
      method: "GET",
      headers: {},
    })
      .then((response) => {
        response.arrayBuffer().then(function (buffer) {
          const url = window.URL.createObjectURL(new Blob([buffer]));
          const link = document.createElement("a");
          link.href = url;
          link.setAttribute("download", "image.gif");
          document.body.appendChild(link);
          link.click();
        });
      })
      .catch((err) => {
        console.log(err);
      });
  };
  
  return ready ? (
    
      
      {video && }              
  ) : (       

Loading...

     ); }    export default App;

输出:如果您的浏览器提供此输出,那么您的项目运行良好。然后选择一个视频文件转换成图片,转换后点击转换按钮可以看到它给了我们一个.gif格式的动画图片。