前端本地使用ffmpeg

2023-12-24  本文已影响0人  Cola_Mr

安装

npm install @ffmpeg/ffmpeg @ffmpeg/core -S

ffmpeg.load
ffmpeg.load() 返回一个 Promise,用来加载 ffmpeg-core.js 核心包,在浏览器环境中,ffmpeg.wasm-core 脚本默认是从 CDN 中获取的,可以在创建 ffmpeg 实例时通过 corePath 来指定到本地路径。

ffmpeg.run
ffmpeg.run(...args) 返回一个 Promise,和原生的 ffmpeg 一样

ffmpeg.FS
ffmpeg.FS(method, ...args) 用来运行 FS 操作。

对于 ffmpeg.wasm 的输入/输出文件,需要先将它们保存到 MEMFS 以便 ffmpeg.wasm 能够使用它们。这里我们依赖 Emscripten 提供的 FS 方法♂️。

ffmpeg.exit
ffmpeg.exit() 用来杀死程序的执行,同时删除 MEMFS 以释放内存。

ffmpeg.setLogging
ffmpeg.setLogging(logging) 控制是否将日志信息输出到控制台。

ffmpeg.setLogger
ffmpeg.setLogger(logger) 设置和获取 ffmpeg.wasm 的输出消息。。

ffmpeg.setProgress
ffmpeg.setProgress(progress) 进度处理程序,用于获取 ffmpeg 命令的当前进度。

fetchFile
fetchFile(media) 返回一个 Promise, 用于从各种资源中获取文件。要处理的视频/音频文件可能位于远程 URL 或本地文件系统中的某个位置。这个函数帮助你获取文件并返回一个 Uint8Array 变量供 ffmpeg.wasm 使用。

注意:网页需要在请求头加上

# webpack
devServer: {
    headers: {
      "Cross-Origin-Opener-Policy": "same-origin",
      "Cross-Origin-Embedder-Policy": "require-corp",
    },
}

# nginx
add_header Cross-Origin-Opener-Policy same-origin; 
add_header Cross-Origin-Embedder-Policy require-corp;

示例代码

import { createFFmpeg , fetchFile } from '@ffmpeg/ffmpeg'

const ffmpeg = createFFmpeg({
  // corePath: "https://unpkg.com/@ffmpeg/core@0.10.0/dist/ffmpeg-core.js", // 指定 ffmpeg-core.js 的加载路径
  // log: true, // 是否打开所有日志,默认为 false
  // logger: ({ message }) => console.log(message), // 获取日志消息的函数
  // progress: p => console.log(p), // 跟踪进度的函数
})

async function init () {
  ffmpeg.setProgress(({ ratio }) => {
    console.log(`${ratio * 100}% 进度===>`);
  });
  ffmpeg.setLogger(({ type, message }) => {
    console.log('🚀🚀 ~ message', message);
    console.log('🚀🚀 ~ type', type);
  });
  await ffmpeg.load()
}
init()

async function start (file) {
  // 获取资源文件
  const result = await fetchFile(file)
  console.log('🚀🚀 ~ result', result);

  // 对于 ffmpeg.wasm 的输入/输出文件,需要先将它们保存到 MEMFS 以便 ffmpeg.wasm 能够使用它们
  await ffmpeg.FS('writeFile', `${file.name}`, result);

  await ffmpeg.run('-i', `${file.name}`, '-acodec', 'aac', '-vcodec', 'libx264', '-y', `${file.name.split('.')[0]}_transcod.mp4`)
  // 在内存中读取文件
  const data = await ffmpeg.FS('readFile', `${file.name.split('.')[0]}.mp4`);
  // 获取内存中的播放地址
  const videoFileUrl = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }))
  console.log('🚀🚀 ~  videoFileUrl', videoFileUrl);
  return videoFileUrl
  
}

const fileDom = document.querySelector('.file')
const videoDom = document.querySelector('.video')
fileDom.onchange = async function (e) {
  const file = e.target.files[0]
  console.log(file, '选择完');
  try {
    const url = await start(file)
    videoDom.src = url
  } catch (err) {
    alert('出错了')
    throw err
  }
}
上一篇 下一篇

猜你喜欢

热点阅读