remotion icon indicating copy to clipboard operation
remotion copied to clipboard

Publish guidelines for making an Electron app

Open JonnyBurger opened this issue 2 years ago • 26 comments

Explain how to embed Remotion - and also FFmpeg and Chrome inside a Electron app.

JonnyBurger avatar Jun 19 '23 15:06 JonnyBurger

I'm currently building an Electron App and including a remotion bundle to render videos inside of it.

It already works pretty well when running the Electron app locally in dev mode but when bundling the Electron App I'm currently running into the following error: ENOENT: no such file or directory, mkdir '/node_modules/.ffmpeg'

I also tried to provide own ffmpeg and ffprobe executables but it didn't seem to help. Any hints on how to resolve this?

dsumer avatar Jun 29 '23 09:06 dsumer

@dsumer Let's only consider the v4 case, because it is the future.. in it, FFmpeg will not be in node_modules/.ffmpeg, but in the @remotion/compositor-* packages, where * is the architecture of the OS.

You should be able to bundle as normal, if you specify './compositor' as external dependency and then copy the contents of the compositor package.

Here are examples:

https://github.com/remotion-dev/remotion/blob/dd626e9c00ef9f3f700bc2a548fbff1df810cf77/packages/lambda/src/admin/bundle-lambda.ts#L27

https://github.com/UmungoBungo/remotion/blob/gcp-lambda-alternative/packages/cloudrun/src/admin/bundle-renderLogic.ts#L20

JonnyBurger avatar Jun 29 '23 12:06 JonnyBurger

I successfuly upgraded my app to Remotion v4 and now the integration into my Electron App seems more promising! :D

Already got a packaged version up and running but as soon as I'm packaging my app's source code using asar, I get the following error message: ENOTDIR: not a directory, chmod '.../electron/out/make/zip/darwin/arm64/electron.app/Contents/Resources/app.asar/node_modules/@remotion/compositor-darwin-arm64/compositor' .. so it seems that remotion is not able to resolve the compositor inside the asar package

I also tried to unpack just the compositor file from the asar package, but then it's also not working because remotion is still looking for the compositor inside the asar package and I guess there's no option to define another path to look for the Compositor package.

I'm a bit confused by your answer above because at the moment I'm using webpack to generate my remotion bundle (and include it into my electron app) .. and there I couldn't define the compositor as external correctly ... with the BundlerInternals.esbuild.build from your example above I get an invalid bundle (without .HTML files or static resources at all)

dsumer avatar Jul 10 '23 10:07 dsumer

@dsumer You need two bundles:

  • Your application code for Electron --> this one must exclude the compositor and add it again afterwards. It also does not necessarily need a index.html, or at least a different one for showing a GUI

  • The bundle of the Remotion code, which can be dynamic, also it can be created outside of the Electron app using bundle. This one should show "Remotion Bundle" at the top and can be used for rendering

JonnyBurger avatar Jul 10 '23 15:07 JonnyBurger

I guess the error you get is true, you use a chmod command for a directory? Can you show what you are trying to do?

JonnyBurger avatar Jul 10 '23 15:07 JonnyBurger

I got it working! 🥳

So yes, I confused the Remotion Bundle (which includes the actual Video written in Remotion) and my Bundle which renders the video using @remotion/renderer

Before I didn't even have a "real" bundle for my Electron specific code .. I just compiled my TypeScript code using tsc

Therefore I switched to esbuild for my Electron code aswell and there I had to:

  • Include @remotion/renderer in my esbuild bundle, but exclude all of its dependencies
  • Write a custom esbuild plugin to substitute all @remotion/compositor-* imports pointing to the directory outside of my app.asar package

So the @remotion/compositor-* get unpacked from the asar package (via the packagerConfig in my electron-forge config) and esbuild tells @remotion/renderer where to look for the compositor packages.

Hopefully I'll find the time to write an in-depth blog post for it soon, it may be helpful until official guidelines are published :)

dsumer avatar Jul 11 '23 07:07 dsumer

Some other issues I stumbled into after signing / notarizing the Electron MacOS app and distributing it to other machines:

  • @remotion/renderer does a chmod by default, which isn't allowed inside a packaged MacOS app (as it's a read only FS) .. I found that one can set the READ_ONLY_FS environment var to disable this behavior, which solved the problem: https://github.com/remotion-dev/remotion/blob/6d8d43a14b15b9a16b66a91184d530feae3c8cf4/packages/renderer/src/compositor/compositor.ts#L80
  • Additionally I needed to set several entitlements so that ffmpeg is allowed to execute external libs

