You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Adobe扩展NodeJS环境下读取FormData文件调用ffmpeg提取音频问题

解决方案:Adobe扩展Node.js环境中用FFmpeg提取视频音频(处理FileInput伪路径问题)

核心问题分析

HTML的input[type=file]在Adobe CEP扩展环境中返回的value是伪路径,无法直接被FFmpeg识别。你需要获取真实的文件内容流或本地真实文件路径来喂给FFmpeg。


方案1:将File对象转为Node.js可读流(无需真实路径)

利用浏览器标准的File API获取文件内容,转成Node.js的Readable流,直接传给FFmpeg:

  1. 获取用户选择的File对象(不要用value属性)
  2. 将File转为ArrayBuffer再转成Node.js Buffer
  3. 基于Buffer创建可读流,传入FFmpeg处理
const { Readable } = require('stream');
const ffmpeg = require('fluent-ffmpeg');
const fileInput = document.getElementById('video-upload');

fileInput.addEventListener('change', async (e) => {
  const selectedFile = e.target.files[0];
  if (!selectedFile) return;

  // 把File转成Node.js可处理的Buffer
  const arrayBuffer = await selectedFile.arrayBuffer();
  const fileBuffer = Buffer.from(arrayBuffer);

  // 创建可读流
  const fileStream = Readable.from(fileBuffer);

  // 用FFmpeg提取音频
  ffmpeg(fileStream)
    .outputOptions('-vn') // 禁用视频流,只保留音频
    .format('mp3') // 指定输出音频格式
    .pipe(process.stdout) // 可替换为写入文件或上传流
    .on('end', () => console.log('音频提取完成'))
    .on('error', (err) => console.error('处理失败:', err));
});

方案2:通过CEP API获取真实本地文件路径

如果你的FFmpeg依赖本地文件路径(比如某些旧版本或特定插件),可以用Adobe CEP的CSInterface调用宿主程序的API获取真实路径:

  1. 引入CEP的CSInterface(扩展默认自带)
  2. 调用宿主的文件选择对话框(替代HTML FileInput,避免伪路径问题)
  3. 获取真实文件路径后直接传给FFmpeg
const csInterface = new CSInterface();
const ffmpeg = require('fluent-ffmpeg');

// 触发文件选择(替代HTML FileInput)
document.getElementById('select-video-btn').addEventListener('click', () => {
  // 调用Adobe宿主的文件选择脚本
  csInterface.evalScript(`
    var fileObj = new File();
    var selectedPath = fileObj.browseDlg("选择视频文件", "*.mp4;*.mov;*.avi");
    fileObj.exists ? fileObj.fsName : null;
  `, (realFilePath) => {
    if (realFilePath === 'null' || !realFilePath) return;

    // 用真实路径调用FFmpeg
    ffmpeg(realFilePath)
      .outputOptions('-vn')
      .format('mp3')
      .save('./extracted-audio.mp3')
      .on('end', () => console.log('音频提取完成'))
      .on('error', (err) => console.error('处理失败:', err));
  });
});

方案3:写入临时文件后用路径调用FFmpeg

如果以上两种方式不兼容,可将File对象写入本地临时文件,用临时文件路径给FFmpeg:

const fs = require('fs');
const os = require('os');
const path = require('path');
const ffmpeg = require('fluent-ffmpeg');
const fileInput = document.getElementById('video-upload');

fileInput.addEventListener('change', async (e) => {
  const selectedFile = e.target.files[0];
  if (!selectedFile) return;

  // 创建临时文件路径
  const tempFilePath = path.join(os.tmpdir(), `temp_video_${Date.now()}.mp4`);
  
  // 将File写入临时文件
  const arrayBuffer = await selectedFile.arrayBuffer();
  fs.writeFileSync(tempFilePath, Buffer.from(arrayBuffer));

  // 用临时文件路径处理
  ffmpeg(tempFilePath)
    .outputOptions('-vn')
    .format('mp3')
    .save('./extracted-audio.mp3')
    .on('end', () => {
      console.log('音频提取完成');
      // 清理临时文件
      fs.unlinkSync(tempFilePath);
    })
    .on('error', (err) => {
      console.error('处理失败:', err);
      // 报错也要清理临时文件
      fs.unlinkSync(tempFilePath);
    });
});

关键注意事项

  • 确保你的扩展manifest.xml中开启了文件访问权限:
    <CEFCommandLine>
      <Parameter>--allow-file-access-from-files</Parameter>
    </CEFCommandLine>
    
  • 若使用fluent-ffmpeg,需确保FFmpeg二进制文件已打包到扩展中,并正确配置ffmpeg.setFfmpegPath('./path/to/ffmpeg')。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:45:33