FFmpeg-wasm/FFmpeg.wasm

[Bug Report] memory access out of bounds on macOS

Closed this issue · 37 comments

How to use this package to add audio to a video. Like merging a background audio in a video? How can i do this in nodejs.

@DreamOfIce Can you please help?

Please refer to the document of ffmpeg: https://ffmpeg.org/ffmpeg.html

@DreamOfIce

Reel3.mp4 is a video and wolf-howl-6310.mp3 is the audio that i want to merge. What i tried?

import { readFile, writeFile } from "fs/promises";
import { FFmpeg } from "@ffmpeg.wasm/main";
import path from "path"; 

const currentDirectory = process.cwd();

const inputFilePath = path.join(currentDirectory, "Reel3.mp4"); 
const outputFilePath = path.join(currentDirectory, "Reel3.mp4"); 

const ffmpeg = await FFmpeg.create({ core: "@ffmpeg.wasm/core-mt" });

try {
  await ffmpeg.fs.writeFile("Reel3", await readFile(inputFilePath));
  await ffmpeg.run("-i", "wolf-howl-6310", "wolf-howl-6310.mp3");
  await writeFile(outputFilePath, ffmpeg.fs.readFile("Reel3.mp4"));
  console.log("Conversion successful!");
} catch (error) {
  console.error("Error:", error);
} finally {
  process.exit(0);
}

Have you written wolf-howl-6310.mp3 to the MEMFS?

@DreamOfIce Can you please give me an example to make things work🙏 Error [RuntimeError]: memory access out of bounds.

Please provide your system environment and node version.
Also please describe the problem accurately.Don't waste everyone's time!

@DreamOfIce using Node v20, Using macOS M2 , I'm trying to add audio to a video but when I try to do that its gives me that error the video is an mp4 file named Reel3.mp4 and the audio is an mp3 file named wolf-howl-6310.mp3 both the files are there in the root directory of my project.

Maybe you could upload the full log and your files for testing.
If they are secret, please try other files and upload them if problem still exists.

Full log is here

node:internal/event_target:1054
  process.nextTick(() => { throw err; });
                           ^
Error [RuntimeError]: memory access out of bounds
    at wasm://wasm/062891ca:wasm-function[147]:0x13f8a
    at wasm://wasm/062891ca:wasm-function[2213]:0x231e3d
    at wasm://wasm/062891ca:wasm-function[1334]:0x13bcdf
    at wasm://wasm/062891ca:wasm-function[424]:0x3627c
    at wasm://wasm/062891ca:wasm-function[1431]:0x14c3cc
    at wasm://wasm/062891ca:wasm-function[13157]:0xdf3543
    at wasm://wasm/062891ca:wasm-function[6565]:0x80264c
    at wasm://wasm/062891ca:wasm-function[4265]:0x499b46
    at wasm://wasm/062891ca:wasm-function[13065]:0xdeb3a5
    at wasm://wasm/062891ca:wasm-function[13077]:0xdeb7cc

Node.js v20.4.0

Please try upgrading to v20.5.0+, there are known issues with the wasm runtime on macOS in older versions.

same error again


node:internal/event_target:1054
  process.nextTick(() => { throw err; });
                           ^
Error [RuntimeError]: memory access out of bounds
    at wasm://wasm/062891ca:wasm-function[147]:0x13f8a
    at wasm://wasm/062891ca:wasm-function[2213]:0x231e3d
    at wasm://wasm/062891ca:wasm-function[1334]:0x13bcdf
    at wasm://wasm/062891ca:wasm-function[424]:0x3627c
    at wasm://wasm/062891ca:wasm-function[1431]:0x14c3cc
    at wasm://wasm/062891ca:wasm-function[13157]:0xdf3543
    at wasm://wasm/062891ca:wasm-function[6565]:0x80264c
    at wasm://wasm/062891ca:wasm-function[4265]:0x499b46
    at wasm://wasm/062891ca:wasm-function[13065]:0xdeb3a5
    at wasm://wasm/062891ca:wasm-function[13077]:0xdeb7cc

Node.js v20.5.1

Could you clone this repository and checkout tag 0.13.1 and then run the test with pnpm test?

Logs test passed


 ↓ tests/browser.test.ts (0) [skipped]
 ✓ tests/ffmpeg.test.ts (10) 449ms
 ✓ tests/convert.test.ts (40) 7507ms

 Test Files  2 passed | 1 skipped (3)
      Tests  50 passed (50)
   Start at  21:42:51
   Duration  7.91s (transform 89ms, setup 0ms, collect 311ms, tests 7.96s, environment 0ms, prepare 197ms)

