mac上传视频时报 cannot find ffprobe是什么问题
mac怎么部署啊
`import ffmpeg from 'fluent-ffmpeg' import path from 'path' import fs from 'fs' import log from '../logger.js'
function initFFmpeg() { const ffmpegPath = { 'development-win32': path.join(__dirname, '../../resources/ffmpeg/win-amd64/bin/ffmpeg.exe'), 'development-linux': path.join(__dirname, '../../resources/ffmpeg/linux-amd64/ffmpeg'), 'development-darwin': '/opt/homebrew/bin/ffmpeg', 'production-win32': path.join( process.resourcesPath, 'app.asar.unpacked', 'resources', 'ffmpeg', 'win-amd64', 'bin', 'ffmpeg.exe' ), 'production-linux': path.join( process.resourcesPath, 'app.asar.unpacked', 'resources', 'ffmpeg', 'linux-amd64', 'ffmpeg' ), 'production-darwin': '/opt/homebrew/bin/ffmpeg' }
if(process.env.NODE_ENV === undefined){ process.env.NODE_ENV = 'production' }
function resolveBinary(map, program) {
const key = ${process.env.NODE_ENV}-${process.platform}
const candidate = map[key]
const fallback = [
candidate,
/opt/homebrew/bin/${program},
/usr/local/bin/${program},
/usr/bin/${program}
]
for (const p of fallback) {
if (p && fs.existsSync(p)) return p
}
return candidate
}
const ffmpegPathValue = resolveBinary(ffmpegPath, 'ffmpeg')
log.debug('ENV:', ${process.env.NODE_ENV}-${process.platform})
log.info('FFmpeg path:', ffmpegPathValue)
if (ffmpegPathValue) {
ffmpeg.setFfmpegPath(ffmpegPathValue)
} else {
log.warn('FFmpeg binary not resolved, please ensure ffmpeg is installed and on PATH')
}
const ffprobePath = { 'development-win32': path.join(__dirname, '../../resources/ffmpeg/win-amd64/bin/ffprobe.exe'), 'development-linux': path.join(__dirname, '../../resources/ffmpeg/linux-amd64/ffprobe'), 'development-darwin': '/opt/homebrew/bin/ffprobe', 'production-win32': path.join( process.resourcesPath, 'app.asar.unpacked', 'resources', 'ffmpeg', 'win-amd64', 'bin', 'ffprobe.exe' ), 'production-linux': path.join( process.resourcesPath, 'app.asar.unpacked', 'resources', 'ffmpeg', 'linux-amd64', 'ffprobe' ), 'production-darwin': '/opt/homebrew/bin/ffprobe' }
const ffprobePathValue = resolveBinary(ffprobePath, 'ffprobe') log.info('FFprobe path:', ffprobePathValue) if (ffprobePathValue) { ffmpeg.setFfprobePath(ffprobePathValue) } else { log.warn('FFprobe binary not resolved, please ensure ffprobe is installed and on PATH') } }
initFFmpeg()
export function extractAudio(videoPath, audioPath) { return new Promise((resolve, reject) => { ffmpeg(videoPath) .noVideo() .save(audioPath) .on('end', () => { log.info('audio split done') resolve(true) }) .on('error', (err) => { reject(err) }) }) }
export async function toH264(videoPath, outputPath) { // const hasNvidia = await detectNvidia() return new Promise((resolve, reject) => { ffmpeg(videoPath) .videoCodec('libx264') .outputOptions('-pix_fmt yuv420p') .save(outputPath) .on('end', () => { log.info('video convert to h264 done') resolve(true) }) .on('error', (err) => { reject(err) }) }) }
function detectNvidia() { return new Promise((resolve) => { const exec = require('child_process').exec; exec('nvidia-smi', (error, stdout, stderr) => { if (error || stderr) { resolve(false); } else { resolve(true); } }); }); }
export function getVideoDuration(videoPath) { return new Promise((resolve, reject) => { ffmpeg(videoPath).ffprobe((err, data) => { if (err) { log.error("🚀 ~ ffmpeg ~ err:", err) reject(err) } else if (data && data.streams && data.streams.length > 0) { resolve(data.streams[0].duration) // 单位秒 } else { log.error('No streams found') reject(new Error('No streams found')) } }) }) } `问题定位
-
主进程通过 fluent-ffmpeg 需要找到 ffprobe / ffmpeg 二进制,但只为 win32 和 linux 配置了路径,缺少 darwin (macOS)映射,导致在 macOS 上报“找不到 ffprobe”。 修复方案
-
增加 macOS 的路径解析,并加入常见 Homebrew 安装位置的回退检测;找不到时打印日志提示安装或配置 PATH。
-
已更新的文件与关键位置:
- src/main/util/ffmpeg.js:1-4 引入 fs 用于存在性检测
- src/main/util/ffmpeg.js:6-26 扩展 ffmpegPath ,新增 development-darwin 与 production-darwin
- src/main/util/ffmpeg.js:32-41 新增 resolveBinary ,按映射与常见位置( /opt/homebrew/bin , /usr/local/bin , /usr/bin )解析路径
- src/main/util/ffmpeg.js:43-48 解析并设置 ffmpeg 路径,找不到时 log.warn
- src/main/util/ffmpeg.js:50-64 扩展 ffprobePath ,新增 development-darwin 与 production-darwin
- src/main/util/ffmpeg.js:66-71 解析并设置 ffprobe 路径,找不到时 log.warn 如何验证
-
在 macOS 上执行任意触发 ffprobe 的功能(如读取视频或音频信息):
- src/main/util/ffmpeg.js:111-125 的 getVideoDuration 会调用 ffprobe ,若路径正确应无“找不到 ffprobe”的错误日志。
- 文件信息接口使用点:
- src/main/handlers/file.js 的 getVideoInfo(...) 与 getAudioInfo(...) ,内部均调用 .ffprobe(...) 。
-
如日志仍提示未解析到二进制,请在本机安装 FFmpeg(包含 ffprobe):
- Apple Silicon: brew install ffmpeg 使用 /opt/homebrew/bin/ffprobe
- Intel: brew install ffmpeg 使用 /usr/local/bin/ffprobe
- 安装后无需改代码,应用会自动识别这些路径;或将 FFmpeg 加入系统 PATH。 补充说明
-
在生产打包中,若未内置 macOS 的 FFmpeg 资源,以上回退逻辑会优先使用本机安装的 FFmpeg/ffprobe。
-
若希望完全内置二进制,可在 resources/ffmpeg 下添加 macos-amd64 / macos-arm64 目录并映射对应路径,然后移除回退逻辑即可。