How can I bundle ffmpeg in an Electron application
Asked Answered
B

3

9

I'm building an Electron application starting from the electron-webpack boilerplate.

I found this node module @ffmpeg-installer/ffmpeg which installs a compatible precompiled binary into the /node_modules directory then makes the path of that executable accessible through.

const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path

This works fine during development, but when I build the distributable and run it I get an error when attempting to spawn a child process with that path. Presumably, because the path does not point at the binary.

The path is set to the following when running the distributable.

/Users/me/project/dist/mac/AppName.app/Contents/Resources/app.asar/node_modules/@ffmpeg-installer/darwin-x64/ffmpeg

However, when looking in the AppName.app package contents I find the binary in the following path.

/Users/me/project/dist/mac/AppName.app/Contents/Resources/app.asar.unpacked/node_modules/@ffmpeg-installer/darwin-x64/ffmpeg

How should I include binary dependencies in an Electron application using electron-webpack and electron-builder?

Bartholomeus answered 16/12, 2017 at 18:11 Comment(0)
S
2

It's likely because electron will bundle the app in an asar archive (something like a zip/tar/jar). Hence, the path to the executable can't be resolved. Try passing asar: false to electron-builder (in electron-builder.json).

Sprag answered 16/12, 2017 at 18:15 Comment(3)
This works but I would like to know why the ASAR did not work. Is it because of the default asarUnpack option?Bartholomeus
⚠️ Packaging using asar archive is disabled — it is strongly not recommended. Please enable asar and use asarUnpack to unpack files that must be externally available.Bartholomeus
@JoshuaBarnett it's been a while since I encountered this - it seems like the asarUnpack/smartUnpack options are new to me. If you can get it to work, this seems like the better option - I was reluctant to use asar: false myself.Sprag
R
6

From here:

Install: npm i ffmpeg-static ffprobe-static

Include in your package.json:

build{
...
    "asarUnpack":[
        "node_modules/ffmpeg-static/bin/${os}/${arch}/ffmpeg",
        "node_modules/ffmpeg-static/index.js",
        "node_modules/ffmpeg-static/package.json"
        ]
    }

Set path in your JS:

const ffmpeg = require('fluent-ffmpeg');

//Get the paths to the packaged versions of the binaries we want to use
const ffmpegPath = require('ffmpeg-static').replace(
    'app.asar',
    'app.asar.unpacked'
);
const ffprobePath = require('ffprobe-static').path.replace(
    'app.asar',
    'app.asar.unpacked'
);

//tell the ffmpeg package where it can find the needed binaries.
ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg.setFfprobePath(ffprobePath);
Ruthieruthless answered 28/12, 2020 at 14:23 Comment(1)
I have never been able to get this to work. For one thing, the directory structure he has listed is wrong. ffmpeg-static only downloads the one needed for the specific build so there aren't separate folders. But even then it doesn't work and nothing ends up in the app.asar.unpacked location.Parrot
S
2

It's likely because electron will bundle the app in an asar archive (something like a zip/tar/jar). Hence, the path to the executable can't be resolved. Try passing asar: false to electron-builder (in electron-builder.json).

Sprag answered 16/12, 2017 at 18:15 Comment(3)
This works but I would like to know why the ASAR did not work. Is it because of the default asarUnpack option?Bartholomeus
⚠️ Packaging using asar archive is disabled — it is strongly not recommended. Please enable asar and use asarUnpack to unpack files that must be externally available.Bartholomeus
@JoshuaBarnett it's been a while since I encountered this - it seems like the asarUnpack/smartUnpack options are new to me. If you can get it to work, this seems like the better option - I was reluctant to use asar: false myself.Sprag
C
-1

MacOS:

  1. Find the executable file for ffmpeg
  2. Copy the executable file to root directory
  3. Add ffmpeg to package.json file
  4. Create and set path to ffmpeg in js file

package.json:

{
"build": {
    "asarUnpack": [
      "ffmpeg"
    ]
}

script.js:

const ffmpeg = require("fluent-ffmpeg");

const ffmpegPath = path.resolve(process.resourcesPath, "app.asar.unpacked/ffmpeg");

ffmpeg.setFfmpegPath(ffmpegPath);
Catfall answered 14/1 at 23:46 Comment(1)
Macos gatekeeper will block it.Strode

© 2022 - 2024 — McMap. All rights reserved.