javascript - 了解存储在 Firebase 云功能中的 Firebase 存储中的视频持续时间的最简单方法是什么?

标签 javascript node.js firebase google-cloud-functions firebase-storage

我有一个基于触发器的云函数,可以找到上传到 Firebase 存储的视频的持续时间。

我尝试使用以下 npm 模块:get-video-duration它采用 url、文件本身或流。

使用我的文件的公共(public) url 不起作用,我的捕获日志:

{ Error: spawn ffprobe ENOENT
    at exports._errnoException (util.js:1020:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:197:32)
    at onErrorNT (internal/child_process.js:376:16)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickDomainCallback (internal/process/next_tick.js:128:9)
  code: 'ENOENT',
  errno: 'ENOENT',
  syscall: 'spawn ffprobe',
  path: 'ffprobe',
  spawnargs: 
   [ '-v',
     'error',
     '-show_format',
     '-show_streams',
     'https://storage.googleapis.com/adboard-dev.appspot.com/5HRuyysoMxe9Tb5vPLDbhEaHtkH2%2F-LAve5VogdAr4ZohU-DE%2FSampleVideo_1280x720_1mb.mp4?GoogleAccessId=firebase-adminsdk-3lthu@adboard-dev.iam.gserviceaccount.com&Expires=16447017600&Signature=cbhn%2BtY2%2FtvcRkvsFp1ywhHKiz%2FLfabfMk6HbD4TEGd%2Brf4njcMz1mQVf6H8nyulTBoRHIgC2uENFEPoEjtON6Um0Jb9P9jgikj6PdhS98m1sPDpTjMiFCTWk6ICjTI%2B%2BWuSVGgDX0tRuq3fADZABKaEcl3CEAI17DCVH98a40XttIDZqeqxIDu1iLi%2F8apQy44pAPJsmVR2dkYHk8Am8e7jIT1OnXG3adO34U3TNhsziPryIIpzo68QANENeieulvleic2BEi7KUhN1K8IxzJXxAfkt9RAFbdrwh%2FOpQ7zTGPRzTC3Vz2FnmKSXVtdKtmftg7BlEXrRr3D7ELJ53g%3D%3D' ],
  stdout: '',
  stderr: '',
  failed: true,
  signal: null,
  cmd: 'ffprobe -v error -show_format -show_streams https://storage.googleapis.com/adboard-dev.appspot.com/5HRuyysoMxe9Tb5vPLDbhEaHtkH2%2F-LAve5VogdAr4ZohU-DE%2FSampleVideo_1280x720_1mb.mp4?GoogleAccessId=firebase-adminsdk-3lthu@adboard-dev.iam.gserviceaccount.com&Expires=16447017600&Signature=cbhn%2BtY2%2FtvcRkvsFp1ywhHKiz%2FLfabfMk6HbD4TEGd%2Brf4njcMz1mQVf6H8nyulTBoRHIgC2uENFEPoEjtON6Um0Jb9P9jgikj6PdhS98m1sPDpTjMiFCTWk6ICjTI%2B%2BWuSVGgDX0tRuq3fADZABKaEcl3CEAI17DCVH98a40XttIDZqeqxIDu1iLi%2F8apQy44pAPJsmVR2dkYHk8Am8e7jIT1OnXG3adO34U3TNhsziPryIIpzo68QANENeieulvleic2BEi7KUhN1K8IxzJXxAfkt9RAFbdrwh%2FOpQ7zTGPRzTC3Vz2FnmKSXVtdKtmftg7BlEXrRr3D7ELJ53g%3D%3D',
  timedOut: false,
  killed: false }

下载文件然后直接传递它也不起作用:

{ Error: spawn ffprobe ENOENT
    at exports._errnoException (util.js:1020:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:197:32)
    at onErrorNT (internal/child_process.js:376:16)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickDomainCallback (internal/process/next_tick.js:128:9)
  code: 'ENOENT',
  errno: 'ENOENT',
  syscall: 'spawn ffprobe',
  path: 'ffprobe',
  spawnargs: 
   [ '-v',
     'error',
     '-show_format',
     '-show_streams',
     '/tmp/SampleVideo_1280x720_1mb.mp4' ],
  stdout: '',
  stderr: '',
  failed: true,
  signal: null,
  cmd: 'ffprobe -v error -show_format -show_streams /tmp/SampleVideo_1280x720_1mb.mp4',
  timedOut: false,
  killed: false }

最后,我使用 fs 创建了一个流,然后传递了它,它给了我一个 Duration Not Found! 错误:

{ AssertionError: No duration found!
    at ffprobe.then (/user_code/node_modules/get-video-duration/index.js:34:3)
    at process._tickDomainCallback (internal/process/next_tick.js:135:7)
  name: 'AssertionError',
  actual: null,
  expected: true,
  operator: '==',
  message: 'No duration found!',
  generatedMessage: false }

我的云函数代码:

exports.recordUploadedFile = functions.storage.object().onFinalize(object => {
  let fileType = object.contentType;
  if (fileType.startsWith("image/") || fileType.startsWith("video/")) {
    let dir = object.name.split("/");
    let name = dir.pop();
    let fileID = dir.pop();
    let uid = dir.pop();
    return admin
      .storage()
      .bucket()
      .file(object.name)
      .getSignedUrl({
        action: "read",
        expires: "03-09-2491"
      })
      .then(urls => {
        let file = {
          name: name,
          link: urls[0],
          type: fileType,
          duration: 0
        }
        if (fileType.startsWith("video/")) {
          const tempFilePath = path.join(os.tmpdir(), name);
          return admin.storage().bucket().file(object.name).download({
            destination: tempFilePath
          }).then(() => {
            const stream = fs.createReadStream(tempFilePath);
            return getDuration(stream).then(duration => {
              console.log(duration);
              file.duration = duration;
              return setFile(file, uid, fileID);
            }).catch(error => {
              console.log(error);
            });
          });
        } else {
          return setFile(file, uid, fileID);
        }
      });
  } else {
    return admin.storage().bucket().file(object.name).delete();
  }
});

我尝试了多个不同大小的视频文件,但没有一个有效。

如果有更好的解决方案来知道视频时长,我也很想知道。

谢谢。

最佳答案

尝试使用名为 fluent-ffmpeg 的库:https://github.com/fluent-ffmpeg/node-fluent-ffmpeg

var ffmpeg = require('fluent-ffmpeg');

ffmpeg.ffprobe(tempFilePath, function(err, metadata) {
  //console.dir(metadata); // all metadata
  console.log(metadata.format.duration);
});

关于javascript - 了解存储在 Firebase 云功能中的 Firebase 存储中的视频持续时间的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50017636/

相关文章:

javascript - Visual Studio Code 中的 Beautif/Tidy (Javascript)

javascript - nodemon配置文件中的verbose是什么意思?

node.js - 如何在 mongoose 中处理 mongoDB close

mysql - 通过 native 连接远程mysql : node expressjs

javascript - 更新 Firebase 中的 key

ios - 从 Firebase 检索 key 数组, "variable used within its own value"

android - 为 Firebase 设计数据结构

javascript - 第一次打开网页时 masonry 元素崩溃

javascript - firebase auth - 获取当前提供者 javascript

javascript - 如何使用 ExtJS 访问从 JsonStore 获取的值?