无法在aws lambda上使用moviepy调整视频大小

时间:2017-01-19 15:43:38

标签: python aws-lambda moviepy

我部分创建了一个aws lambda函数,该函数利用moviepy在单个视频文件中连接图像和视频。

例如,我有“img1.jpeg”,“img2.jpeg”,“video1.mp4”和“video2.mp4”。处理完上述文件后,最终剪辑(“mp4”文件)将是一个单独的mp4文件:“img1.jpeg + video1.mp4 + img2.jpeg + video2.mp4”。定制的剪辑分辨率为640x480。

所以我调整视频和图像的大小(moviepy.video.fx.all.resize - 转换为视频后调整图像大小),如果它们大于上述分辨率。如果媒体文件的大小合适,我将进入连接过程。

当媒体文件为640x480时,所有过程都可以正常进行。问题是当媒体大于640x480时,我收到错误:

[Errno 32] Broken pipe

MoviePy error: FFMPEG encountered the following error while writing file 1_img_transTEMP_MPY_wvf_snd.mp3:

1_img_transTEMP_MPY_wvf_snd.mp3: Permission denied


The audio export failed, possily because the bitrate you specified was two high or too low for the video codec.: IOError
Traceback (most recent call last):
File "/var/task/media_merge.py", line 70, in handler
s.do_merge()
File "/var/task/mediamerge/stitch_video_and_images.py", line 320, in do_merge
self.convert_crop_media()
File "/var/task/mediamerge/stitch_video_and_images.py", line 310, in convert_crop_media
res_path = resize.resize_media()
File "/var/task/mediamerge/stitch_video_and_images.py", line 229, in resize_media
self.final_media_file, verbose=False)
File "<decorator-gen-51>", line 2, in write_videofile
File "/var/task/moviepy/decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
File "<decorator-gen-50>", line 2, in write_videofile
File "/var/task/moviepy/decorators.py", line 137, in use_clip_fps_by_default
return f(clip, *new_a, **new_kw)
File "<decorator-gen-49>", line 2, in write_videofile
File "/var/task/moviepy/decorators.py", line 22, in convert_masks_to_RGB
return f(clip, *a, **k)
File "/var/task/moviepy/video/VideoClip.py", line 331, in write_videofile
verbose=verbose)
File "<decorator-gen-73>", line 2, in write_audiofile
File "/var/task/moviepy/decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
File "/var/task/moviepy/audio/AudioClip.py", line 204, in write_audiofile
verbose=verbose, ffmpeg_params=ffmpeg_params)
File "<decorator-gen-70>", line 2, in ffmpeg_audiowrite
File "/var/task/moviepy/decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
File "/var/task/moviepy/audio/io/ffmpeg_audiowriter.py", line 162, in ffmpeg_audiowrite
writer.write_frames(chunk)
File "/var/task/moviepy/audio/io/ffmpeg_audiowriter.py", line 122, in write_frames
raise IOError(error)
IOError: [Errno 32] Broken pipe

MoviePy error: FFMPEG encountered the following error while writing file 1_img_transTEMP_MPY_wvf_snd.mp3:

1_img_transTEMP_MPY_wvf_snd.mp3: Permission denied


The audio export failed, possily because the bitrate you specified was two high or too low for the video codec.

以上是来自aws lambda日志。有趣的是,当我在本地运行时,它可以工作。

有没有人遇到类似的问题,或者是否有人能够就如何解决这个问题给我一些指示?

2 个答案:

答案 0 :(得分:0)

使用lambda文件权限可能很有趣。对于任何临时工作文件等使用/ tmp。

不确定这是否有帮助,但很高兴知道。

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
LIB_DIR = os.path.join(SCRIPT_DIR, 'lib')



lambda_tmp_dir = '/tmp' # Lambda fuction can use this directory.
image_path = "{0}/{1}".format(lambda_tmp_dir, "images")
video_path = "{0}/{1}".format(lambda_tmp_dir, "video")
video_name = "video.mp4"

# 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_BINARY = "{0}/ffmpeg".format(lambda_tmp_dir)
shutil.copyfile('/var/task/ffmpeg/ffmpeg', FFMPEG_BINARY)
FFPROBE_BINARY = "{0}/ffprobe".format(lambda_tmp_dir)
shutil.copyfile('/var/task/ffmpeg/ffprobe', FFPROBE_BINARY)

os.environ['FFPROBE'] = FFPROBE_BINARY
os.environ['FFMPEG'] = FFMPEG_BINARY
os.chmod(FFPROBE_BINARY, os.stat(FFPROBE_BINARY).st_mode | stat.S_IEXEC)
os.chmod(FFMPEG_BINARY, os.stat(FFMPEG_BINARY).st_mode | stat.S_IEXEC)

答案 1 :(得分:0)

from __future__ import print_function
import uuid
import boto3
from botocore.exceptions import ClientError

from moviepy.config import change_settings

import os
from shutil import copyfile
import stat

lambda_tmp_dir = '/tmp'
FFMPEG_BINARY = "{0}/ffmpeg".format(lambda_tmp_dir)
change_settings({"FFMPEG_BINARY": FFMPEG_BINARY})
copyfile('/var/task/ffmpeg', FFMPEG_BINARY)
FFPROBE_BINARY = "{0}/ffprobe".format(lambda_tmp_dir)
copyfile('/var/task/ffprobe', FFPROBE_BINARY)
os.environ['FFPROBE'] = FFPROBE_BINARY
os.environ['FFMPEG'] = FFMPEG_BINARY
os.chmod(FFPROBE_BINARY, os.stat(FFPROBE_BINARY).st_mode | stat.S_IEXEC)
os.chmod(FFMPEG_BINARY, os.stat(FFMPEG_BINARY).st_mode | stat.S_IEXEC)


def lambda_handler(event, context):
    from moviepy.video.io.VideoFileClip import VideoFileClip
    from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
    s3_client = boto3.client('s3')
    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        key = record['s3']['object']['key']
        print('{} - {}'.format(bucket, key))
        key_without_path = key.replace('/', '')
        source_file = '/tmp/{}{}'.format(uuid.uuid4(), key_without_path)
        try:
            s3_client.download_file(bucket, key, source_file)
        except ClientError as e:
            if e.response['Error']['Code'] == "404":
                return None
        try:
            short_clip_path = '/tmp/resized{}{}'.format(uuid.uuid4(), key_without_path)
            ffmpeg_extract_subclip(source_file, 2, 5, targetname=short_clip_path)
            clip = VideoFileClip(source_file)
            print('clip.duration = {}'.format(clip.duration))
            clip.save_frame("{}.jpg".format(short_clip_path), t=4.00)

            if clip.duration > 5:
                print('clip bigger then 5')
        except:
            return None
        s3_client.upload_file(short_clip_path, bucket.replace('-', '-thumb-'), key)
        s3_client.upload_file("{}.jpg".format(short_clip_path), bucket.replace('-', '-thumb-'), "{}.jpg".format(key))

下载64位静态并解压缩并将2个文件添加到lambda zip https://www.johnvansickle.com/ffmpeg/