安装
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
}
}