领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

七爪源码:使用 ffmpeg 和 React 创建 Gif Maker

nixiaole 2024-11-27 18:38:51 知识剖析 10 ℃

今天我们将使用 ffmpeg - 根据他们的页面 - 允许您......

您可以使用 ffmpeg 做很多事情,我看到人们使用它的主要用途包括:降低视频帧速率(以缩小尺寸)、降低视频质量、将视频格式转码为其他视频(或图像)格式和 向视频添加叠加层(例如创建自己的水印)。

在本教程中,我们将创建一个玩具示例来将视频转换为 gif

是的,我使用该工具在本文中创建了 gif。


ffmpeg 命令

首先,让我们看看我们将运行的命令……

ffmpeg -i vid.mp4 -s 480x320 -r 3 -t ${length} -ss ${start} -f gif out.gif
  • -i =>输入
  • -s => 大小
  • -r => 帧速率(即 3 帧/秒)
  • -t => 以秒为单位的长度
  • -ss => 以秒为单位的开始偏移量
  • -f => 输出格式

看起来很简单,如果你的机器上安装了 ffmpeg,你也可以在 CLI 中运行这个命令。


进口

首先创建你的反应应用程序......

那么我们将需要以下三个包

"@ffmpeg/core": "^0.10.0",
"@ffmpeg/ffmpeg": "^0.9.8",
"http-proxy-middleware": "^2.0.6",


编码

由于我们使用 WebAssembly 来运行 ffmpeg,我们需要向我们的应用程序添加一些跨域标头(不是默认的 react),因此在您的 src 目录中创建一个名为 setupProxy.js 的文件。


setupProxy.js

module.exports = function (app) {
    app.use(function (request, response, next) {
        response.setHeader("Cross-Origin-Opener-Policy", "same-origin");
        response.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
        next();
    });
};

当我们运行我们的反应应用程序时,这将自动添加这些标题。

接下来,让我们更新我们的 App.js


应用程序.js

import React from "react";
import {createFFmpeg, fetchFile} from "@ffmpeg/ffmpeg";

const ffmpeg = createFFmpeg({log: true});

export class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {ready: false, video: null, gif: null, start: 0, length: 3}
  }

  componentDidMount() {
    this.loadFFmpeg();
  }

  async loadFFmpeg() {
    await ffmpeg.load();
    this.setState({ready: true})
  }

  async convertVideoToGif() {
    //write video to memory
    ffmpeg.FS("writeFile", "vid.mp4", await fetchFile(this.state.video));

    //run ffmpeg command
    await ffmpeg.run("-i", "vid.mp4", "-s", "480x320", "-r", "3", "-t", String(this.state.length), "-ss", String(this.state.start), "-f", "gif", "out.gif");

    //convert to data to url
    const data = ffmpeg.FS("readFile", "out.gif");
    const url = URL.createObjectURL(new Blob([data.buffer], {type: "image/gif"}));
    this.setState({gif: url})

  }


  render() {
    return this.state.ready ? (
        <div>
          {
            this.state.video &&
            <video controls width={250} src={URL.createObjectURL(this.state.video)}/>
          }
          <input type={"file"} onChange={(e) => {this.setState({video: e.target.files?.item(0)})}}/>
          <label htmlFor={"start-input"}>Start Time</label>
          <input id={"start-input"} type={"number"} value={this.state.start} onChange={(e) => {
            this.setState({start: e.target.value});
          }}/>
          <label htmlFor={"length-input"}>Length</label>
          <input id={"length-input"} type={"number"} value={this.state.length} onChange={(e) => {
            this.setState({length: e.target.value});
          }}/>
          <button onClick={() => {this.convertVideoToGif()}}>Convert</button>
          {
            this.state.gif &&
            <img src={this.state.gif} alt={"gif"} width={250}/>
          }
        </div>
    ) : <p>Loading...</p>
  }
}
  • 第 4 行:我们创建一个 ffmpeg 实例并将日志记录设置为 true,以便我们可以在控制台中看到日志。
  • 构造函数:我们创建一些状态项来跟踪当前的应用程序状态
  • ComponentDidMount & loadFFmpeg:在这里,我们等到我们的 react 组件挂载,然后加载 ffmpeg 的 Web Assembly 代码,然后我们将 ready 设置为 true,表示我们已准备好转换视频。
  • ConvertVideoToGif:这是实际工作完成的地方,我们在第 23 行将视频文件写入 ffmpeg 的文件系统。然后,在第 26 行运行我们的 ffmpeg 命令。最后我们从 ffmpeg 的文件系统中获取结果并将字节转换为 blob url gif 类型,我们可以在第 29-31 行向用户展示。
  • 渲染:这是我们的 UI 部分,如果我们还没有准备好,我们会显示“正在加载...”,否则我们将显示输入字段。我们输入了视频、开始时间和长度,所有这些都有一个 onChange 处理程序来更新它们各自的状态字段(第 43-51 行)。我们有一个视频(第 39-42 行)和图像(第 53-56 行)视图,如果我们的视频和 gif 状态不为空,则会显示这些视图。最后,我们有一个按钮,单击该按钮会将我们的视频转换为 gif(第 52 行)。


运行!

现在是测试它的时候了!运行 npm start 启动你的 react 应用并上传视频进行转换(转换可能需要几秒钟,检查控制台中的日志以查看 ffmpeg 的更新)。这只是一个起点,您可以自动为 S3 中的视频创建一些自动 gif 生成,转码并降低视频质量以支持较低带宽的用户,自动生成某些图像徽标的多种分辨率等......像ffmpeg这样强大的工具,谁需要任何昂贵的视频编辑工具?

最近发表
标签列表