繁体   English   中英

AWS Lambda子进程OSError:[Errno 2]没有这样的文件或目录

[英]AWS Lambda subprocess OSError: [Errno 2] No such file or directory

我正在尝试创建一个lambda函数,使用ffmpeg从亚马逊s3上的视频中收集缩略图。 ffmpeg二进制文件包含在功能包中。

功能代码:

# -*- coding: utf-8 -*-

import stat
import shutil
import boto3
import logging
import subprocess as sp
import os
import threading

thumbnail_prefix = 'thumb_'
thumbnail_ext = '.jpg'
time_delta = 1
video_frames_path = 'media/videos/frames'

print('Loading function')
logger = logging.getLogger()
logger.setLevel(logging.INFO)

lambda_tmp_dir = '/tmp'  # Lambda fuction can use this directory.

# ffmpeg is stored with this script.
# When executing ffmpeg, execute permission is requierd.
# But Lambda source directory do not have permission to change it.
# So move ffmpeg binary to `/tmp` and add permission.
ffmpeg_bin = "{0}/ffmpeg.linux64".format(lambda_tmp_dir)
shutil.copyfile('/var/task/ffmpeg.linux64', ffmpeg_bin)

os.chmod(ffmpeg_bin, 777)

# tried also:
# os.chmod(ffmpeg_bin, os.stat(ffmpeg_bin).st_mode | stat.S_IEXEC)

s3 = boto3.client('s3')


def get_thumb_filename(num):
    return '{prefix}{num:03d}{ext}'.format(prefix=thumbnail_prefix, num=num, ext=thumbnail_ext)


def create_thumbnails(video_url):
    i = 1
    filenames_list = []
    filename = None
    while i == 1 or os.path.isfile(os.path.join(os.getcwd(), get_thumb_filename(i-1))):
        if filename:
            filenames_list.append(filename)
        time = time_delta * (i - 1)
        filename = get_thumb_filename(i)
        print(ffmpeg_bin)
        if os.path.isfile(ffmpeg_bin):
            print('ok')
        sp.call(['sudo',
                 ffmpeg_bin,
                 '-ss',
                 str(time),
                 '-i',
                 video_url,
                 '-frames:v',
                 '1',
                 get_thumb_filename(i)])
        i += 1
    print(filenames_list)
    return filenames_list


def s3_upload_file(file_path, key, bucket, acl, content_type):
    file = open(file_path, 'r')
    s3.put_object(
        Bucket=bucket,
        ACL=acl,
        Body=file,
        Key=key,
        ContentType=content_type
    )
    logger.info("file {0} moved to {1}/{2}".format(file_path, bucket, key))


def s3_upload_files_in_threads(filenames_list, dir_path, bucket, s3path, acl, content_type):
    for filename in filenames_list:
        if os.path.isfile(os.path.join(dir_path, filename)):
            print(os.path.join(dir_path, filename))
        t = threading.Thread(target=s3_upload_file,
                             args=(os.path.join(dir_path, filename),
                                   '{0}/{1}'.format(s3path, filename),
                                   bucket,
                                   acl,
                                   content_type)).start()


def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    video_key = event['Records'][0]['s3']['object']['key']
    video_name = video_key.split('/')[-1].split('.')[0]
    video_url = 'http://{0}/{1}'.format(bucket, video_key)
    filenames_list = create_thumbnails(video_url)
    s3_upload_files_in_threads(filenames_list,
                               os.getcwd(),
                               bucket,
                               '{0}/{1}'.format(video_frames_path, video_name),
                               'public-read',
                               'image/jpeg')
    return

在执行期间,我得到以下日志:

Loading function

/tmp/ffmpeg.linux64

ok

[Errno 2] No such file or directory: OSError
Traceback (most recent call last):
 File "/var/task/lambda_function.py", line 112, in lambda_handler
 filenames_list = create_thumbnails(video_url)
 File "/var/task/lambda_function.py", line 77, in create_thumbnails
 get_thumb_filename(i)])
 File "/usr/lib64/python2.7/subprocess.py", line 522, in call
 return Popen(*popenargs, **kwargs).wait()
 File "/usr/lib64/python2.7/subprocess.py", line 710, in __init__
 errread, errwrite)
 File "/usr/lib64/python2.7/subprocess.py", line 1335, in _execute_child
 raise child_exception
OSError: [Errno 2] No such file or directory

当我在ec2实例上使用相同的sp.call()和相同的ffmpeg二进制文件时,它可以正常工作。

问题不在于ffmpeg 错误是找不到sudo Lambda实例没有sudo 你为什么需要sudo 你可以打印传递给sp.call()吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM