Lambda nodejs – 不支持mediainfo w / libcurl字节范围

我已经创build了一个Lambda函数来使用ffmpeg和Mediainfo创buildmp4video文件的缩略图图像,这对于较小的文件非常有用。

到目前为止,我已经成功地创build了大小为372.5 KB和73.4 KB的文件的缩略图,但是文件大小分别为2.9 MB和7.9 MB时收到了错误。

在我的CloudWatch日志中,我看到以下错误:

https://s3-us-west-2.amazonaws.com/object-path, HTTP server doesn't seem to support byte ranges. Cannot resume. 

当我尝试使用Mediainfo提取video元数据时发生错误 – 我在EC2环境中安装了带有libcurl的Mediainfo二进制文件。

我是一个cURL,Mediainfo和Lambda的相对新手,所以我觉得我已经达到了我的界限,试图解决这个问题。 我不确定这个特定的错误是由于Lambda节点环境引起的,还是与Mediainfo有关。

任何帮助解决这个将不胜感激。 如果需要,我可以提供更多的澄清信息。

供参考的代码 –

 process.env.PATH = process.env.PATH + ":/tmp/"; var child_process = require("child_process"); child_process.exec( "cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg;", function (error, stdout, stderr) { if (error) { console.log(error); } } ); var mediainfo = require("mediainfo-wrapper"); var async = require("async"); var AWS = require("aws-sdk"); var fs = require("fs"); var utils = { decodeKey: function(key) { return decodeURIComponent(key).replace(/\+/g, " "); } }; var s3 = new AWS.S3(); var thumbKeyPrefix = "thumbnails/", thumbWidth = 300, thumbHeight = 300, allowedFileTypes = ["mp4"]; exports.handler = function(event, context) { var tmpFile = fs.createWriteStream("/tmp/screenshot.jpg"); var srcKey = utils.decodeKey(event.Records[0].s3.object.key), bucket = event.Records[0].s3.bucket.name, dstKey = thumbKeyPrefix + srcKey.replace(/\.\w+$/, ".jpg"), fileType = srcKey.match(/\.\w+$/), target = s3.getSignedUrl("getObject",{Bucket:bucket, Key:srcKey, Expires: 900}), metadata = {width: 0, height: 0, duration: 0}; if(srcKey.indexOf(thumbKeyPrefix) === 0) return; if (fileType === null) { context.fail("Invalid filetype found for key: " + srcKey); return; } fileType = fileType[0].substr(1); if (allowedFileTypes.indexOf(fileType) === -1) { context.fail("Filetype " + fileType + " not valid for thumbnail, exiting"); return; } async.waterfall([ function createMetaData(next) { console.log('creating metadata...'); mediainfo(target).then(function(data) { metadata.width = data[0].video[0].width[0] * 1; metadata.height = data[0].video[0].height[0] * 1; metadata.duration = data[0].video[0].duration[0] * 1; next(null); }).catch(function(err) {console.error(err)}); // ERROR LOGGED HERE }, function createThumbnail(next) { console.log("creating thumbnail..."); // use ffmpeg and metadata to create thumbnail // compute formattedTime, width, height ... cut for brevity var ffmpeg = child_process.spawn("ffmpeg", [ "-ss", formattedTime, // time to take screenshot "-i", target, // url to stream from "-vf", "thumbnail,scale="+width+":"+height, "-q:v", "2", "-vframes", "1", "-f", "image2", "-c:v", "mjpeg", "pipe:1" ]); ffmpeg.on("error", function(err) { console.log(err); }) ffmpeg.on("close", function(code) { if (code !== 0 ) { console.log("child process exited with code " + code); } else { console.log("Processing finished! Code: ", code); } tmpFile.end(); next(code); }); tmpFile.on("error", function(err) { console.log("stream err: ", err); }); ffmpeg.on("end", function() { tmpFile.end(); }); ffmpeg.stdout.pipe(tmpFile) .on("error", function(err) { console.log("error while writing: ", err); }); }, function uploadThumbnail(next) { var tmpFile = fs.createReadStream("/tmp/screenshot.jpg"); child_process.exec("echo `ls -l -R /tmp`", function (error, stdout, stderr) { console.log("upload stdout: " + stdout) }); var params = { Bucket: bucket, Key: dstKey, Body: tmpFile, ContentType: "image/jpg", ACL: "public-read", Metadata: { thumbnail: "TRUE" } }; var uploadMe = s3.upload(params); uploadMe.send( function(err, data) { if (err != null) console.log("error: " +err); next(err); } ); } ], function(err) { if (err) { console.error("Unable to generate thumbnail for '" + bucket + "/" + srcKey + "'" + " due to error: " + err); context.fail(err); } else { context.succeed("Created thumbnail for '" + bucket + "/" + srcKey + "'"); } } ); }; 

在使用Mediainfo时我无法解决这个问题。 我改为使用ffprobe来提取我所需要的video元数据,我简单地使用video持续时间…

 function createMetaData(next) { console.log('capturing video duration...'); var ffprobe = child_process.spawn('ffprobe', [ '-v', 'quiet', '-print_format', 'json', '-show_format', target ]); ffprobe.stdout.on('data', function(data) { output.push(data); }); ffprobe.on('error', function(err) { console.log('ffprobe error: ', err); }); ffprobe.on('close', function() { var outputStr = output.join(''); var jsonOut = {}; jsonOut = JSON.parse(outputStr); videoDuration = jsonOut.format && jsonOut.format.duration ? jsonOut.format.duration : 0.5; next(null); }) }