You need to enable JavaScript to run this app. Electron主进程如何用async正确搭配execFile与fs.readFile处理ffmpeg视频裁剪读取(遇ENOENT报错)
优惠活动
大模型
产品
解决方案
定价
更多

Electron主进程如何用async正确搭配execFile与fs.readFile处理ffmpeg视频裁剪读取(遇ENOENT报错)

主进程async调用ffmpeg裁剪视频报ENOENT的解决方案

核心问题根因

你当前的代码混用了回调式异步API和Promise/async语法,最直接的触发点是:

  • execFile默认是回调驱动的异步API,没有被async/await捕获等待,代码刚启动ffmpeg进程,还没等裁剪文件生成,就直接执行fs.readFile去读还不存在的文件,自然报ENOENT。
  • 引入fs.promises后,对应的文件操作方法都是Promise版本,不需要传回调,硬塞回调会导致逻辑异常。
  • ipcMain.on的回调签名错误,实际第一个参数是事件对象,第二个才是renderer传的业务数据,之前的参数接收逻辑会拿不到正确的buffer。
  • 临时目录删除操作没有await,会导致流程未完成就提前清理文件。

修正后的可运行代码

const fs = require('fs').promises
const path = require('path')
const os = require('os')
const util = require('util')
const { execFile } = require('child_process')
// 将回调式execFile转为Promise版本,支持await
const execFileAsync = util.promisify(execFile)

ipcMain.on("capture:buffer", async (event, video_object) => {
  const {x_pos, y_pos, window_width, window_height, buffer} = video_object
  const dir = await fs.mkdtemp(path.join(await fs.realpath(os.tmpdir()), path.sep))
  const capturedVideoPath = path.join(dir, "screen_capture_video.mp4")
  const croppedVideoPath = path.join(dir, "cropped_video.mp4")

  try {
    // 写入原始录制buffer,Promise版本直接await,不需要传回调
    await fs.writeFile(capturedVideoPath, buffer)
    console.log("Screen Capture File written")

    // 等待ffmpeg裁剪执行完成,再走后续读文件逻辑
    await execFileAsync(ffmpeg.path, [
      '-i', capturedVideoPath,
      '-vf', `crop=${window_width}:${window_height}:${x_pos}:${y_pos}`,
      croppedVideoPath
    ])
    console.log("Cropped File created")

    // 读取裁剪后的视频为base64,直接await返回结果
    const base64Buffer = await fs.readFile(croppedVideoPath, 'base64')
    mainWindow.webContents.send("main:video_buffer", Buffer.from(base64Buffer))

  } catch (error) {
    console.log(error)
  } finally {
    // 等待临时目录删除完成,避免文件占用问题
    await fs.rm(dir, {recursive: true, force: true})
  }
})

关键调整点

  • 移除所有fs Promise方法的回调参数,纯靠async/await处理流程顺序
  • 用util.promisify包装execFile,确保ffmpeg裁剪完成后才会执行后续读文件操作
  • 修正ipcMain的回调参数接收逻辑,正确获取renderer传来的视频buffer
  • 用fs.rm替代旧的fs.rmdir处理递归删除,避免Node新版本的废弃警告,同时加force参数避免目录非空时报错

内容的提问来源于stack exchange,提问作者Radespy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 12:54:02