ffmpegwasm / ffmpeg.wasm

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

Add WORKERFS support #581

Closed LostBeard closed 9 months ago

LostBeard commented 10 months ago

I'm not sure if this is of interest but I have enabled support for WORKERFS mounting and unmounting. I am still learning GitHub. If there is an issue with my pull request please let me know. Thank you for the awesome work.

Quick example that uses WORKERFS for the input file.

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);
};
netlify[bot] commented 10 months ago

Deploy Preview for ffmpegwasm canceled.

Name Link
Latest commit 0a03d39fa7251b840df89aa2f0f8747fab2f5a61
Latest deploy log https://app.netlify.com/sites/ffmpegwasm/deploys/6501c9743162fa0008f1367b
LostBeard commented 10 months ago

Just updated the branch for this pull request to support calling ffmpeg.mount() with the name of the filesystem type to mount so that it can support any additional filesystems that may be enabled for the build. I also updated my usage example in the first post here.

LostBeard commented 9 months ago

Simple demo of a Blazor WASM app using ffmpeg.wasm with WORKERFS via this code.

jeromewu commented 9 months ago

LGTM, thanks!

ashuvssut commented 2 months ago

I think WORKERFS uses File System Web API internally.

if I am not wrong with what I said above, then I think WORKERFS might not work correctly in Firefox or Safari because File System web API is not fully supported in these two browsers If that's the case, do we use RAM for fallback?

LostBeard commented 2 months ago

@ashuvssut You are wrong in your guess about WORKERFS not working in Firefox. WORKERFS in ffmpeg.wasm via Firefox works just fine, and can be easily verified by using the link I provided above to demo WORKERFS before it was merged.

WORKERFS is optional, not the default, and you have to manually use it in your code. Just like any other development, code, test, fix.

What is YOUR issue and what does it have to do with THIS pull request for an optional feature?

If that's the case, do we use RAM for fallback?

Start by getting some code working using the basic examples provided. When you actually have a problem and not just a guess about compatibility, we are here to help provided you offer up sufficient details.

LostBeard commented 2 months ago

@ashuvssut WORKERFS

ashuvssut commented 2 months ago

WORKERFS is optional,

Oh I didnt know that. Thankyou very much for this implementation. Is this also fully working on Safari?

What is YOUR issue and what does it have to do with THIS pull request for an optional feature?

I want to just process large video files using ffmpeg wasm

LostBeard commented 2 months ago

Is this also fully working on Safari?

Safari for what OS?

Safari on iOS is significantly different than Safari on OSx. I have neither at this time so I cannot answer that. You will have to test on Safari to determine compatibility.

I want to just process large video files using ffmpeg wasm

Cool beans. That is why WORKERFS was added. 👍

ashuvssut commented 2 months ago

Safari for what OS?

OSx only.


Update on my tests with Safari on OSX

I am trying to test with a 19GB mkv file to convert to mp4 on Safari

Memory consumption seems to be steadily increasing. Does this mean that the RAM is being used instead of WORKERFS?

Here's the last screenshot of the devtools

20mins taken for processing. RAM consumption steadily increased from 1.32GB to 1.76GB. Total transcoded video duration is 214secs

https://github.com/ffmpegwasm/ffmpeg.wasm/assets/60546840/22246a21-0ca6-44a0-be04-7f398a605244

ashuvssut commented 2 months ago

On FireFox, i took these memory snapshots for 10 mins. Seems consistent at 66-67MB usage. Maybe on Firefox we are actually using WORKERFS. Sorry, I am not sure if this is the best way to test this or not😅

image
LostBeard commented 2 months ago

When WORKERFS is used, it allows mounting File or Blob objects into a virtual folder ffmpeg.wasm can read directly from. Without it, you need to copy all of the input files into the default file system MEMFS, an in-memory file system.

WORKERFS files are read only and can only be used for ffmpeg.wasm's input.

ffmpeg.wasm will still use the default file system (MEMFS) for writing the output. This could be causing the increase in memory over time you are seeing.

I updated my Blazor WASM ffmpeg.wasm demo. It now uses the current release version of ffmpeg.wasm and I added a checkbox for toggling WORKERFS on or off.

LostBeard commented 2 months ago

The processing is all being done in workers. Are both browsers showing memory usage for those also?

KyGuy2002 commented 1 month ago

Hey, thanks for all this awesome work LostBeard!

I am looking into this, and wondering how this would let you download or view the output file? If WORKERFS allows mounting files greater than 2gb, but is read only, then wouldnt ffmpeg write the output into MEMFS, which would also be more than 2gb?

Is this limitation for specific files, or total size?

I apologize if I missed something. Thanks!

LostBeard commented 1 month ago

Correct. Adding WORKERFS allows using very large files as input without having to load the entire file into memory, and is read-only. The output is still written to MEMFS. Depending on what you are trying to do, output size may not be an issue. If you are just creating a GIF from a small section of a very large video MEMFS is fine.

Maybe IDBFS could be added as an alternative to MEMFS. I have not had a chance to look into it much yet.

LostBeard commented 1 month ago

I do not know what the exact limitations are in terms of GB and input. I would imagine that also depends on what you are trying to do in terms of processing.

KyGuy2002 commented 1 month ago

Thanks for the info. I was able to get WORKERFS working for the input using your example above, but I am trying to concat many clips together so the output file will always be large. Do you know if it's currently possible at all with WASM to do this?

I was reading a little about streaming/chunk the output from WASM to JS, but not sure the details or if that's even possible?

Thank you!

jj449 commented 6 days ago

@LostBeard Thank you so much !