node.js - 无法使用 Node js 在 AWS lambda 函数中将视频文件转换为音频文件

标签 node.js amazon-web-services ffmpeg aws-lambda

我无法使用 Node JS 在 AWS lambda 函数中将视频文件转换为音频文件。在运行我的 lambda 函数时,它不会抛出任何错误,它会在没有任何错误的情况下执行。但音频文件大小仍然是 0 MB 大小。我无法在我的代码中找到错误或任何问题。

这是我的代码,

const fs = require('fs');
const childProcess = require('child_process');
const AWS = require('aws-sdk');
const path = require('path');
AWS.config.update({
    region : 'us-east-2'
});
const s3 = new AWS.S3({apiVersion: '2006-03-01'});


exports.handler = (event, context, callback) => {
    process.env.PATH = process.env.PATH + ':/tmp/';
    process.env['FFMPEG_PATH'] = '/tmp/ffmpeg';
    const BIN_PATH = process.env['LAMBDA_TASK_ROOT'];
    process.env['PATH'] = process.env['PATH'] + ':' + BIN_PATH;

    childProcess.exec(
        'cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg;',
        function (error, stdout, stderr) {
            if (error) {
                console.log('Error occured',error);
            } else {
                var ffmpeg = '/tmp/ffmpeg';
                var createStream = fs.createWriteStream("/tmp/video.mp3");
                createStream.end();
                var params = {
                    Bucket: "test-bucket",
                    Key: event.Records[0].s3.object.key
                };
                s3.getObject(params, function(err, data) {
                    if (err) {
                        console.log("Error", err);
                    }
                    fs.writeFile("/tmp/vid.mp4", data.Body, function (err) {
                        if (err) console.log(err.code, "-", err.message);
                        return callback(err);
                    }, function() {
                        try {
                            var stats = fs.statSync("/tmp/vid.mp4");
                            console.log("size of the file1 ", stats["size"]);
                            try {
                                console.log("Yeah");
                                const inputFilename = "/tmp/vid.mp4";
                                const mp3Filename = "/tmp/video.mp3";
                                // // Convert the FLV file to an MP3 file using ffmpeg.
                                const ffmpegArgs = [
                                    '-i', inputFilename,
                                    '-vn', // Disable the video stream in the output.
                                    '-acodec', 'libmp3lame', // Use Lame for the mp3 encoding.
                                    '-ac', '2', // Set 2 audio channels.
                                    '-q:a', '6', // Set the quality to be roughly 128 kb/s.
                                    mp3Filename,
                                ];
                                try {
                                    const process = childProcess.spawnSync(ffmpeg, ffmpegArgs);
                                    console.log("stdout ", process.stdout);
                                    console.log("stderr ", process.stderr);
                                    console.log("tmp files ");
                                    fs.readdir('/tmp/', (err, files) => {
                                        files.forEach(file => {
                                            var stats = fs.statSync(`/tmp/${file}`);
                                            console.log("size of the file2 ", stats["size"]);
                                          console.log(file);
                                        });
                                      });

                                } catch (e) {
                                    console.log("error while converting video to audio ", e);
                                }

                                // return process;
                            } catch (e) {
                                console.log(e);
                            }
                        } catch (e) {
                            console.log("file is not complete", e);
                        }
                    }, function () {
                        console.log("checking ");
                        var stats = fs.statSync("/tmp/video.mp3");
                        console.log("size of the file2 ", stats["size"]);
                    });

                    return callback(err);
                });
            }
        }
    )
}

代码工作流程

首先,我已经下载了 ffmpeg 二进制 exec 文件并放入我的项目目录。之后,我压缩了我的项目并将其放入 lambda 函数中。每当新文件上传到 S3 存储桶时,都会触发此 lambda 函数。我检查了/tmp/存储文件和存在的音频文件 .mp3,但大小为 0 MB。

备注

而且,在我的代码中,下面没有调用或者这部分没有到达。当我查看 Cloudwatch 日志时,我看不到此控制台日志消息。我不知道为什么这个函数没有调用。
function () {
        console.log("checking ");
        var stats = fs.statSync("/tmp/video.mp3");
        console.log("size of the file2 ", stats["size"]);
    });

请帮我找到这个问题的解决方案。我花了很多时间来弄清楚这个问题。但我无法找到解决方案。欢迎任何建议!
谢谢,

最佳答案

有许多限制可能导致 Lambda 在尝试进行转换时爆炸。您需要做的第一件事是为 AWS Linux 编译 ffmpeg,通常,您必须使用静态链接而不是动态链接进行编译。

另一种方法是使用 docker 容器并在 aws ecs fargate 上运行它,这将使您更容易控制依赖关系,并且您对运行时间没有任何限制,您仍然可以将机器的管理外包给 AWS。

在 Lambda 上转码视频
https://intoli.com/blog/transcoding-on-aws-lambda/

预编译的ffmpeg
https://johnvansickle.com/ffmpeg/

关于node.js - 无法使用 Node js 在 AWS lambda 函数中将视频文件转换为音频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54794211/

相关文章:

node.js - NodeJS 应用程序部署 - NPM/Gulp

javascript - node.js async.series 是它应该如何工作的?

mysql - 在 RDS 中访问 MySQL 或 MS SQL 时,AWS Lambda node.js ETIMEDOUT

java - 使用 ResteasyClient 时 AWS API Gateway 出现 SSLHandShakeException

ffmpeg : 4K BluRay to 1080p x264

ffmpeg - 如何使用带间隔的 FFMPEG 创建动画 GIF?

ffmpeg - qt-faststart 命令永远不会完成

javascript - 将数据从模型传递到 Node js中的路由器

javascript - WHERE 子句中的多个列

ruby-on-rails - 在 Rails 应用程序中向 PostgreSQL 提供 SSL 证书