Javascript 了解Firebase云函数中Firebase存储中存储的视频持续时间的最简单方法是什么?
我有一个基于触发器的云函数,可以找到上传到Firebase存储的视频的持续时间 我尝试使用以下npm模块:它接受url、文件本身或流 使用我的文件的公共url无效,我的捕获日志:Javascript 了解Firebase云函数中Firebase存储中存储的视频持续时间的最简单方法是什么?,javascript,node.js,firebase,google-cloud-functions,firebase-storage,Javascript,Node.js,Firebase,Google Cloud Functions,Firebase Storage,我有一个基于触发器的云函数,可以找到上传到Firebase存储的视频的持续时间 我尝试使用以下npm模块:它接受url、文件本身或流 使用我的文件的公共url无效,我的捕获日志: { Error: spawn ffprobe ENOENT at exports._errnoException (util.js:1020:11) at Process.ChildProcess._handle.onexit (internal/child_process.js:197:32)
{ 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创建了一个流,然后我传递了它,它给了我一个未找到的持续时间代码>错误:
{ 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的库:
我最终使用了建议的库:fluent mmpeg,但要在Firebase上使用它,您需要执行以下操作:
您需要使用bluebird“promisify”fluent mmpeg,如下所示:const ffprobe=Promise.promisify(require(“fluent ffmpeg”).ffprobe)代码>
您需要同时安装ffmpeg和ffprobe的静态二进制文件,因此请将它们包含在您的pacakgenpm i--save@ffmpeg installer/ffmpeg,@ffprobe installer/ffprobe
最后,设置路径:const ffmpegPath=require(“@ffmpeg安装程序/ffmpeg”).path;
const ffprobePath=require(“@ffprobe安装程序/ffprobe”).path;
setFfmpegPath(ffmpegPath);
ffmpeg.setFfprobePath(ffprobePath)代码>
下面是一些经过测试和运行的代码:
从package.json:
"@ffmpeg-installer/ffmpeg": "^1.0.17",
"@ffprobe-installer/ffprobe": "^1.0.9",
"@google-cloud/storage": "^1.1.1",
"bluebird": "^3.5.3",
"fluent-ffmpeg": "^2.1.2"
我试过了,但我发现:TypeError:Cannot readed属性'format'of undefined at/user\u code/ready/recordUploadedFile.js:38:35
元数据似乎未定义,你能不能控制台err
?err
也为空,但原因是firebase只处理异步函数,因此,我使用了bluebird
来演示ffprobe函数。但是,当我发现错误时,我得到:error:not find ffprobe at/user\u code/node\u modules/fluent ffmpeg/lib/ffprobe.js:145:31
我安装了ffmpeg、ffprobe和fluent mpeg。而且,它们都在我的package.js
os = require('os');
path = require('path');
gcs = require('@google-cloud/storage')();
const filePath = object.name;
const const fileBucket = object.bucket;
var Promise = require("bluebird");
var ffmpeg = Promise.promisify(require("fluent-ffmpeg"));
var ffmpegPath = require("@ffmpeg-installer/ffmpeg").path;
var ffprobePath = require("@ffprobe-installer/ffprobe").path;
ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg.setFfprobePath(ffprobePath);
const fileName = filePath.split('/').pop();
const tempFilePath = path.join(os.tmpdir(), fileName);
const bucket = gcs.bucket(fileBucket);
bucket.file(filePath).download({
destination: tempFilePath,
validation: false
}).then(function() {
ffmpeg.ffprobe(tempFilePath, function(err, metadata) {
if (err) {
reject(err);
} else {
if (metadata) {
console.log(metadata.format.duration);
console.log(metadata.streams[0].width);
console.log(metadata.streams[0].height);
console.log(metadata);
resolve();
} else {
reject();
}
}
})
}).catch(function(error) {
console.error(error); reject();
})
"@ffmpeg-installer/ffmpeg": "^1.0.17",
"@ffprobe-installer/ffprobe": "^1.0.9",
"@google-cloud/storage": "^1.1.1",
"bluebird": "^3.5.3",
"fluent-ffmpeg": "^2.1.2"