reactjs – How to fix ‘ffmpeg.load() failed to fetch’ TypeError?

I’m trying to create a function that adds a text watermark to a video in Next.js using ffmpeg and I’m keep running into the same error and I’ve no idea how to fix it.

TypeError: Failed to fetch
await ffmpeg.load();

No errror in code, error only occurs in browser after I click Add Watermark button.

Server component: app/api/addwatermark.ts

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

const ffmpeg = createFFmpeg({ log: true });

export default async function addWatermark(
  inputFile: File,
  text: string
): Promise<string> {
  if (!ffmpeg.isLoaded()) {
    await ffmpeg.load();
    // Error ☝️
  }

  ffmpeg.FS('writeFile', inputFile.name, await fetchFile(inputFile));

  await ffmpeg.run(
    '-i',
    inputFile.name,
    '-filter_complex',
    `drawtext=text="${text}":fontfile=Arial.ttf:fontcolor=white@0.8:fontsize=40:x=(w-text_w)/2:y=(h-text_h)/2`,
    'output.mp4'
  );

  const data = ffmpeg.FS('readFile', 'output.mp4');

  const videoUrl = URL.createObjectURL(
    new Blob([data.buffer], { type: 'video/mp4' })
  );

  return videoUrl;
}

Client componenet:

export default function VideoWatermark() {
  const [inputFile, setInputFile] = useState<File>();
  const [outputFile, setOutputFile] = useState<string>();
  const [text, setText] = useState<string>('');

  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    if (event.target.files && event.target.files.length > 0) {
      setInputFile(event.target.files[0]);
      setOutputFile(undefined);
    }
  };

  const handleWatermark = async () => {
    if (!inputFile) {
      return;
    }
    const output = await addWatermark(inputFile, text);
    setOutputFile(output);
  };

  return (
    <div>
      <input type="file" onChange={handleFileChange} />
      <br />
      <input
        value={text}
        type="text"
        onChange={(event) => setText(event.target.value)}
      />
      <br />
      <button onClick={handleWatermark}>Add Watermark</button>
      {outputFile && (
        <div>
          <video controls>
            <source src={outputFile} type="video/mp4" />
          </video>
        </div>
      )}
    </div>
  );
}

Read more here: Source link