ffmpegwasm / ffmpeg.wasm

FFmpeg for browser, powered by WebAssembly
https://ffmpegwasm.netlify.app
MIT License
13.45k stars 772 forks source link

ffmpeg.mount - ErrnoError: FS error #757

Open JohnRSim opened 3 weeks ago

JohnRSim commented 3 weeks ago

Describe the bug Getting the following error when trying to mount a file -

ErrnoError: FS error

try {
        // Mount the file using WORKERFS
        await ffmpeg.mount('WORKERFS', { files: [videoFile] }, '/mounted');
    } catch (error) {
        console.error('Error mounting file system:', error);
        return;
    }

To Reproduce Please provide a GitHub link or code snippet.

    let videoBuffer = new Uint8Array();
    // Process frames in chunks
    const chunkSize = 10; // Adjust chunk size based on memory constraints
    for (let i = 0; i < frames.length; i += chunkSize) {
        const chunkFrames = frames.slice(i, i + chunkSize);
        for (const frame of chunkFrames) {
            const planeData = new Uint8Array(config.width * config.height * 4); // Assuming RGBA format
            await frame.copyTo(planeData);
            videoBuffer = appendBuffer(videoBuffer, planeData);
            frame.close();
        }
    }
    // Create a Blob from the video buffer and a File object
    const videoBlob = new Blob([videoBuffer], { type: 'application/octet-stream' });
    const videoFile = new File([videoBlob], 'input.raw');

    // Mount the file using WORKERFS
    try {
        // Mount the file using WORKERFS
        await ffmpeg.mount('WORKERFS', { files: [videoFile] }, '/mounted');
    } catch (error) {
        console.error('Error mounting file system:', error);
        return;
    }

    const inputFileName = '/mounted/input.raw';
    const outputFileName = '/mounted/output.mp4';
    // const inputFileName = 'input.raw';
    // const outputFileName = 'output.mp4';

    //await ffmpeg.writeFile(inputFileName, videoBuffer);

    const args = [
        '-f', 'rawvideo',
        '-pix_fmt', 'rgba',
        '-s', `${config.width}x${config.height}`,
        '-r', `${config.framerate}`,
        '-i', `${inputFileName}`,
        '-c:v', 'libvpx-vp9',
        '-preset', 'ultrafast',
        '-profile:v', '0', // Profile 0 (vp09.00.10.08 corresponds to profile 0)
        '-b:v', '30M', // Reduced bitrate
        outputFileName
    ];
    console.log(...args);

    await ffmpeg.exec(args);

Expected behavior I run out of memory using await ffmpeg.writeFile(inputFileName, videoBuffer); so wanted to use the mount to process the videoframe buffer but I can't get it to work on the latest core-mt@0.12.6

Screenshots n/a

Desktop (please complete the following information):

stri8ed commented 3 weeks ago

Try creating the mounted dir, before mounting data to it.

await ffmpeg.createDir('/mounted');

JohnRSim commented 3 weeks ago

Thanks @stri8ed that was it!

Do you know if I need to setup permissions somehow for the ffmpeg output file?

I had to create a blank output file in mounted files otherwise I got /mounted/output.mp4: Operation not permitted from ffmpeg

        const videoBlob = new Blob([videoBuffer], { type: 'application/octet-stream' });
        const inputVideoFile = new File([videoBlob], 'input.raw');
        const outputVideoFile2 = new File([], 'output.mp4', { type: 'video/mp4' });

        const inputFileName = '/mounted/input.raw';
        const outputFileName = '/mounted/output.mp4';

    // encode
    try {
        //create mounted dir
        await ffmpeg.createDir('/mounted');

        // add file to workersfs
        await ffmpeg.mount('WORKERFS', { 
            files: [
                inputVideoFile,
                outputVideoFile2 
            ] }, '/mounted');

        //ffmpeg cmd
        const args = [
            '-f', 'rawvideo',
            '-pix_fmt', 'rgba',
            '-s', `${config.width}x${config.height}`,
            '-r', `${config.framerate}`,
            '-i', `${inputFileName}`,
            '-c:v', 'libx264',
            //'-preset', 'ultrafast',
            '-profile:v', '0', // Profile 0 (vp09.00.10.08 corresponds to profile 0)
            '-b:v', '30M', // Reduced bitrate
            outputFileName
        ];
        console.log(...args);

        await ffmpeg.exec(args);
        //await ffmpeg.exec(['-i', `${inputFileName}`, `${outputFileName}`]);

    } catch (error) {
        console.error('Error detected ', error);
        return;
    }

