0

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

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

4

2 回答 2

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)
于 2017-01-23T15:29:59.983 回答
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/

于 2017-02-12T23:01:07.867 回答