gpt4 book ai didi

javascript - 在 cloudfunction 中运行的 ffmpeg 静默失败/永远不会完成

转载 作者:行者123 更新时间:2023-12-04 23:07:39 25 4
gpt4 key购买 nike

我正在尝试实现一个可以运行 ffmpeg 的 Cloudfunction在谷歌存储桶上传。我一直在玩基于 https://kpetrovi.ch/2017/11/02/transcoding-videos-with-ffmpeg-in-google-cloud-functions.html 的脚本

随着库的发展,原始脚本几乎不需要调整。我当前的版本在这里:

const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');

console.log("Linking ffmpeg path to:", ffmpeg_static)
ffmpeg.setFfmpegPath(ffmpeg_static);

exports.transcodeVideo = (event, callback) => {
const bucket = storage.bucket(event.bucket);
console.log(event);
if (event.name.indexOf('uploads/') === -1) {
console.log("File " + event.name + " is not to be processed.")
return;
}

// ensure that you only proceed if the file is newly createdxxs
if (event.metageneration !== '1') {
callback();
return;
}

// Open write stream to new bucket, modify the filename as needed.
const targetName = event.name.replace("uploads/", "").replace(/[.][a-z0-9]+$/, "");
console.log("Target name will be: " + targetName);

const remoteWriteStream = bucket.file("processed/" + targetName + ".mp4")
.createWriteStream({
metadata: {
//metadata: event.metadata, // You may not need this, my uploads have associated metadata
contentType: 'video/mp4', // This could be whatever else you are transcoding to
},
});

// Open read stream to our uploaded file
const remoteReadStream = bucket.file(event.name).createReadStream();

// Transcode
ffmpeg()
.input(remoteReadStream)
.outputOptions('-c:v copy') // Change these options to whatever suits your needs
.outputOptions('-c:a aac')
.outputOptions('-b:a 160k')
.outputOptions('-f mp4')
.outputOptions('-preset fast')
.outputOptions('-movflags frag_keyframe+empty_moov')
// https://github.com/fluent-ffmpeg/node-fluent-ffmpeg/issues/346#issuecomment-67299526
.on('start', (cmdLine) => {
console.log('Started ffmpeg with command:', cmdLine);
})
.on('end', () => {
console.log('Successfully re-encoded video.');
callback();
})
.on('error', (err, stdout, stderr) => {
console.error('An error occured during encoding', err.message);
console.error('stdout:', stdout);
console.error('stderr:', stderr);
callback(err);
})
.pipe(remoteWriteStream, { end: true }); // end: true, emit end event when readable stream ends
};


此版本正确运行,我可以在日志中看到:
2020-06-16 21:24:22.606  Function execution took 912 ms, finished with status: 'ok'
2020-06-16 21:24:52.902 Started ffmpeg with command: ffmpeg -i pipe:0 -c:v copy -c:a aac -b:a 160k -f mp4 -preset fast -movflags frag_keyframe+empty_moov pipe:1

似乎函数执行在实际的 ffmpeg 命令之前结束,然后永远不会完成。

有没有办法让 ffmpeg “同步”或“阻塞”,以便它在函数执行之前完成?

最佳答案

来自 google cloud documentation该函数似乎应该接受三个参数:(data, context, callback)你试过这个还是你知道context是可选的吗?从文档看来,如果函数接受三个参数被视为后台函数,如果它只接受两个参数,则仅当它返回 Promise 时才被视为后台函数.

除此之外,还有一点:

1:这里没有 callback函数被调用,如果在您的测试中您的函数以该日志行退出,则另一点表明将第二个参数作为回调函数调用是完成过程所需的步骤:

if (event.name.indexOf('uploads/') === -1) {
console.log("File " + event.name + " is not to be processed.")
return;
}
  • 我建议添加一些其他 console.log (或许多其他,如果您愿意)澄清流程:在您的问题中,您仅粘贴了 1 条日志行,说它是在系统日志行
  • 之后记录的并没有太大帮助。
  • 您用作教程的链接已经快三年了,可能是谷歌云同时改变了它的界面。

  • 曾经说过,如果接受三个参数而不是两个参数不能解决您的问题,您可以尝试更改 Promise 中的函数:
    exports.transcodeVideo = (event, callback) => new Promise((resolve, reject) => {
    const bucket = storage.bucket(event.bucket);
    console.log(event);
    if (event.name.indexOf('uploads/') === -1) {
    console.log("File " + event.name + " is not to be processed.")
    return resolve(); // or reject if this is an error case
    }

    // ensure that you only proceed if the file is newly createdxxs
    if (event.metageneration !== '1') {
    return resolve(); // or reject if this is an error case
    }

    // Open write stream to new bucket, modify the filename as needed.
    const targetName = event.name.replace("uploads/", "").replace(/[.][a-z0-9]+$/, "");
    console.log("Target name will be: " + targetName);

    const remoteWriteStream = bucket.file("processed/" + targetName + ".mp4")
    .createWriteStream({
    metadata: {
    //metadata: event.metadata, // You may not need this, my uploads have associated metadata
    contentType: 'video/mp4', // This could be whatever else you are transcoding to
    },
    });

    // Open read stream to our uploaded file
    const remoteReadStream = bucket.file(event.name).createReadStream();

    // Transcode
    ffmpeg()
    .input(remoteReadStream)
    .outputOptions('-c:v copy') // Change these options to whatever suits your needs
    .outputOptions('-c:a aac')
    .outputOptions('-b:a 160k')
    .outputOptions('-f mp4')
    .outputOptions('-preset fast')
    .outputOptions('-movflags frag_keyframe+empty_moov')
    // https://github.com/fluent-ffmpeg/node-fluent-ffmpeg/issues/346#issuecomment-67299526
    .on('start', (cmdLine) => {
    console.log('Started ffmpeg with command:', cmdLine);
    })
    .on('end', () => {
    console.log('Successfully re-encoded video.');
    resolve();
    })
    .on('error', (err, stdout, stderr) => {
    console.error('An error occured during encoding', err.message);
    console.error('stdout:', stdout);
    console.error('stderr:', stderr);
    reject(err);
    })
    .pipe(remoteWriteStream, { end: true }); // end: true, emit end event when readable stream ends
    });

    希望这可以帮助。

    关于javascript - 在 cloudfunction 中运行的 ffmpeg 静默失败/永远不会完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62417909/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com