but now I'm getting the following I think it can't write to it?: Could not write header for output file #0 (incorrect codec parameters ?): I/O error benchmark.ts:163 Error initializing output stream 0:0 -- benchmark.ts:163 Conversion failed!

JohnRSim commented 3 weeks ago

ok I adjusted the ffmpeg cmd to output to webm which resolved the header output issue - But now I'm hitting Error writing trailer of /mounted/output.webm: I/O error

-f rawvideo -pix_fmt rgba -s 100x100 -r 60 -i /mounted/input.raw -c:v libvpx-vp9 -profile:v 0 -b:v 3000k /mounted/output.webm
benchmark.ts:163 ffmpeg version 5.1.4 Copyright (c) 2000-2023 the FFmpeg developers
benchmark.ts:163   built with emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.40 (5c27e79dd0a9c4e27ef2326841698cdd4f6b5784)
benchmark.ts:163   configuration: --target-os=none --arch=x86_32 --enable-cross-compile --disable-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --nm=emnm --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc --extra-cflags='-I/opt/include -O3 -msimd128 -sUSE_PTHREADS -pthread' --extra-cxxflags='-I/opt/include -O3 -msimd128 -sUSE_PTHREADS -pthread' --enable-gpl --enable-libx264 --enable-libx265 --enable-libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libopus --enable-zlib --enable-libwebp --enable-libfreetype --enable-libfribidi --enable-libass --enable-libzimg
benchmark.ts:163   libavutil      57. 28.100 / 57. 28.100
benchmark.ts:163   libavcodec     59. 37.100 / 59. 37.100
benchmark.ts:163   libavformat    59. 27.100 / 59. 27.100
benchmark.ts:163   libavdevice    59.  7.100 / 59.  7.100
benchmark.ts:163   libavfilter     8. 44.100 /  8. 44.100
benchmark.ts:163   libswscale      6.  7.100 /  6.  7.100
benchmark.ts:163   libswresample   4.  7.100 /  4.  7.100
benchmark.ts:163   libpostproc    56.  6.100 / 56.  6.100
benchmark.ts:163 [rawvideo @ 0xdec3e0] Estimating duration from bitrate, this may be inaccurate
benchmark.ts:163 Input #0, rawvideo, from '/mounted/input.raw':
benchmark.ts:163   Duration: 00:00:00.02, start: 0.000000, bitrate: 19199 kb/s
benchmark.ts:163   Stream #0:0: Video: rawvideo (RGBA / 0x41424752), rgba, 100x100, 19200 kb/s, 60 tbr, 60 tbn
benchmark.ts:163 Stream mapping:
benchmark.ts:163   Stream #0:0 -> #0:0 (rawvideo (native) -> vp9 (libvpx-vp9))
benchmark.ts:163 [libvpx-vp9 @ 0xe003e0] v1.13.1
benchmark.ts:163 Output #0, webm, to '/mounted/output.webm':
benchmark.ts:163   Metadata:
benchmark.ts:163     encoder         : Lavf59.27.100
benchmark.ts:163   Stream #0:0: Video: vp9 (Profile 0), yuva420p(tv, progressive), 100x100, q=2-31, 3000 kb/s, 60 fps, 1k tbn
benchmark.ts:163     Metadata:
benchmark.ts:163       encoder         : Lavc59.37.100 libvpx-vp9
benchmark.ts:163     Side data:
benchmark.ts:163       cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
benchmark.ts:163 frame=    1 fps=0.0 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A speed=   0x    
benchmark.ts:163 Error writing trailer of /mounted/output.webm: I/O error
benchmark.ts:163 frame=    1 fps=0.0 q=9.0 Lsize=       1kB time=00:00:00.00 bitrate=5488.0kbits/s speed=0.0161x    
benchmark.ts:163 video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 453.225800%
benchmark.ts:163 Error closing file /mounted/output.webm: I/O error
benchmark.ts:163 Aborted()
stri8ed commented 3 weeks ago

Try outputting the file in the root dir. e.g. /output.webm.