Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FFmpeg transcoding on Lambda results in unusable (static) audio

I'd like to move towards serverless for audio transcoding routines in AWS. I've been trying to setup a Lambda function to do just that; execute a static FFmpeg binary and re-upload the resulting audio file. The static binary I'm using is here.

The Lambda function I'm using in Python looks like this:

import boto3

s3client = boto3.client('s3')
s3resource = boto3.client('s3')

import json
import subprocess 

from io import BytesIO

import os

os.system("cp -ra ./bin/ffmpeg /tmp/")
os.system("chmod -R 775 /tmp")

def lambda_handler(event, context):

    bucketname = event["Records"][0]["s3"]["bucket"]["name"]
    filename = event["Records"][0]["s3"]["object"]["key"]

    audioData = grabFromS3(bucketname, filename)

    with open('/tmp/' + filename, 'wb') as f:
        f.write(audioData.read())

    os.chdir('/tmp/')

    try:
        process = subprocess.check_output(['./ffmpeg -i /tmp/joe_and_bill.wav /tmp/joe_and_bill.aac'], shell=True, stderr=subprocess.STDOUT)
        pushToS3(bucketname, filename)
        return process.decode('utf-8')
    except subprocess.CalledProcessError as e:
        return e.output.decode('utf-8'), os.listdir()


def grabFromS3(bucket, file):

    obj = s3client.get_object(Bucket=bucket, Key=file)
    data = BytesIO(obj['Body'].read())

    return(data)

def pushToS3(bucket, file):

    s3client.upload_file('/tmp/' + file[:-4] + '.aac', bucket, file[:-4] + '.aac')

    return

You can listen to the output of this here. WARNING: Turn your volume down or your ears will bleed.

The original file can be heard here.

Does anyone have any idea what might be causing the encoding errors? It doesn't seem to be an issue with the file upload, since the md5 on the Lambda fs matches the MD5 of the uploaded file.

I've also tried building the static binary on an Amazon Linux instance in EC2, then zipping and porting it into the Lambda project, but the same issue persists.

I'm stumped! :(

like image 803
jmkmay Avatar asked Aug 24 '18 15:08

jmkmay


1 Answers

Alright this is a fun one.

So it turns out the Python subprocess inherits stdin from some Lambda processes going on in the background. I was watching this AWS re:Invent keynote and he was describing some issues they were having w.r.t. this issue.

I added stdin=subprocess.DEVNULL to the subprocess call and the audio is now fixed.

Very interesting bug if you ask me.

like image 175
jmkmay Avatar answered Nov 26 '22 04:11

jmkmay