简体   繁体   English

无法在AWS Lambda上使用Moviepy调整视频大小

[英]Cannot resize videos using moviepy on aws lambda

I partially created an aws lambda function that utilize moviepy to concatenate images and videos in a single video file. 我部分创建了aws lambda函数,该函数利用moviepy将单个视频文件中的图像和视频连接起来。

For example, I have “img1.jpeg”, “img2.jpeg”, “video1.mp4” and “video2.mp4”. 例如,我有“ img1.jpeg”,“ img2.jpeg”,“ video1.mp4”和“ video2.mp4”。 After processing the above files the final clip (“mp4” file) will be a single mp4 file of: “img1.jpeg + video1.mp4 + img2.jpeg + video2.mp4”. 处理完上述文件后,最终的片段(“ mp4”文件)将是一个单独的mp4文件:“ img1.jpeg + video1.mp4 + img2.jpeg + video2.mp4”。 The fresulted clip resolution is 640x480. 修剪后的剪辑分辨率为640x480。

So I resize the videos and the images (moviepy.video.fx.all.resize - resize images after converting to videos) in the case that they are greater than the aforementioned resolution. 因此,我要调整视频和图像的大小(moviepy.video.fx.all.resize-转换为视频后重新调整图像的大小),以使其大于上述分辨率。 If the media files are in the above size, I move to the concatenation process. 如果媒体文件的大小超过上述大小,我将进入串联过程。

When the media files are 640x480 all the process goes fine. 当媒体文件为640x480时,所有过程都可以进行。 The issue is when the media are larger than 640x480 I get an error: 问题是当媒体大于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.

The above is from aws lambda logs. 以上是来自aws lambda日志。 The funny thing is, that when I ran it locally it works. 有趣的是,当我在本地运行它时,它可以工作。

Has anyone ever faced a similar issue or is anyone able to give me some pointers on how to tackle this problem? 有没有人遇到过类似的问题,或者有人可以给我一些如何解决这个问题的指示?

With lambda file permissions can be funny. 使用lambda文件权限可能很有趣。 Use /tmp for any temp, working files etc. 对任何临时文件,工作文件等使用/ tmp。

Not sure if that will help but good to know. 不确定是否会有所帮助,但很高兴知道。

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)
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))

Download 64 bit static and unzip it and add 2 files to the lambda zip https://www.johnvansickle.com/ffmpeg/ 下载64位静态文件并解压缩,然后将2个文件添加到lambda zip文件中https://www.johnvansickle.com/ffmpeg/

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

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