【问题标题】:Cannot resize videos using moviepy on aws lambda无法在 aws lambda 上使用 moviepy 调整视频大小
【发布时间】:2017-02-13 07:01:07
【问题描述】:

我部分创建了一个 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 日志。有趣的是,当我在本地运行它时,它可以工作。

有没有人遇到过类似的问题,或者有人能给我一些关于如何解决这个问题的建议吗?

【问题讨论】:

  • 顺便说一下,请忽略关于音频比特率的最后一行。这只是一个通用的评论。

标签: python aws-lambda moviepy


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    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/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2014-04-06
      • 2019-04-28
      • 2021-03-04
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      相关资源
      最近更新 更多