I’m creating an app which allows users to view videos. With payload as the server side for CMS, I have been trying to implement ffmpeg/fluent-ffmpeg with payload to extract thumbnails from the video uploaded in video collection and directly save it to another collection called thumbnails but it doesn’t work.
( I’m using the beforeChangeHook )
The module ‘fs’ is not found when I import and use ffmpeg from either module (ffmpeg/fluent-ffmpeg), same goes for ‘utils’ in the ffmpeg node_modules.
Does payload block the usage of such packages which require fs and utils?
There was another issue with webpack poly fills but which I’m assuming I can’t change.
Is it possible to use ffmpeg/fluent-ffmpeg with payload? If not could you suggest a way to extract thumbnails and directly save it to the thumbnails collection
Can you post your code?
It sounds like you need to exclude your hook from the client side (webpack).
import fs from "fs";
import ffmpeg from "ffmpeg";
import { CollectionBeforeChangeHook } from "payload/types";
async function onBeforeChangeHook({ data, req }): Promise<CollectionBeforeChangeHook> {
if (data.file) {
const process = new ffmpeg(data.file);
process.then((video) => {
video.fnExtractFrameToJPG("/tmp", { number: 1 }, async (error, files) => {
if (error) {
return;
}
const buffer = fs.readFileSync(files[0]);
try {
const newThumbnail = {
thumbnail: buffer,
title: data.file.filename,
videoId: data.id,
};
await req.collection["thumbnails"].insertOne(newThumbnail);
} catch (error) {
console.error("Error occured: ", error);
}
});
});
console.log(data);
return data;
}
}
export default onBeforeChangeHook;
This is the code for the hook (using ffmpeg package) , please show me how I can exclude the hook from the client side.
Not sure if it matters but just to give context of my structure, I have an independent create-next-app in a client folder, and a server folder in which I created the payload app.
ERROR in ./node_modules/ffmpeg/lib/errors.js 1:11-26
Module not found: Error: Can't resolve 'util' in 'C:\Users\awabi\Desktop\Work\majaalis-al-ilm\server\node_modules\ffmpeg\lib'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
- install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "util": false }
ERROR in ./node_modules/ffmpeg/lib/ffmpeg.js 5:33-46
Module not found: Error: Can't resolve 'fs' in 'C:\Users\awabi\Desktop\Work\majaalis-al-ilm\server\node_modules\ffmpeg\lib'
ERROR in ./node_modules/ffmpeg/lib/utils.js
Module build failed (from ./node_modules/swc-loader/src/index.js):
Error:
× Legacy octal literals are not available when targeting ECMAScript 5 and higher
╭─[C:\Users\awabi\Desktop\Work\majaalis-al-ilm\server\node_modules\ffmpeg\lib\utils.js:86:1]
86 │ parts = parts.slice(1);
87 │
88 │ // Set the initial configuration
89 │ mode = mode
0777;0;
91 │
92 │ // Check se current position is greater than the list of folders
╰────
× Legacy octal escape is not permitted in strict mode
╭─[C:\Users\awabi\Desktop\Work\majaalis-al-ilm\server\node_modules\ffmpeg\lib\utils.js:86:1]
86 │ parts = parts.slice(1);
87 │
88 │ // Set the initial configuration
89 │ mode = mode
0777;0;
91 │
92 │ // Check se current position is greater than the list of folders
╰────
Caused by:
Syntax Error
ERROR in ./node_modules/ffmpeg/lib/video.js
Module build failed (from ./node_modules/swc-loader/src/index.js):
Error:
× Legacy octal literals are not available when targeting ECMAScript 5 and higher
╭─[C:\Users\awabi\Desktop\Work\majaalis-al-ilm\server\node_modules\ffmpeg\lib\video.js:765:1]
765 │ settings.file_name = path.basename(settings.file_name, path.extname(settings.file
name)) + '%d.jpg';
766 │
767 │ // Create the directory to save the extracted frames
768 │ utils.mkdir(destinationFolder, 0777);
· ────
769 │
770 │ resetCommands(this);
771 │
╰────
× Legacy octal escape is not permitted in strict mode
╭─[C:\Users\awabi\Desktop\Work\majaalis-al-ilm\server\node_modules\ffmpeg\lib\video.js:765:1]
765 │ settings.file_name = path.basename(settings.file_name, path.extname(settings.file
name)) + '%d.jpg';
766 │
767 │ // Create the directory to save the extracted frames
768 │ utils.mkdir(destinationFolder, 0777);
· ────
769 │
770 │ resetCommands(this);
771 │
╰────
Caused by:
Syntax Error
ERROR in ./src/utils/thumbnailExtraction.ts 125:0-20
Module not found: Error: Can't resolve 'fs' in 'C:\Users\awabi\Desktop\Work\majaalis-al-ilm\server\src\utils'
webpack compiled with 5 errors
Here is the errors I get when I start the server, with fluent-ffmpeg I get more but I will assume they are caused by the same thing
As a side thought, would using ffmpeg.wasm be a useful approach so it can be done on the client side at the time of upload? The benefits are that it would be snappier to generate the thumbnails, extract metadata etc. without waiting for a large video to upload first.
A huge benefit is simply not having to dedicate server resources to the task. Processing that can be offloaded to the client for has potential to reduce expenses (server resources). Ffmpeg isn't lightweight.
Thank you, I appreciate your help!
I’ll also look into ffmpeg.wasm
I haven’t looked into its docs yet, but could you give me a short idea of how would it work with payload?
When a user or admin uploads a video, will it allow me to get the video and thumbnail before complete upload?
Can you share what you ended with ?
Is your media is just videos or also images?
Star
Discord
online
Get dedicated engineering support directly from the Payload team.