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

如何使用Python将FFmpeg的输出直接存储到S3存储桶中

视频转码结果直接上传S3的两种可落地方案

方案1:本地临时文件中转(最稳妥,易调试)

适合视频文件不大、服务器磁盘空间充足的场景,开发成本低,出错后易排查。

import boto3
import subprocess
import os

# 替换为你的实际配置
S3_REGION = "你的S3区域"
S3_ACCESS_KEY_ID = "你的S3访问密钥ID"
S3_ACCESS_SECRET_KEY = "你的S3访问密钥"
S3_BUCKET = "目标S3桶名"

avi_file_path = "本地输入的AVI文件路径"
output_name = "输出文件的名称(不带后缀)"
local_output_path = f"{output_name}.mp4"

s3 = boto3.client('s3',
            region_name = S3_REGION,
            aws_access_key_id = S3_ACCESS_KEY_ID, 
            aws_secret_access_key = S3_ACCESS_SECRET_KEY)

# 执行转码,捕获执行状态
ffmpeg_cmd = [
    "ffmpeg", "-i", avi_file_path,
    "-ac", "2", "-b:v", "2000k", "-c:a", "aac", "-c:v", "libx264",
    "-b:a", "160k", "-vprofile", "high", "-bf", "0", "-strict", "experimental",
    "-f", "mp4", local_output_path
]
result = subprocess.run(ffmpeg_cmd, capture_output=True, text=True)

if result.returncode != 0:
    print(f"转码失败,错误日志:{result.stderr}")
else:
    # 上传到S3,s3_key为文件在桶内的存储路径
    s3_key = f"transcoded_videos/{output_name}.mp4"
    s3.upload_file(local_output_path, S3_BUCKET, s3_key)
    # 上传完成后清理本地临时文件,按需开启
    os.remove(local_output_path)
    # 若输入文件也是临时下载的,也可同步删除
    # os.remove(avi_file_path)

方案2:流式直接上传(无本地磁盘占用,适合大文件)

无需写入本地磁盘,直接把ffmpeg的输出流上传到S3,适合大视频、服务器磁盘空间有限的场景。

import boto3
import subprocess
from io import BytesIO

# 替换为你的实际配置
S3_REGION = "你的S3区域"
S3_ACCESS_KEY_ID = "你的S3访问密钥ID"
S3_ACCESS_SECRET_KEY = "你的S3访问密钥"
S3_BUCKET = "目标S3桶名"

avi_file_path = "本地输入的AVI文件路径"
# 转码后文件在S3的存储路径
output_s3_key = "transcoded_videos/你的输出文件名.mp4"

s3 = boto3.client('s3',
            region_name = S3_REGION,
            aws_access_key_id = S3_ACCESS_KEY_ID, 
            aws_secret_access_key = S3_ACCESS_SECRET_KEY)

# ffmpeg输出到stdout,新增movflags参数保证mp4支持流式输出
ffmpeg_cmd = [
    "ffmpeg", "-i", avi_file_path,
    "-ac", "2", "-b:v", "2000k", "-c:a", "aac", "-c:v", "libx264",
    "-b:a", "160k", "-vprofile", "high", "-bf", "0", "-strict", "experimental",
    "-movflags", "frag_keyframe+empty_moov",
    "-f", "mp4", "-"
]

# 启动ffmpeg进程,捕获标准输出流
process = subprocess.Popen(ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# 直接将流转上传到S3
s3.upload_fileobj(BytesIO(process.stdout.read()), S3_BUCKET, output_s3_key)

# 校验转码执行结果
stderr = process.stderr.read().decode()
if process.wait() != 0:
    print(f"转码失败,错误日志:{stderr}")
    # 按需删除S3上的无效文件
    s3.delete_object(Bucket=S3_BUCKET, Key=output_s3_key)

注意事项

  • 不要使用os.popen调用ffmpeg,无法捕获错误状态和运行日志,转码失败时无法感知,统一使用subprocess模块更稳妥
  • S3访问凭证需要配置对应桶的s3:PutObject权限,如果需要清理上传失败的无效文件,还要额外开通s3:DeleteObject权限
  • 如果输入视频本身存储在S3上,可先调用s3.download_file下载到本地临时路径再执行转码,更高阶的场景也可以配合S3流式下载和ffmpeg流式输入做到全链路无本地文件
  • 10GB以上的大文件场景无需额外开发,boto3的upload_file和upload_fileobj默认开启自动分片上传,稳定性有保障

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:48:03