在Next.js中引用ffmpeg.wasm

近期遇到一个需求,要在next.js里面使用ffmpeg的wasm版本来对上传的视频文件进行转码
但是按照官方的demo在next.js里引用就是会有很多报错,属实是整不明白了
下面是一个小案例,要是有更聪明的办法请告知

官方文档:https://github.com/ffmpegwasm/ffmpeg.wasm

步骤

初始化一个Next.js项目

我是使用的typescript开发,仅使用的JavaScript的小伙伴应该不影响观看

yarn create next-app --typescript

按照官方的demo将ffmpeg引到项目中

官方demo:https://ffmpegwasm.netlify.app/#installation

先安装依赖包,我使用的是yarn,使用npm的可以直接看官方demo,这个要是安装不下来多半要科学上网

yarn add @ffmpeg/ffmpeg @ffmpeg/core

直接按照官方的demo改写了pages/index.tsx文件

import type { NextPage } from 'next'
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import { useRef, useState } from 'react'

// 引入ffmpeg
import { FFmpeg, createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg'

const Home: NextPage = () => {
  const [message, setMessage] = useState<string>('')
  const video = useRef<HTMLVideoElement | null>(null)

  // 此处是记录了一个ffmpeg的实例
  const ffmpeg = useRef<FFmpeg | null>(null)

  // 转码逻辑函数
  async function transcode(files: FileList | null) {
    if (!ffmpeg.current) {
      ffmpeg.current = createFFmpeg({
        corePath: '/ffmpeg-core.js', // 这一步一定要加,不然会报错,此外还有一个步骤要往下看
        log: true // 控制台输出转码log,可以去掉
      })
    }
    if (!files) return
    const { name } = files[0]
    setMessage('Loading ffmpeg-core.js')
    // 加载ffmpeg实例
    if (!ffmpeg.current.isLoaded()) {
      await ffmpeg.current.load()
    }
    // 读取文件
    ffmpeg.current.FS('writeFile', name, await fetchFile(files[0]))
    setMessage('Start transcoding')
    // 开始转码
    await ffmpeg.current.run('-i', name, 'output.mp4')
    setMessage('Complete transcoding')
    // 读取转码后的文件
    const data = ffmpeg.current.FS('readFile', 'output.mp4')
    // 转码后的文件挂载到video上可直接播放
    if (video.current) {
      video.current.src = URL.createObjectURL(
        new Blob([data.buffer], { type: 'video/mp4' })
      )
    }
  }

  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <h3>Upload a video to transcode to mp4 (x264) and play!</h3>
      <video
        ref={video}
        width={800}
        height={460}
        id="output-video"
        controls
      ></video>
      <br />
      {/* 在上传文件的input绑定上方transcode转码函数 */}
      <input
        type="file"
        id="uploader"
        onChange={e => transcode(e.target.files)}
      />
      <p>{message}</p>
    </div>
  )
}

export default Home

将几个文件复制到public文件夹中

重要的一步!这一步就是我感觉有点蠢的地方,因为是直接把第三方包中的文件直接复制到public文件夹中,虽然但是,这就不报错了可以正常使用了

这一步是为了解决上方创建ffmpeg实例时配置的corePath: '/ffmpeg-core.js',如果不配置会报错,报错原因就是找不到目标文件,这一步是参考了ffmpeg.wasm官方文档以及Next.js官方文档,可以点击链接查看知识点

  1. 找到node_modules/@ffmpeg/core/dist文件夹,复制下面的三个文件ffmpeg-core.jsffmpeg-core.wasmffmpeg-core.worker.js
  2. 将上方复制的三个文件粘贴到项目中的public文件夹

配置运行时的server环境

这步也很重要,不然也会报错

在项目根目录下新建一个文件server.js

const http = require('http')
const next = require('next')
const app = next({
  dir: './',
  dev: true
})
const handle = app.getRequestHandler()

app
  .prepare()
  .then(() => {
    const port = 3000
    const server = http.createServer((req, res) => {
      // 这一步非常有必要
      res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
      res.setHeader('Cross-Origin-Opener-Policy', 'same-origin')

      handle(req, res)
    })

    server.listen(port)
  })
  .catch(err => {
    console.trace(err)
  })

上面的setHeader操作是不可或缺的,具体原因是因为这样,参考ffmpeg.wasm官方文档,与SharedArrayBuffer有关

SharedArrayBuffer is only available to pages that are cross-origin isolated. So you need to host your own server with Cross-Origin-Embedder-Policy: require-corp and Cross-Origin-Opener-Policy: same-origin headers to use ffmpeg.wasm.

然后更改package.jsonscriptsdev字段

"scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  }

运行yarn dev启动项目即可,跑起来了跑起来了!

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在项目安装ffmpeg.wasm和@ffmpeg/ffmpeg,你可以按照以下步骤进行操作: 1. 首先,使用命令`yarn add @ffmpeg/ffmpeg @ffmpeg/core`来将ffmpeg.wasm和@ffmpeg/ffmpeg安装到你的项目。 2. 接下来,你需要创建一个ffmpeg实例。你可以使用`import FFmpeg from 'ffmpeg/@ffmpeg/dist/ffmpeg.min.js'`来导入ffmpeg的核心文件。然后,使用`FFmpeg.createFFmpeg()`方法来创建一个ffmpeg实例,并传入一些配置参数,例如核心文件的路径和日志选项。 3. 然后,你需要等待ffmpeg加载完成。可以使用`await ffmpeg.load()`来等待加载完成。这个过程可能需要一些时间,所以确保在等待期间不会执行其他操作。 综上所述,你可以按照上述步骤在项目安装ffmpeg.wasm和@ffmpeg/ffmpeg。希望对你有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [ffmpeg.wasm的使用教程](https://blog.csdn.net/qq_41535611/article/details/121907623)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [ffmpeg.wasm:用于Web浏览器和节点的FFmpeg,由WebAssembly支持](https://download.csdn.net/download/weixin_42125867/18577288)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝散bennkyo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值