But now it really seems to work, even on external MacOS machines :)

dsumer avatar Jul 12 '23 10:07 dsumer

That's sick, thanks for documenting! If we can make some code changes so it becomes less tedious, we would consider that.

JonnyBurger avatar Jul 13 '23 07:07 JonnyBurger

I'm encountering the same problem and couldn't find a beginner guide help me do this. I would really appreciate if anyone can point me into the right direct, especially @dsumer and @JonnyBurger, since you guy are experts in this area.

Thanks in advance.

What I want to archive is the do an as simple as possible task, which is:

  1. On the UI of the electron app have a button,
  2. When user click on it, the app will trigger remotion to render a already setup animation out as an mp4 video.

I already setup a project up with some initial example code and try to get it running.

My public repo for this: https://github.com/TuanManhCao/electron-remotion

A few things about this project, I setup this project using eletron-vite. And already setup some code to make the Say Hello button interact with main thread.

My guess is that I need to figure out a way to make the project's bundler to bundle all the remotion code and put it in out/main.js file and necessary binary like ffmpeg along the way. But I'm really noob in regarding how to write code for webpack and vite. And I guess the fact that my app using vite instead of webpack also make thing more difficult.

And then find a way to invoke renderMedia with right parameters and setup so that it will output the video as I wanted.

To make thing a little clearer I explain my thought and my setup in this video.

https://youtu.be/g2dVQo_9t7E

TuanManhCao avatar Oct 23 '23 08:10 TuanManhCao

Woohoo.

I managed to solve the problem myself. Checkout the repo for the latest code. I'll write up a guide once I have more time.

Here is the result.

CleanShot 2023-10-24 at 09 13 13

TuanManhCao avatar Oct 24 '23 02:10 TuanManhCao

@TuanManhCao Super nice! Thanks for posting this, will for sure be helpful for others too

JonnyBurger avatar Oct 24 '23 09:10 JonnyBurger

I hit another roadblock. Essentially, when it ran the code with yarn build the bundling code does not work any more. I think I'll need to do something like @dsumer .

In my case, I think since electron-vite use vite, the yarn dev will use esbuild to "bundling" codes and serve it to main process and renderer process. But when it come to build, or bundling it for distribution, vite use roll-up underneath to bundle everything.

So I think I might need to do something similar to Dominik, maybe use esbuild for both. Would appreciate any help you guys can provide 🙏 . I'll report back if I figure out anything.

TuanManhCao avatar Oct 30 '23 02:10 TuanManhCao

Updated the project to support build for distribution. My approach mostly similar to Dominik but a bit different when it comes to to modify the path to "@remotion/compositor". I decided to patch the remotion/render package to support electron. Check out the project I put in the previous comment.

Will make a video explaining how it was done. If I found time.

Note to build for distribution run

yarn build:mac

TuanManhCao avatar Nov 01 '23 07:11 TuanManhCao

We are refactoring how the binaries work from v4.0.97 on step by step.

This will make it easier in the end to copy the dependencies into the Electron app and we can probably publish a smooth way to do so (have not yet tried it yet though)

Until it is done, I recommend staying on 4.0.83 because the internals are changing from version to version.

JonnyBurger avatar Jan 24 '24 16:01 JonnyBurger

Thanks for the head up Jonny!

TuanManhCao avatar Jan 24 '24 16:01 TuanManhCao

In recent versions of Remotion, it has gotten a bit easier.

  • In the @remotion/compositor-* packages, there are a bunch of files:
    • For macOS: ffmpeg, ffprobe, remotion, *.dylib files
    • For Linux: ffmpeg, ffprobe, remotion, *.so files
    • For Windows: ffmpeg.exe, ffprobe.exe, remotion.exe, *.dll files
  • Those files should either be put:
    • Adjacent to the .js file that executes the SSR code
    • In a custom location that you can now specify with the binariesDirectory option, which is accepted by all SSR APIs

There is also a challenge to include the browser binaries and sign them. I recommend this message on Discord to find a possible solution! https://discord.com/channels/809501355504959528/817306238811111454/1213120432329203803

This is a good step forward, but we still want to make it easier and document a flow.

JonnyBurger avatar Mar 02 '24 09:03 JonnyBurger

Another sample project to check out: https://github.com/avibn/electron-vite-remotion Thanks @avibn!

JonnyBurger avatar Jul 22 '24 12:07 JonnyBurger