- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
背景
我正在 Node 中连接 firebase 函数。目的是将入站音频剪辑解析为设定长度。使用 ffmpeg 和 Fluent-ffmpeg。
问题
当该函数在 firebase 中触发时,当 Fluent-Ffmpeg 尝试访问 Ffmpeg 二进制文件时,我收到 ENOENT 错误
Firebase 调试输出
Error: { Error: spawn ./Cloud/functions/node_modules/ffmpeg-binaries/bin/ffmpeg ENOENT at exports._errnoException (util.js:1018:11) at Process.ChildProcess._handle.onexit (internal/child_process.js:193:32) at onErrorNT (internal/child_process.js:367: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 ./Cloud/functions/node_modules/ffmpeg-binaries/bin/ffmpeg', path: './Cloud/functions/node_modules/ffmpeg-binaries/bin/ffmpeg',
spawnargs: [ '-formats' ] }
预期结果
入站文件被下载到临时目录,进行裁剪,然后作为裁剪后的文件重新上传到 Firebase 存储。
环境
代码[已更新以反射(reflect) Svenskunganka 的更改。现在有效]
const ffmpeg = require('fluent-ffmpeg');
const PREVIEW_PREFIX = 'preview_';
exports.generatePreviewClip = functions.storage.object('audioFiles').onChange(event => {
//console.log('Times this function has run: ', run++);
const object = event.data; // The Storage 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.
const resourceState = object.resourceState; // The resourceState is 'exists' or 'not_exists' (for file/folder deletions).
const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.
// Exit if this is triggered on a file that is not an audio file.
if (!contentType.startsWith('audio/')) {
console.log('This is not an audio file.');
console.log('This is the file:', filePath);
return;
}
// Get the file name.
const fileName = path.basename(filePath);
console.log('Working with filename', fileName);
// Exit if the file is already an audio clip.
if (fileName.startsWith(PREVIEW_PREFIX)) {
console.log('Already a preview clip.');
return;
}
// Exit if this is a move or deletion event.
if (event.data.resourceState === 'not_exists') {
console.log('This is a deletion event.');
return;
}
// Exit if file exists but is not new and is only being triggered
// because of a metadata change.
if (resourceState === 'exists' && metageneration > 1) {
console.log('This is a metadata change event.');
return;
}
// Download file from bucket.
const bucket = gcs.bucket(fileBucket);
const tempFilePath = path.join(os.tmpdir(), fileName);
return bucket.file(filePath).download({
destination: tempFilePath
}).then(() => {
console.log('Audio file downloaded locally to temp directory', tempFilePath);
var ffmpegPath = require("ffmpeg-binaries").ffmpegPath();
var ffprobePath = require("ffmpeg-binaries").ffprobePath();
// Generate a croped file using ffmpeg.
var command = new ffmpeg(tempFilePath);
command.setFfmpegPath(ffmpegPath);
command.setFfprobePath(ffprobePath);
command
.setStartTime('00:00:03')
.setDuration('10')
.output(tempFilePath)
.on('end', function() {
console.log('Audio Crop Done Successfully');
})
.on('error', function(err)
{
console.log('Error:', err);
}).run();
}).then(() => {
console.log('Preview file created at', tempFilePath);
// We add a 'preview_' prefix to the audio file name. that's how it will appear in firebase.
const previewFileName = PREVIEW_PREFIX + fileName;
console.log('previewFileName is', previewFileName)
const previewFilePath = path.join(path.dirname(filePath), previewFileName);
console.log('previewFilePath is', previewFilePath);
// Uploading the preview file.
return bucket.upload(tempFilePath, {destination: previewFilePath});
// Once the file has been uploaded delete the local file to free up disk space.
}).then(() => fs.unlinkSync(tempFilePath));
// [END audio file generation]
});
我的 ffmpeg-binaries/bin 目录的内容和结构
-rwxrwxrwx 1 sherpa staff 24M Dec 10 2016 ffmpeg
-rwxr--r-- 1 sherpa staff 35M Jan 12 2017 ffmpeg.exe
-rwxr--r-- 1 sherpa staff 35M Jan 12 2017 ffplay.exe
-rwxrwxrwx 1 sherpa staff 24M Dec 10 2016 ffprobe
-rwxr--r-- 1 sherpa staff 35M Jan 12 2017 ffprobe.exe
-rwxrwxrwx 1 sherpa staff 22M Dec 10 2016 ffserver
我尝试过的事情
感谢您的任何建议。
最佳答案
我们在问题的评论中解决了该问题,但我会为可能遇到相同问题的任何 future 用户发布答案。问题是提供给 setFfmpegPath() 方法的路径是相对的,而应该是绝对的。 ffmpeg-binaries 模块导出几个辅助函数,您可以调用它来获取其二进制文件的路径:
var ffmpeg = require("fluent-ffmpeg")
var ffmpegPath = require("ffmpeg-binaries")
ffmpeg
.setFfmpegPath(ffmpegPath)
...
确保您已使用 npm i -S ffmpeg-binaries
安装了 ffmpeg-binaries
。
2018 年 11 月 7 日更新:
ffmpeg-binaries
包在 4.0.0
版本中发布了一项新的重大更改,删除了它导出的所有函数,而仅导出指向 ffmpeg
所在目录的字符串。这已在提交 009e4d5
中更改.
我已更新答案以反射(reflect)这些更改。
关于node.js - 从 Fluent-Ffmpeg Api 调用 Ffmpeg 二进制文件时 Node 出现 ENOENT 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45682984/
这是我的 Fluent 模型 struct Ailment: PostgreSQLModel { enum Frequency: String , Content { case regular
我正在尝试使用 Fluent Nhibernate 自动映射一个简单的继承层次结构,并且我需要为每个表使用与其类稍有不同的名称(下划线而不是 Pascal 大小写)。这似乎是一个使用约定的明显地方。我
如何为没有标识列的表指定流畅的 NHibernate 映射? 我想要这样的东西: public sealed class CustomerNewMap : ClassMap, IMap { p
使用 FluentMigrator,有没有办法找出 MigrateUp() 函数是否确实会迁移某些东西,或者它是否已经是最新的? 最佳答案 没有简单的方法可以使用公共(public) api 判断 M
我正在使用 Fluent NHibernate,我喜欢它! 我有一个小问题:启动时间大约是 10 秒,我不知道如何优化 Fluent nHibernate 为了减少这个启动时间的问题,我把它放在一个线
我在 Fluent NHIbernate 中使用 AutoPersistenceModel 来映射我的所有实体,并且一切正常:D 但是,我的几个对象有 public virtual IList Com
我有一个数据库,我正在运行多个应用程序。我喜欢通过为每个应用程序创建模式来分隔表。对于我最新的应用程序,我使用的是 FluentNHibernate。似乎我的大部分管道都是正确的,但是当我尝试查询其中
应用程序有许多扩展程序集,它们包含其类的映射。我需要为这些映射中的所有(基本、连接、多对多等)表名添加前缀。 例如 Assembly: ~/bin/Extensions/Foo.dll
您好,我很好奇 DDD 是如何使用 Fluent Nhibernate 真正实现的。例如,我有一个名为 User 的实体类和另一个名为 UserProfile 的类,就我而言,UserProfile
是否可以在 Fluent NHibernate 中映射来自多个程序集的实体? 我试过了 AutoPersistenceModel .MapEntitiesFromAssemblyOf() .AddEn
我有一个看起来像这样的基类: public abstract class MyBaseClass { public virtual DateTime UpdatedOn { get; set;
我有 Post 和 Comment 类,它们有一对多的关系,其中 Post 有一个评论列表。我如何将其映射为与 Fluent NHibernate 的单向关系,因为评论不需要知道其父 Post?目前,
我对如何查询模型对象的子对象并立即使用它感到困惑。我的Client包含数量Station child final class Client: PostgreSQLModel { var sta
目前我有一个表“ComponentAnalysis”和一个表“HistoryOfUse”,我正试图在 Fluent NHibernate 中进行映射。 一个成分分析应该只有1个使用历史,一个使用历史应
正如标题所说,我想知道我是否应该避免将 fluent nhibernate 用于生产代码,或者它是否足够成熟,可以“深入研究”? :) 最佳答案 FluentNHibernate API 尚未稳定下来
我正在尝试使用 Fluent NHibernate,我有几个问题。我发现缺少文档。 我知道 Fluent NHibernate/NHibernate 允许您自动生成数据库模式。人们通常只对测试/开发数
我正在使用 fluent-nhibernate 约定来映射我的实体: public class HasManyConvention : IHasManyConvention {
如何更改多列索引中的列顺序? IE: mapping.References(x => x.SomeReference).SetAttribute("index", "IX_index"); mappi
我需要像下面的代码一样创建一个外键: Create.ForeignKey().FromTable("TCGDocFiscalOpMedItem").ForeignColumn("IDCabecalho
我正在使用 Sharp 架构,并且在许多情况下都在实体中使用了值对象。这是一个明显的简单示例: public class Person : Entity { protected Person(
我是一名优秀的程序员,十分优秀!