关于如何将像imagemagick这样的第三方预编译二进制文件包含到电子应用程序中,是否有很好的解决方案?有node.js模块,但它们都是包装程序或与系统范围内已安装库的本地绑定。我想知道是否可以在发行版中捆绑预编译的二进制文件。
请参阅 下面的 UPDATE (此方法现在并不理想)。
我确实找到了解决方案,但是我不知道这是否被视为最佳实践。我找不到包含第三方预编译二进制文件的任何好的文档,因此我一直在弄弄它直到最终与我的ffmpeg二进制文件一起使用。这是我做的(从电子快速入门,node.js v6开始):
Mac OS X方法
在app目录中,我在终端中运行以下命令以将ffmpeg二进制文件包含为模块:
mkdir node_modules/ffmpeg cp /usr/local/bin/ffmpeg node_modules/ffmpeg/ cd node_modules/.bin ln -s ../ffmpeg/ffmpeg ffmpeg
(替换/usr/local/bin/ffmpeg为当前的二进制路径,请从此处下载)放置链接可使电子包装程序包括我保存到的二进制文件node_modules/ffmpeg/。
/usr/local/bin/ffmpeg
node_modules/ffmpeg/
然后获取捆绑的应用程序路径(以便我可以为二进制文件使用绝对路径…不管我做什么,相对路径似乎都不起作用),我通过运行以下命令安装了npm软件包app- root-dir命令:
npm i -S app-root-dir
现在有了根应用程序目录,我只需为二进制文件附加子文件夹并从那里生成。这是我放在renderer.js中的代码:
var appRootDir = require('app-root-dir').get(); var ffmpegpath=appRootDir+'/node_modules/ffmpeg/ffmpeg'; console.log(ffmpegpath); const spawn = require( 'child_process' ).spawn, ffmpeg = spawn( ffmpegpath, ['-i',clips_input[0]]); //add whatever switches you need here ffmpeg.stdout.on( 'data', data => { console.log( `stdout: ${data}` ); }); ffmpeg.stderr.on( 'data', data => { console.log( `stderr: ${data}` ); });
Windows方法
打开电子基础文件夹(electron-quick-start是默认名称),然后进入node_modules文件夹。在此处创建一个名为ffmpeg的文件夹,然后将静态二进制文件复制到该目录中。注意:它必须是二进制文件的静态版本,因为ffmpeg我在这里获取了最新的Windows版本。
为了获取捆绑的应用程序路径(以便我可以为二进制文件使用绝对路径…不管我做什么,相对路径似乎都不起作用),我通过运行以下命令安装了npm包app-root-dir从我的应用目录中的命令提示符:
在您的node_modules文件夹中,导航到.bin子文件夹。您需要在此处创建几个文本文件,以告知节点包括刚复制的二进制exe文件。使用您喜欢的文本编辑器并创建两个文件,其中一个文件的名称ffmpeg如下:
ffmpeg
#!/bin/sh basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") case `uname` in *CYGWIN*) basedir=`cygpath -w "$basedir"`;; esac if [ -x "$basedir/node" ]; then "$basedir/node" "$basedir/../ffmpeg/ffmpeg" "$@" ret=$? else node "$basedir/../ffmpeg/ffmpeg" "$@" ret=$? fi exit $ret
第二个文本文件名为ffmpeg.cmd:
ffmpeg.cmd
@IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\..\ffmpeg\ffmpeg" %* ) ELSE ( @SETLOCAL @SET PATHEXT=%PATHEXT:;.JS;=;% node "%~dp0\..\ffmpeg\ffmpeg" %* )
接下来,您可以按以下步骤在Windows电子发行版(位于renderer.js中)中运行ffmpeg(我也使用了app-root- dir节点模块)。请注意添加到二进制路径中的引号,如果您的应用安装到带有空格的目录(例如C:\Program Files\YourApp),则没有这些空格将无法使用。
C:\Program Files\YourApp
var appRootDir = require('app-root-dir').get(); var ffmpegpath = appRootDir + '\\node_modules\\ffmpeg\\ffmpeg'; const spawn = require( 'child_process' ).spawn; var ffmpeg = spawn( 'cmd.exe', ['/c', '"'+ffmpegpath+ '"', '-i', clips_input[0]]); //add whatever switches you need here, test on command line first ffmpeg.stdout.on( 'data', data => { console.log( `stdout: ${data}` ); }); ffmpeg.stderr.on( 'data', data => { console.log( `stderr: ${data}` ); });
更新:统一的简单方法
嗯,随着时间的推移和Node的更新,这种方法不再是包含预编译二进制文件的最简单方法。它仍然有效,但是npm install运行时,node_modules下的二进制文件夹将被删除,必须再次替换。以下方法适用于Node v12。
npm install
此新方法消除了符号链接的需要,并且在Mac和Windows中也类似地工作。相对路径现在似乎有效。
您仍然需要appRootDir: npm i -S app-root-dir
bin在我ffmpeg的示例中,在应用程序的根目录下创建一个名为的文件夹,并将预编译的静态二进制文件放在此处。
bin
在渲染器脚本中使用以下代码:
const appRootDir = require('app-root-dir').get(); const ffmpegpath = appRootDir + '/bin/ffmpeg'; const spawn = require( 'child_process' ).spawn; const child = spawn( ffmpegpath, ['-i', inputfile, 'out.mp4']); //add whatever switches you need here, test on command line first child.stdout.on( 'data', data => { console.log( `stdout: ${data}` ); }); child.stderr.on( 'data', data => { console.log( `stderr: ${data}` ); });