75lb / handbrake-js

Video encoding / transcoding / converting for node.js
Other
550 stars 69 forks source link

Does not work on Electron prod build #34

Closed jpangelle closed 5 years ago

jpangelle commented 5 years ago

Using hbjs.spawn in Electron dev environment works fine, but with the built Electron prod app, it goes to the .on('error') block. I've written the error message to a file:

  "err": {
    "message": "spawn ENOTDIR",
    "name": "InvalidOption",
    "output": "",
    "options": {
      "input": <valid-file-path>,
      "preset": "General/Fast 1080p30",
      "output": <valid-file-path>
    }
  }

Has anyone else used this library in an Electron prod build?

75lb commented 5 years ago

Hi, I'll have a go a reproducing this tonight..

jpangelle commented 5 years ago

@75lb, I dug deeper and I found the exact line that it breaks: https://github.com/75lb/handbrake-js/blob/master/lib/Handbrake.js#L80

const handle = this.cp.spawn(this.HandbrakeCLIPath, spawnArgs)

I think it is something with using the child_process.spawn as this method has been reported by several people to give problems in Electron apps (Google "child process spawn electron"). I am still searching for a workaround. Hope that information helps. Also, this library is great! Thanks.

jpangelle commented 5 years ago

I got it working. There were a few things I needed to change. I will just document it here in case anyone in the future has problems using this library with Electron.

  1. So, I had to change this.cp.spawn to exec, but first I had to reconstruct the command string to make sure it had quotes around my preset which has a space in it. Don't forget to const { exec } = require('child_process'); at the top of the file. You can see my changes here.

  2. For a reason that I do not quite understand yet but found on some StackOverflow posts is that you need to do a regex replace 'app.asar' to 'app.asar.unpacked'. You can see my implementation here.

As far as I know, these are both Electron production-build specific problems/solutions. Feel free to contact me if you have issues. Thanks again to @75lb for such a great library! 🎉

75lb commented 5 years ago

Cool, thanks for documenting the workaround.

  1. Would it be easier to use the handbrake-js exec() method?
akcware commented 3 years ago

@jpangelle Thanks for code, I was researching for 5 days and never find a way. But your exec function didn't worked me. So I did below.

Your code:

this._emitStart()

const newHandbrakeCLIPath = this.HandbrakeCLIPath.replace('app.asar', 'app.asar.unpacked');
const newCommand = `${newHandbrakeCLIPath} ${spawnArgs[0]} ${spawnArgs[1].split('=')[0]}='General/Fast 1080p30' ${spawnArgs[2]}`
 const handle = exec(newCommand);

My code:

this._emitStart()
const newHandbrakeCLIPath = this.HandbrakeCLIPath.replace('app.asar', 'app.asar.unpacked');
const handle = this.cp.spawn(newHandbrakeCLIPath, spawnArgs)

The important point was replacing app.asar to app.asar.unpacked. If someone had this problem, he can use my code.