如何直接从S3读取MP4文件至MoviePy?已遇报错求解决
解决MoviePy读取S3中MP4文件的报错问题
你的问题出在MoviePy的VideoFileClip初始化时会检查输入对象的文件名后缀,而BytesIO对象并没有endswith方法(这个方法是字符串/文件路径才有的),所以触发了AttributeError。下面给你两种可行的解决方案:
方案1:给BytesIO对象添加文件名属性及方法
我们可以创建一个继承自BytesIO的自定义类,补充endswith方法和name属性,让MoviePy能识别它的文件类型:
import boto3 from io import BytesIO from moviepy.editor import VideoFileClip class NamedBytesIO(BytesIO): def __init__(self, data, filename): super().__init__(data) self.name = filename # 给对象添加文件名属性 def endswith(self, suffix): # 让endswith方法基于文件名判断 return self.name.endswith(suffix) # 读取S3文件 client = boto3.client('s3') obj = client.get_object(Bucket='some-bucket', Key='some-file') # 使用自定义类包装S3的二进制内容 buf = NamedBytesIO(obj['Body'].read(), 'some-file.mp4') # 现在可以正常创建VideoFileClip了 clip = VideoFileClip(buf)
这个方法不需要写入磁盘,直接在内存中处理,适合处理中等大小的视频文件。
方案2:使用临时文件中转
如果视频文件比较大,内存处理压力大,可以把S3的文件内容写入临时文件,再用MoviePy读取:
import boto3 import tempfile import os from moviepy.editor import VideoFileClip client = boto3.client('s3') obj = client.get_object(Bucket='some-bucket', Key='some-file') # 创建临时MP4文件 with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as tmp_file: tmp_file.write(obj['Body'].read()) tmp_file_path = tmp_file.name # 读取临时文件创建VideoFileClip clip = VideoFileClip(tmp_file_path) # 处理完视频后记得删除临时文件(避免磁盘占用) os.unlink(tmp_file_path)
这个方法的优势是对内存友好,适合大文件,但需要注意清理临时文件。
内容的提问来源于stack exchange,提问作者racket99
相关产品推荐
相关产品推荐

