Search code examples
amazon-web-servicesaws-lambdaffmpeg

AWS Lambda - FFmpeg to extract frames doesn't write anything


I have a lambda with a ffmpeg layer on it.

The command i want to use is basically

ffmpeg -i video.mp4 -qscale:v 2 -vf fps=8 '%04d.jpg'

so it has an input file, and creates 8 frames per second in the same folder

This code seems to do everything except writing the files, what am I missing ?

import ...
SIGNED_URL_TIMEOUT = 60
FPS_SAMPLES = 8

def lambda_handler(event, context):
    # Set up logging.
    logger = logging.getLogger(__name__)

    s3_client = boto3.client('s3')

    s3_source_bucket = event['Records'][0]['s3']['bucket']['name']
    s3_source_key = event['Records'][0]['s3']['object']['key']

    s3_source_basename = os.path.splitext(os.path.basename(s3_source_key))[0]

    logger.info( "bucket: %s, key: %s, basename: %s",s3_source_bucket, s3_source_key, s3_source_basename)

    s3_source_signed_url = s3_client.generate_presigned_url('get_object',
    Params={'Bucket': s3_source_bucket, 'Key': s3_source_key},
    ExpiresIn=SIGNED_URL_TIMEOUT)

    with tempfile.TemporaryDirectory() as tmpdir:
        os.chdir(tmpdir) # change the current folder to that one (current one is in     os.getcwd())
        cwd = os.getcwd()
        ffmpeg_cmd = "/opt/bin/ffmpeg -i \"" + s3_source_signed_url + "\" -qscale:v 2 -vf fps="+str(FPS_SAMPLES)+" "+ cwd + "/'%04d.jpg'"
    print("COMMAND: "+ffmpeg_cmd)
    
        command1 = shlex.split(ffmpeg_cmd)
        p1 = subprocess.run(command1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        # List all files and directories in the current directory
        contents = os.listdir(cwd)
    
        # Print the contents
        print(f"Contents of {cwd}:")
        for item in contents:
            print(item) # <--- NOthing here...

   
return {
    'statusCode': 200,
    'body': json.dumps("bucket: %s, key: %s, basename: %s" % (s3_source_bucket, s3_source_key, s3_source_basename))
}

Solution

  • AWS Lambda functions can only write to the /tmp/ directory, so make sure the temporary directory is being created there.

    It might also be better to have the Lambda function download the input file to /tmp/ and then pass that file to ffmpeg. This way, you can better diagnose what might be happening.

    Also, please note that the Lambda environment might be re-used, so it is generally a good idea to delete newly-created files before exiting the Lambda function otherwise the available disk space (512MB by default) might be filled by subsequent executions.