node.js - 无法使用 Node js 在 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 - nodejs自动维护winston日志
- windows - 我想用 Vagrant 在 OSX 上运行一个基本的 Windows 来宾,但我不断收到身份验证失败
- swift - 从初始化程序返回而不初始化所有存储的属性Swift Xcode 10.0
- sql - 使用别名或同义词的 SQL Server 跨数据库查询
- sql-server - 在同一查询中为 Oracle 和 SQL Server 转义特殊字符
- php - laravel 5.6 socialite auth by facebook email 为空
- android - 获取 Widevine 许可证服务器密钥
- image-processing - 对角线方向边缘检测
- symfony - 动态类加载 - 尝试从命名空间 _NAMESPACE_ 加载类 _CLASS_
- php - 使用没有错误消息的私人频道时无法从推送者那里获得响应