在 NextJS 中用 ffmpeg 剪辑视频

FFmpeg 是一个由用于多媒体任务(如音频和视频转换以及视频修剪)的库组成的工具。为了在客户端实现视频修剪,将通过 FFmpeg.wasm 来使用 FFmpeg 软件包的二进制格式,其中 “wasm “代表 WebAssembly(一种专为在网络浏览器中高效执行而设计的二进制指令格式)。FFmpeg 主要用 C 语言编写,目的是在 WebAssembly 的支持下将其二进制格式部署到浏览器中。

为了在浏览器中运行 ffmpeg,我们需要提供一些浏览器安全头文件。

默认情况下,浏览器不允许使用浏览器中可用的共享缓冲区 API。我们需要明确告知浏览器我们要使用该 API,这样浏览器就会将其置于浏览器上下文之外的单独上下文中……这就是所谓的跨源隔离(cross-origin-isolated)。

默认情况下,浏览器会为弹出窗口、iframe 等维护不同的上下文…

我们要告诉浏览器为我们的用例创建一个单独的上下文,为此我们需要提供以下两个标头:

1. Cross-Origin-Embedder-Policy: require-corp:

“使用 Cross-Origin-Embedder-Policy:require-corp,我们就可以在文档中嵌入更多资源。不过,它规定嵌入的资源也必须包含相同的标头,以保证安全策略的一致性”。

2. Cross-Origin-Opener-Policy: same-origin:

“通过设置 Cross-Origin-Opener-Policy: same-origin,我们可以执行同源策略。这意味着具有相同来源的窗口和从文档中打开的窗口将共享相同的浏览上下文组,从而实现它们之间的通信。例如,如果浏览器位于 a.example.com,而打开的弹出窗口位于 b.example.com,由于来源不同,它们将无法通信。要实现通信,两个窗口应来自同一来源,如 a.example.com 和 b.example.com”。

在 NextJS 中,我们将保留该标头:

export async function getServerSideProps(context) {
context.res.setHeader(“Cross-Origin-Opener-Policy”, “same-origin”);
context.res.setHeader(“Cross-Origin-Embedder-Policy”, “require-corp”);
return {
props: {},
};
}

我们将使用 ffmpeg 软件包:

import { createFFmpeg, fetchFile } from “@ffmpeg/ffmpeg”;

我们将使用 createFFmpeg 方法加载该软件包,如下所示:

我们将为部署在某个地方的所需软件包提供服务……对于我来说,我部署在同一个项目中,并为它们提供服务,如下所示。我们将通过 load() 加载这些所需的软件包;

const ffmpeg = React.useRef();

useEffect(() => {
(async () => {
try {
// Initialize FFmpeg
ffmpeg.current = await createFFmpeg({
log: true,
corePath: “https://yourDomain.com/static/ffmpeg-core.js",
workerPath: “https://yourDomain.com/static/ffmpeg-core.worker.js",
wasmPath: “https://yourDomain.com/static/ffmpeg-core.wasm",
});

// Load FFmpeg
await ffmpeg.current.load();
} catch (error) {
console.error(“Error initializing FFmpeg:”, error);
}
})();
}, []);

我们将使用 ffmpeg 软件包将视频从 0 秒剪辑到 59 秒,如下所示:

// Trim video functionality
const outputOptions = “-ss 00:00:00 -t 00:00:59 -vcodec copy -acodec copy”;
const inputOptions = “-i”;

const handleTrim = async () => {
const file = formData?.video;
try {
ffmpeg.current.FS(
“writeFile”,
formData?.video?.name,
await fetchFile(formData?.video)
);
currentFSls.current = ffmpeg.current.FS(“readdir”, “.”);
const uniqueFileName = UniqueFileName();

await ffmpeg.current.run(
…inputOptions.split(“ “),
formData?.video?.name,
…outputOptions.split(“ “),
uniqueFileName
);

const FSls = ffmpeg.current.FS(“readdir”, “.”);
const outputFiles = FSls.filter((i) => !currentFSls.current.includes(i));
const data = ffmpeg.current.FS(“readFile”, outputFiles[0]);

const type = await fileTypeFromBuffer(data.buffer);
const objectURL = URL.createObjectURL(new Blob([data.buffer], { type: type.mime }));

fetch(objectURL)
.then((response) => response.blob())
.then((blobData) => {
const fileName = `trimmed_${formData?.video?.name}`;
const file = new File([blobData], fileName, { type: blobData.type });
console.log(“Trimmed Video file is”, file);
});
} catch (err) {
console.error(“Error is “, err);
}
};

性能考虑因素: 需要注意的是,在客户端执行 CPU 密集型任务(如视频剪辑)可能会影响网站性能。FFmpeg 包的大小可能会导致网站运行速度减慢。此外,在显示图像时,应在外部资源上应用与上述类似的标题,以确保安全策略的一致性。

结论

在 NextJS 项目中使用 FFmpeg 进行视频剪辑可增强多媒体功能。不过,开发人员必须注意安全标头、潜在的性能影响以及资源密集型任务的替代解决方案。本综合指南将为您提供将 FFmpeg 无缝集成到 NextJS 应用程序中以实现高效视频剪辑的知识。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论