node.js - NodeJs - Fluent-FFMPEG 找不到用于 firebase 云功能的 FFMPEG

标签 node.js firebase firebase-realtime-database google-cloud-functions fluent-ffmpeg

我正在尝试学习如何使用 ffmpeg-fluent 编写 firebase 云函数,并引用此示例 code .我已经复制了代码,只是将 gcs 的初始化更改为 const gcs = admin.storage();。在 Node 10 上部署成功,但是在上传 mp3 文件来测试功能时,出现以下错误。

Error: Cannot find ffmpeg at /srv/node_modules/fluent-ffmpeg/lib/processor.js:136:22 
at FfmpegCommand.proto._getFfmpegPath (/srv/node_modules/fluent-ffmpeg/lib/capabilities.js:90:14) 
at FfmpegCommand.proto._spawnFfmpeg (/srv/node_modules/fluent-ffmpeg/lib/processor.js:132:10) 

at FfmpegCommand.proto.availableFormats.proto.getAvailableFormats (/srv/node_modules/fluent-ffmpeg/lib/capabilities.js:517:10) 
at /srv/node_modules/fluent-ffmpeg/lib/capabilities.js:568:14 
at nextTask (/srv/node_modules/async/dist/async.js:4578:27) 
at Object.waterfall (/srv/node_modules/async/dist/async.js:4589:9) 
at Object.awaitable(waterfall) [as waterfall] (/srv/node_modules/async/dist/async.js:208:32) 
at FfmpegCommand.proto._checkCapabilities (/srv/node_modules/fluent-ffmpeg/lib/capabilities.js:565:11) 
at /srv/node_modules/fluent-ffmpeg/lib/processor.js:298:14

谁能告诉我我错过了哪些安装步骤?

这是之前存储库中的代码段。

index.js

const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
const path = require('path');
const os = require('os');
const fs = require('fs');
const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');

// Makes an ffmpeg command return a promise.
function promisifyCommand(command) {
  return new Promise((resolve, reject) => {
    command.on('end', resolve).on('error', reject).run();
  });
}

/**
 * When an audio is uploaded in the Storage bucket We generate a mono channel audio automatically using
 * node-fluent-ffmpeg.
 */
exports.generateMonoAudio = functions.storage.object().onFinalize(async (object) => {
  const fileBucket = object.bucket; // The Storage bucket that contains the file.
  const filePath = object.name; // File path in the bucket.
  const contentType = object.contentType; // File content type.

  // Exit if this is triggered on a file that is not an audio.
  if (!contentType.startsWith('audio/')) {
    console.log('This is not an audio.');
    return null;
  }

  // Get the file name.
  const fileName = path.basename(filePath);
  // Exit if the audio is already converted.
  if (fileName.endsWith('_output.flac')) {
    console.log('Already a converted audio.');
    return null;
  }

  // Download file from bucket.
  const bucket = gcs.bucket(fileBucket);
  const tempFilePath = path.join(os.tmpdir(), fileName);
  // We add a '_output.flac' suffix to target audio file name. That's where we'll upload the converted audio.
  const targetTempFileName = fileName.replace(/\.[^/.]+$/, '') + '_output.flac';
  const targetTempFilePath = path.join(os.tmpdir(), targetTempFileName);
  const targetStorageFilePath = path.join(path.dirname(filePath), targetTempFileName);

  await bucket.file(filePath).download({destination: tempFilePath});
  console.log('Audio downloaded locally to', tempFilePath);
  // Convert the audio to mono channel using FFMPEG.

  let command = ffmpeg(tempFilePath)
      .setFfmpegPath(ffmpeg_static.path)
      .audioChannels(1)
      .audioFrequency(16000)
      .format('flac')
      .output(targetTempFilePath);

  await promisifyCommand(command);
  console.log('Output audio created at', targetTempFilePath);
  // Uploading the audio.
  await bucket.upload(targetTempFilePath, {destination: targetStorageFilePath});
  console.log('Output audio uploaded to', targetStorageFilePath);

  // Once the audio has been uploaded delete the local file to free up disk space.
  fs.unlinkSync(tempFilePath);
  fs.unlinkSync(targetTempFilePath);

  return console.log('Temporary files removed.', targetTempFilePath);
});

package.json

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "lint": "eslint .",
    "serve": "firebase emulators:start --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "10"
  },
  "dependencies": {
    "@google-cloud/storage": "^5.0.1",
    "child-process-promise": "^2.2.1",
    "ffmpeg-static": "^4.2.5",
    "firebase-admin": "^8.10.0",
    "firebase-functions": "^3.6.1",
    "fluent-ffmpeg": "^2.1.2",
    "fs-extra": "^8.1.0",
    "sharp": "^0.25.3"
  },
  "devDependencies": {
    "eslint": "^5.12.0",
    "eslint-plugin-promise": "^4.0.1",
    "firebase-functions-test": "^0.2.0"
  },
  "private": true
}

最佳答案

这里的 ffmpeg_static.path 路径是未定义的

let command = ffmpeg(tempFilePath)
      .setFfmpegPath(ffmpeg_static.path)
      .audioChannels(1)
      .audioFrequency(16000)
      .format('flac')
      .output(targetTempFilePath);

您应该做的是安装“ffmpeg-installer/ffmpeg”。您可以在这里找到它:https://www.npmjs.com/package/@ffmpeg-installer/ffmpeg

然后设置正确的路径如下:

const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ffmpeg = require('fluent-ffmpeg');

let command = ffmpeg(tempFilePath)
      .setFfmpegPath(ffmpegPath)
      .audioChannels(1)
      .audioFrequency(16000)
      .format('flac')
      .output(targetTempFilePath);

关于node.js - NodeJs - Fluent-FFMPEG 找不到用于 firebase 云功能的 FFMPEG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62652721/

相关文章:

javascript - 从一个函数内部的 request.get 返回变量值到另一个 NODEJS 表达式

javascript - 在 Node.js 的 require 声明中不使用 var 会产生什么后果?

node.js - 无法启动 chrome [FATAL :zygote_host_impl_linux. cc(116)] 没有可用的沙箱

java - Android 中的完成处理程序 Firebase

angular - 如何避免需要使用 Elvis Operator?

node.js - 异步和解析的问题

java - 当应用程序被杀死时如何停止接收通知?

node.js - 如何验证服务器上的 FCM 注册 token ?

Firebase云函数: Accessing Data from a different node

javascript - 如何在firebase中检索当前用户数据