You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Lambda从S3加载.mov视频读取StreamingBody报错如何解决

问题根因

两个报错本质都是混淆了二进制数据和文本数据的处理逻辑:

  • 'utf-8' codec can't decode byte 错误:.mov是二进制格式文件,不是UTF-8编码的文本,你调用.read().decode()强行把二进制字节流按文本规则解析,必然触发编码错误。所有图片、视频、压缩包这类非文本文件,都不能直接用文本编码解码成字符串。
  • endswith first arg must be bytes or a tuple of bytes, not str 错误:这个是参数类型传错导致的,常见触发场景有三个:一是把读取到的视频字节内容当成文件路径传给了视频处理库,库内部做后缀判断时拿到字节而非路径字符串就会抛错;二是读写文件时混用了文本模式和二进制模式;三是构造内存流后调用处理接口时,没有给接口提供正确的格式后缀标识,接口做后缀校验时参数类型不匹配。
正确实现代码

Lambda环境下处理S3上的.mov视频,根据你后续用的视频处理库是否支持内存流,分两种写法,核心是不要对二进制字节流做文本转码,IO操作明确指定二进制模式:

import json
import urllib.parse
import boto3
import os
from io import BytesIO
# 按需导入你用的视频处理库,比如opencv、moviepy
# import cv2
# import numpy as np
# from moviepy.editor import VideoFileClip

print('Loading function')
s3 = boto3.client('s3')


def lambda_handler(event, context):
    bucket = os.environ['SOURCE_BUCKET_NAME']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')

    try:
        s3_resp = s3.get_object(Bucket=bucket, Key=key)
        # 直接读取二进制字节,绝对不要调用decode()转字符串
        video_bytes = s3_resp['Body'].read()

        # --- 写法1:内存流处理,适合小视频、库支持类文件对象入参的场景 ---
        video_stream = BytesIO(video_bytes)
        # moviepy 读内存流示例,传带.mov后缀的虚拟文件名帮库识别格式
        # clip = VideoFileClip(video_stream, audio=True)
        # opencv 读内存流示例
        # img_array = np.asarray(bytearray(video_bytes), dtype=np.uint8)
        # cap = cv2.VideoCapture(img_array, cv2.CAP_FFMPEG)

        # --- 写法2:落地到临时目录处理,适合大视频、库只支持本地文件路径的场景 ---
        # Lambda只有/tmp目录可写,默认512M,可在配置里最高调到10G
        local_file_path = f"/tmp/{os.path.basename(key)}"
        # 写二进制文件必须指定wb模式,不能用默认的w文本模式
        with open(local_file_path, "wb") as f:
            f.write(video_bytes)
        # 之后直接传本地路径给处理库即可
        # cap = cv2.VideoCapture(local_file_path)

        return {
            "statusCode": 200,
            "body": json.dumps("video load success")
        }
        
    except Exception as e:
        print(e)
        print(f'Error getting object {key} from bucket {bucket}. Make sure they exist and your bucket is in the same region as this function.')
        raise e
注意事项
  • Lambda内存配置必须大于你要处理的单视频大小,如果用内存流处理,还要预留出视频处理库运行的内存占用,否则会触发OOM被强杀。
  • 所有二进制文件的读写操作,都要显式指定rb(读二进制)、wb(写二进制)模式,不要用默认的文本模式,否则Python会自动做编码转换,损坏视频文件内容。
  • 大部分视频处理库会根据文件后缀判断封装格式,不管是传内存流还是本地文件,都要保证文件名后缀和实际格式一致(这里是.mov),否则容易触发格式识别错误。
  • 大体积视频不建议直接全量读到内存处理,优先落地到/tmp目录,或者用分块读取的方式处理,避免超出Lambda内存限制。

内容的提问来源于stack exchange,提问作者munkaboo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:45:31