Publish guidelines for making an Electron app
Explain how to embed Remotion - and also FFmpeg and Chrome inside a Electron app.
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 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
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 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
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?
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/rendererin my esbuild bundle, but exclude all of its dependencies - Write a custom
esbuildplugin to substitute all@remotion/compositor-*imports pointing to the directory outside of myapp.asarpackage
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 :)
Some other issues I stumbled into after signing / notarizing the Electron MacOS app and distributing it to other machines:
-
@remotion/rendererdoes achmodby default, which isn't allowed inside a packaged MacOS app (as it's a read only FS) .. I found that one can set theREAD_ONLY_FSenvironment 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 :)
That's sick, thanks for documenting! If we can make some code changes so it becomes less tedious, we would consider that.
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:
- On the UI of the electron app have a button,
- 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
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.
@TuanManhCao Super nice! Thanks for posting this, will for sure be helpful for others too
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.
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
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.
Thanks for the head up Jonny!
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,*.dylibfiles - For Linux:
ffmpeg,ffprobe,remotion,*.sofiles - For Windows:
ffmpeg.exe,ffprobe.exe,remotion.exe,*.dllfiles
- For macOS:
- 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
binariesDirectoryoption, 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.
Another sample project to check out: https://github.com/avibn/electron-vite-remotion Thanks @avibn!