await ffmpeg.fs.writeFile("Reel3", await readFile(inputFilePath));

Have you written wolf-howl-6310.mp3 to the memory fs like this?

await ffmpeg.run("-i", "wolf-howl-6310", "wolf-howl-6310.mp3");

Are you sure these parameters are really correct?

I'm sorry but I don't get you. I have wolf-howl-6310.mp3 file in my project like myProject -> wolf-howl-6310.mp3

@DreamOfIce Can you give me a example that work for you?

@stydxm Okay, so this example is to add audio to a video in nodejs right?

That's merging two videos. But it should also works if you replace one video with your audio.

@stydxm Unfortunately it gives to same error of Error [RuntimeError]: memory access out of bounds Any fix for this? or any other library that i can use that will do the job?

This maybe another MacOS-only issue. It works on my Windows computer with Node.js v20.5.1.
The origin project can do the job with browsers but not node.

@stydxm Can you please give me an example here? for browser?

Read its document, please!!!

@stydxm I tried this can you please check whats wrong using react + vite

import { useState, useRef } from "react";
import { FFmpeg } from "@ffmpeg/ffmpeg";
import { toBlobURL, fetchFile } from "@ffmpeg/util";

function App() {
  const [loaded, setLoaded] = useState(false);
  const ffmpegRef = useRef(new FFmpeg());
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const messageRef = useRef<HTMLParagraphElement | null>(null);

  const load = async () => {
    const baseURL = "https://unpkg.com/@ffmpeg/core-mt@0.12.2/dist/esm";
    const ffmpeg = ffmpegRef.current;
    ffmpeg.on("log", ({ message }) => {
      if (messageRef.current) messageRef.current.innerHTML = message;
    });
    // Load FFmpeg
    await ffmpeg.load({
      coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`, "text/javascript"),
      wasmURL: await toBlobURL(
        `${baseURL}/ffmpeg-core.wasm`,
        "application/wasm"
      ),
      workerURL: await toBlobURL(
        `${baseURL}/ffmpeg-core.worker.js`,
        "text/javascript"
      ),
    });
    setLoaded(true);
  };

  const transcode = async () => {
    const videoURL1 = "https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; // Replace with your video URLs
    const videoURL2 = "https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; // Replace with your video URLs
    const ffmpeg = ffmpegRef.current;

    // Write the input videos to temporary files
    await ffmpeg.writeFile("input1.webm", await fetchFile(videoURL1));
    await ffmpeg.writeFile("input2.webm", await fetchFile(videoURL2));

    // Interlace (blend) the two videos using the filter_complex option
    await ffmpeg.exec([
      "-i", "input1.webm",
      "-i", "input2.webm",
      "-filter_complex",
      "[0:v][1:v]blend=all_expr='A*(if(eq(0,N/2),1,T))+B*(if(eq(0,N/2),T,1))'",
      "output.mp4",
    ]);

    // Read the resulting MP4 file and display it
    const fileData = await ffmpeg.readFile('output.mp4');
    const data = new Uint8Array(fileData as ArrayBuffer);
    if (videoRef.current) {
      videoRef.current.src = URL.createObjectURL(
        new Blob([data.buffer], { type: 'video/mp4' })
      )
    }
  };

  return loaded ? (
    <>
      <video ref={videoRef} controls></video>
      <br />
      <button onClick={transcode}>Interlace and Save as MP4</button>
      <p ref={messageRef}></p>
    </>
  ) : (
    <button onClick={load}>Load ffmpeg-core</button>
  );
}

export default App;

It's not the deal of this project. Report it to the original project. Thank you for your cooperation!!!

@stydxm Unfortunately it gives to same error of Error [RuntimeError]: memory access out of bounds Any fix for this? or any other library that i can use that will do the job?

Please provide a minimum reproduction
You can use online tools IDE as stackblitz

@DreamOfIce Any updates about this issue?

I've been a busy lately, so I haven't had time to reply.

Can you replace src/routes/merge.js with the following and test again?

import express from "express";
const router = express.Router();
import { readFile, writeFile } from "fs/promises";
import { FFmpeg } from "@ffmpeg.wasm/main";
import path from "path";

const currentDirectory = process.cwd();

const inputFilePath = path.join(currentDirectory, "Reel3.mp4");
const inputFilePath1 = path.join(currentDirectory, "wolf-howl-6310.mp3");
const outputFilePath = path.join(currentDirectory, "Reel3-2.mp4");

const ffmpeg = await FFmpeg.create({ core: "@ffmpeg.wasm/core-mt", log: true });

try {
  ffmpeg.fs.writeFile("/Reel3.mp4", await readFile(inputFilePath));
  ffmpeg.fs.writeFile("/wolf-howl-6310.mp3", await readFile(inputFilePath1));
  console.log(ffmpeg.version);
  await ffmpeg.run(
    "-i",
    "/wolf-howl-6310.mp3",
    "-i",
    "/Reel3.mp4",
    "-c",
    "copy",
    "-map",
    "0:a:0",
    "-map",
    "1:v:0",
    "/Reel3-2.mp4"
  );
  await writeFile(outputFilePath, ffmpeg.fs.readFile("/Reel3-2.mp4"));
  console.log("Conversion successful!");
} catch (error) {
  console.error("Error:", error);
}

router.post("/", (req, res) => {});
export { router as Merge };

@DreamOfIce I get this logs

{
  main: '0.13.1',
  core: {
    version: 'v0.11.0-17-gf4361a7807',
    configuration: "--target-os=none --arch=x86_32 --enable-cross-compile --disable-x86asm --disable-inline-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --extra-cflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1' --extra-cxxflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1' --extra-ldflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1 -L/work/ffmpeg.wasm-core/build/lib' --pkg-config-flags=--static --nm=llvm-nm --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc --enable-gpl --enable-nonfree --enable-zlib --enable-libx264 --enable-libx265 --enable-libvpx --enable-libwavpack --enable-libmp3lame --enable-libfdk-aac --enable-libtheora --enable-libvorbis --enable-libfreetype --enable-libopus --enable-libwebp --enable-libass --enable-libfribidi",
    libs: {
      libavutil: '56.51.100',
      libavcodec: '58.91.100',
      libavformat: '58.45.100',
      libavdevice: '58.10.100',
      libavfilter: '7.85.100',
      libswscale: '5.7.100',
      libswresample: '3.7.100',
      libpostproc: '55.7.100'
    },
    raw: 'ffmpeg version v0.11.0-17-gf4361a7807 Copyright (c) 2000-2020 the FFmpeg developers\n' +
      'built with emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.43 (a6b8143cf3c1171db911750359456b15a8deece7)\n' +
      "configuration: --target-os=none --arch=x86_32 --enable-cross-compile --disable-x86asm --disable-inline-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --extra-cflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1' --extra-cxxflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1' --extra-ldflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1 -L/work/ffmpeg.wasm-core/build/lib' --pkg-config-flags=--static --nm=llvm-nm --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc --enable-gpl --enable-nonfree --enable-zlib --enable-libx264 --enable-libx265 --enable-libvpx --enable-libwavpack --enable-libmp3lame --enable-libfdk-aac --enable-libtheora --enable-libvorbis --enable-libfreetype --enable-libopus --enable-libwebp --enable-libass --enable-libfribidi\n" +
      'libavutil      56. 51.100 / 56. 51.100\n' +
      'libavcodec     58. 91.100 / 58. 91.100\n' +
      'libavformat    58. 45.100 / 58. 45.100\n' +
      'libavdevice    58. 10.100 / 58. 10.100\n' +
      'libavfilter     7. 85.100 /  7. 85.100\n' +
      'libswscale      5.  7.100 /  5.  7.100\n' +
      'libswresample   3.  7.100 /  3.  7.100\n' +
      'libpostproc    55.  7.100 / 55.  7.100\n' +
      'Successfully parsed a group of options.\n' +
      'Parsing a group of options: output url ffmpeg.\n' +
      'Successfully parsed a group of options.\n' +
      'Opening an output file: ffmpeg.\n' +
      "Unable to find a suitable output format for 'ffmpeg'\n" +
      'ffmpeg: Invalid argument\n' +
      "Output #0, (null), to '(null)':\n" +
      'Output file #0 does not contain any stream\n' +
      'No input streams but output needs an input stream\n'
  }
}

@DreamOfIce I get this logs


{

  main: '0.13.1',

  core: {

    version: 'v0.11.0-17-gf4361a7807',

    configuration: "--target-os=none --arch=x86_32 --enable-cross-compile --disable-x86asm --disable-inline-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --extra-cflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1' --extra-cxxflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1' --extra-ldflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1 -L/work/ffmpeg.wasm-core/build/lib' --pkg-config-flags=--static --nm=llvm-nm --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc --enable-gpl --enable-nonfree --enable-zlib --enable-libx264 --enable-libx265 --enable-libvpx --enable-libwavpack --enable-libmp3lame --enable-libfdk-aac --enable-libtheora --enable-libvorbis --enable-libfreetype --enable-libopus --enable-libwebp --enable-libass --enable-libfribidi",

    libs: {

      libavutil: '56.51.100',

      libavcodec: '58.91.100',

      libavformat: '58.45.100',

      libavdevice: '58.10.100',

      libavfilter: '7.85.100',

      libswscale: '5.7.100',

      libswresample: '3.7.100',

      libpostproc: '55.7.100'

    },

    raw: 'ffmpeg version v0.11.0-17-gf4361a7807 Copyright (c) 2000-2020 the FFmpeg developers\n' +

      'built with emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.43 (a6b8143cf3c1171db911750359456b15a8deece7)\n' +

      "configuration: --target-os=none --arch=x86_32 --enable-cross-compile --disable-x86asm --disable-inline-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --extra-cflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1' --extra-cxxflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1' --extra-ldflags='-O3 --closure=1 -I/work/ffmpeg.wasm-core/build/include -s USE_PTHREADS=1 -L/work/ffmpeg.wasm-core/build/lib' --pkg-config-flags=--static --nm=llvm-nm --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc --enable-gpl --enable-nonfree --enable-zlib --enable-libx264 --enable-libx265 --enable-libvpx --enable-libwavpack --enable-libmp3lame --enable-libfdk-aac --enable-libtheora --enable-libvorbis --enable-libfreetype --enable-libopus --enable-libwebp --enable-libass --enable-libfribidi\n" +

      'libavutil      56. 51.100 / 56. 51.100\n' +

      'libavcodec     58. 91.100 / 58. 91.100\n' +

      'libavformat    58. 45.100 / 58. 45.100\n' +

      'libavdevice    58. 10.100 / 58. 10.100\n' +

      'libavfilter     7. 85.100 /  7. 85.100\n' +

      'libswscale      5.  7.100 /  5.  7.100\n' +

      'libswresample   3.  7.100 /  3.  7.100\n' +

      'libpostproc    55.  7.100 / 55.  7.100\n' +

      'Successfully parsed a group of options.\n' +

      'Parsing a group of options: output url ffmpeg.\n' +

      'Successfully parsed a group of options.\n' +

      'Opening an output file: ffmpeg.\n' +

      "Unable to find a suitable output format for 'ffmpeg'\n" +

      'ffmpeg: Invalid argument\n' +

      "Output #0, (null), to '(null)':\n" +

      'Output file #0 does not contain any stream\n' +

      'No input streams but output needs an input stream\n'

  }

}

Sorry, I forgot to delete console.log(ffmpeg.version);

@DreamOfIce Hey, It works fine, thanks. But I do have a question will doing this affect the video quality?

Please check the ffmpeg documentation: https://ffmpeg.org/documentation.html

Can we close this issue?

@DreamOfIce I'm getting this error "Error: Error: Cannot find module '@ffmpeg.wasm/core-mt', When my code is deployed on Vercel (Node.js + TypeScript) Does I get confused because when I try to run the same code on my local machine it works fine

But as I deploy it on Vercel it gives that error. Obviously, i do have "@ffmpeg.wasm/core-mt" installed as said in the package https://github.com/FFmpeg-wasm/FFmpeg.wasm#installation So how do I fix it?

Is there any other way to do the way?

I'm currently using it like this

import { FFmpeg } from "@ffmpeg.wasm/main";

async function myFunction() {
    const ffmpeg = await FFmpeg.create({
        core: "@ffmpeg.wasm/core-mt",
        log: true,
    });
}

However, in the docs, i see doing like this

  import { FFmpeg } from "@ffmpeg.wasm/main";
    
     const ffmpeg = await FFmpeg.create({
            core: "@ffmpeg.wasm/core-mt",
            log: true,
        });

    async function myFunction() {
        // use ffmpeg here
    }

@xts-bit - Vercel does not know how to copy the wasm file over to the serverless functions. You must explicitly move the file in after build, before deploy. Very silly but I spent a whole day on this issue. The fix is here: https://github.com/syntaxfm/website/blob/main/why_do_i_need_this.mjs