Electron录制应用-打包静态文件问题【命令行ffmpeg导不出视频】

问题描述

在开发环境下,所有功能都运行正常,但一旦进行打包并运行生产环境的版本,导出mp4视频的功能就失效了。没有文件生成,也没有任何错误提示。

排查问题

为了找到问题的根源,我首先决定通过日志来追踪。我使用了winston和winston-daily-rotate-file这两个强大的日志库来记录应用程序的运行信息。通过分析日志,我发现了一个关键的线索:

ffmpeg(一个用于处理多媒体内容的开源库)没有被正确地打包进最终的产品中。

复制代码
const { createLogger, format, transports } = require("winston");
require("winston-daily-rotate-file");
const { app } = require('electron');
const path = require('path');
const fs = require('fs');

const logDir = path.join(app.getPath('userData'), 'logs');

if (!fs.existsSync(logDir)) {
  try {
    fs.mkdirSync(logDir);
  } catch (error) {
    console.error('Failed to create logs directory:', error);
  }
}


const customFormat = format.combine(
    format.timestamp({ format: "MMM-DD-YYYY HH:mm:ss" }),
    format.align(),
    format.printf((i: { level: any; timestamp: any; message: any; }) => `${i.level}: ${[i.timestamp]}: ${i.message}`)
);
const defaultOptions = {
    format: customFormat,
    datePattern: "YYYY-MM-DD",
    zippedArchive: true,
    maxSize: "20m",
    maxFiles: "14d",
};
const globalLogger = createLogger({
    format: customFormat,
    transports: [
        new transports.DailyRotateFile({
            filename: logDir + "/info-%DATE%.log",
            level: "info",
            ...defaultOptions,
        }),
        new transports.DailyRotateFile({
            filename:  logDir + "/error-%DATE%.log",
            level: "error",
            ...defaultOptions,
        }),
    ],
});

export default globalLogger

尝试解决(方案一:失败)

我首先尝试使用webpack的copy-webpack-plugin插件将ffmpeg复制到dist/main/bin目录下。然而,即使这样做了,问题依然没有得到解决。

成功解决(方案二)

经过深思熟虑,我意识到问题的关键在于如何让打包后的程序能够找到ffmpeg文件。于是,我采取了以下步骤:

放置ffmpeg文件:我将ffmpeg的文件放置在项目的assets文件夹中。

配置打包参数:在package.json文件中,我配置了extraResources选项,以确保assets文件夹中的文件能够被打包进去。

复制代码
// package.json 配置extraResources  
"extraResources": [  
  "./assets/**"  
]

获取ffmpeg的路径:在代码中,我根据运行平台(如Windows、Mac或Linux)和架构(如x64或arm64)动态地生成ffmpeg的路径。

复制代码
// 查找assets中ffmpeg的输出路径  
var os = require('os');  
var path = require('path');  
  
var platform = os.platform();  
// 适配electron-builder的智能构建过程  
if (platform === 'darwin') {  
  platform = 'mac';  
} else if (platform === 'win32') {  
  platform = 'win';  
}  
  
// ...(其他平台判断和架构检查代码省略)  
  
var ffmpegPath = (dirname: string) => path.join(  
  dirname,  
  'ffmpeg-exe',  
  'bin',  
  platform,  
  arch,  
  platform === 'win' ? 'ffmpeg.exe' : 'ffmpeg'  
);  
export default ffmpegPath;

执行命令行:最后,我使用Node.js的child_process模块中的exec函数来执行ffmpeg的命令行。

复制代码
const { exec } = require('child_process');  
exec(command);

注意事项

在生成日志文件夹时,我遇到了读写权限的问题。为了避免这个问题,我使用了Electron的app.getPath('userData')方法来获取应用程序内部的文件路径,这些路径通常都具有读写权限。

复制代码
const { app } = require('electron');  
const logDir = path.join(app.getPath('userData'), 'logs');

总结

一直要有日志!!

相关推荐
2501_920931703 小时前
React Native鸿蒙跨平台采用ScrollView的horizontal属性实现横向滚动实现特色游戏轮播和分类导航
javascript·react native·react.js·游戏·ecmascript·harmonyos
0思必得05 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5165 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino5 小时前
图片、文件的预览
前端·javascript
2501_920931707 小时前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
layman05287 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔7 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李7 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN8 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒8 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局