ffmpeg.wasm icon indicating copy to clipboard operation
ffmpeg.wasm copied to clipboard

Request for appendFile method

Open StephDam opened this issue 1 year ago • 4 comments

Hi,

I try to optimize the time to load big files. For the moment, I follow a 2 step approach :+1:

  • First I read the input file in a memory buffer (UINT8Array)
  • Then I write the contents of the buffer to FFMPEG fs using ffmpeg.FS.writeFile method.

However I think it would be faster reading the source file into chunks with File Stream Reader and then writes directly these chunks in append mode to the FS object.

Unfortunately ffmpeg.FS does not expose the appendFile method, or even better it would be great to have a File Stream Writer.

Thanks, Stéphane

StephDam avatar Nov 25 '24 11:11 StephDam

slammed for time now but - if you get a patch up i'm happy to review / build / include!

lucasgelfond avatar Jan 13 '25 22:01 lucasgelfond

Use ffmpeg.mount('WORKERFS' ...

It will work with the file directly on your machine without copying it to memory

Check my example app: https://github.com/pavloshargan/quicksplit

pavloshargan avatar Feb 03 '25 01:02 pavloshargan

I would love to have this as well. emscripten supports appendFile correctly, it will be great if the ffmpeg api supports it directly

dahmadjid avatar Feb 03 '25 02:02 dahmadjid

@pavloshargan 👍

WORKERFS is the best way right now to use large files for input. The file is not read into memory all at once and is not copied before use.

Example

const transcodePicker = async () => {
    let fileHandle;
    const pickerOpts = {
        types: [
            {
                description: "Videos",
                accept: {
                    "video/*": [".mp4", ".m4v", ".webm", ".avi", ".mkv", ".mov", ".wmv"],
                },
            },
        ],
        excludeAcceptAllOption: true,
        multiple: false,
    };
    [fileHandle] = await window.showOpenFilePicker(pickerOpts);
    let file = await fileHandle.getFile();
    const inputDir = '/input';
    const inputFile = `${inputDir}/${file.name}`;
    await ffmpeg.createDir(inputDir);
    await ffmpeg.mount('WORKERFS', {
        files: [ file ],
    }, inputDir);
    await ffmpeg.exec(['-i', inputFile, 'output.mp4']);
    const output = await ffmpeg.readFile('output.mp4');
    videoEl.src = URL.createObjectURL(new Blob([output.buffer], { type: 'video/mp4' }));
    await ffmpeg.unmount(inputDir);
    await ffmpeg.deleteDir(inputDir);
};

LostBeard avatar Feb 18 '25 02:02 LostBeard