3

Objective

To calculate the duration of a wav file which is saved in S3 by AWS Lambda using node.js. I had to add ffmpeg and ffprobe executable inside a lambda layer (Downloaded linux-64 version from here). These files could be found in /opt folder on lambda file system.

What I have tried

I have been trying using ffprobe in numerous ways, but I get Invalid Data as error. Here's one example

const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const fs = require('fs');
const ffmpeg = require('fluent-ffmpeg');

exports.handler = async function(event) {
    let path = await load();
    console.log(`Saved Path ${path}`);

    ffmpeg.setFfmpegPath('/opt/ffmpeg');
    ffmpeg.setFfprobePath("/opt/ffprobe");

    let dur = await duration(path).catch(err => {
        console.log(err);
    })
    console.log(dur);
}


function duration(path) {
    return new Promise((resolve, reject) => {
        ffmpeg(path).ffprobe(path, function(err, metadata) {
            //console.dir(metadata); // all metadata
            if (err) {
                reject(err);
            }
            else {
                resolve(metadata.format.duration);

            }
        });
    })
}

async function listFiles(path) {
    console.log('list files');
    return new Promise((resolve, reject) => {
        fs.readdir(path, (err, files) => {
            if (err) {
                console.error('Error in readdir');
                reject(err);
            }
            else {
                console.log('recieved files');
                resolve(files);
            }

        });

    });

}

async function load() {
    return new Promise((resolve, reject) => {
        let params = {
            Key: 'Fanfare60.wav',
            Bucket: 'samplevideosshamim'
        };
        console.log(`Getting s3 object : ${JSON.stringify(params)}`);
        s3.getObject(params, (err, data) => {
            if (err) {
                console.error(err);
                reject(err);
            }
            else if (data) {
                console.log('Recieved Data');
                let path = `/tmp/${params.Key}`;
                console.log('Path: ' + path);
                fs.writeFileSync(path, data.body);
                resolve(path);
            }
        });
    });

}

Error:

Error: ffprobe exited with code 1
ffprobe version 4.2.1-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2007-2019 the FFmpeg developers
  built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
/tmp/Fanfare60.wav: Invalid data found when processing input

    at ChildProcess.<anonymous> (/var/task/node_modules/fluent-ffmpeg/lib/ffprobe.js:233:22)
    at ChildProcess.emit (events.js:314:20)
    at ChildProcess.EventEmitter.emit (domain.js:483:12)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:276:12)

I am guessing it doesn't support wav format, but internet searches provide no proof of that.

A point to note here is, I was able to get the duration of a local file when I ran this code on my local machine, but I have a windows machine, so perhaps only linux executable of ffprobe has issue?

Possible Solutions I am looking for

  1. Is there a way to specify format?
  2. Can I use a different library (code example for the same)?
  3. Any possible way to get duration of a wav file in the mentioned scenario (AWS Lambda NodeJS and S3 file (private file)?
Salim Shamim
  • 656
  • 10
  • 25

0 Answers0