如何使用 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 应用程序:
npx create-snowpack-app gifconverter –template @snowpack/app-template-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 && }
Result
{gif && }
{gif && }
) : (
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 && }
Result
{gif && }
{gif && }
) : (
Loading...
);
}
export default App;
输出:如果您的浏览器提供此输出,那么您的项目运行良好。然后选择一个视频文件转换成图片,转换后点击转换按钮可以看到它给了我们一个.gif格式的动画图片。