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

使用MoviePy转换视频为GIF后体积过大,如何极致压缩?

解决GIF体积过大的优化方案

你的代码生成的GIF体积异常膨胀,核心原因是使用了未优化的默认参数。以下是针对性的压缩优化措施,按效果优先级排序:

关键优化手段

  • 降低帧率:GIF无需和原视频保持相同帧率,10-15 FPS即可保证流畅度,直接减少帧数量以压缩体积。
  • 缩小分辨率:降低视频宽高像素数,比如缩放到480p/360p,大幅减少单帧数据量。
  • 限制调色板颜色:GIF使用索引色,将默认256色降至64/128色,视觉损失极小但体积显著下降。
  • 启用FFmpeg高效压缩:利用FFmpeg的调色板优化和最高压缩级别参数。

优化后的完整代码

import asyncio  # 需引入asyncio替代time.sleep

@bot.on_message(at_state("VIDEO") & video)
async def download_video(client, message):
    downloading = await message.reply("⏳ *در حال دانلود فایل شما ...*")
    file_size = message.video.size
    max_size = 10 * 1024 * 1024
    if file_size > max_size:
        await downloading.edit_text("حجم فایل ارسالی بیشتر از 10 مگابایت است 🚫")
    else:  
        response = await client.download(message.video.id)
        mime_type = message.video.mime_type.split("/")[-1]
        file_format = mime_type.split(";")[0]
        user_id = message.author.id
        input_path = f"video-{user_id}.{file_format}"
        output_path = f"video-{user_id}.gif"
        
        with open(input_path, "wb") as file:
            file.write(response)

        await downloading.edit_text("""⌛️ *دانلود فایل شما با موفقیت به پایان رسید.
🎞️ شروع ساخت گیف ...*""")

        # 核心优化部分
        with VideoFileClip(input_path) as clip:
            # 1. 缩小分辨率至宽度480,高度按比例自动适配
            resized_clip = clip.resize(width=480)
            # 2. 降低帧率到15
            target_fps = 15
            # 3. 用FFmpeg生成优化GIF
            resized_clip.write_gif(
                output_path,
                program="ffmpeg",
                fps=target_fps,
                # FFmpeg压缩参数:64色调色板+最高压缩级别
                ffmpeg_params=[
                    "-compression_level", "9",
                    "-vf", f"fps={target_fps},palettegen=max_colors=64,paletteuse=dither=sierra2_4a"
                ]
            )

        await downloading.edit_text("""🎞️ *گیف شما با موفقیت ساخته شد.
📲 شروع ارسال گیف نهایی برای شما ...*""")
        await bot.send_animation(user_id, output_path, 60, 100, 100, "📽️ *گیف شما ساخته شد و نتیجه نهایی ارسال گردید.*")
        await downloading.edit_text("🎞️ *گیف شما با موفقیت ساخته شد.*")
        await message.reply("""*جهت ادامه کار با ربات ،
یکی از گزینه های زیر رو انتخاب کن 👇 *""",
InlineKeyboard(
    [("🎥 ویدیو به گیف 🎞️","1")],
    [("📸 عکس به گیف 🎞️","2")],
))

        # 异步清理文件,避免阻塞机器人事件循环
        await asyncio.sleep(10)
        os.remove(input_path)
        os.remove(output_path)

额外优化建议

  • 若原视频存在无关片段,可通过clip.subclip(start_time, end_time)裁剪后再转换。
  • 测试不同max_colors值(32/64/128),找到视觉质量与体积的平衡点。
  • 替换time.sleep为asyncio.sleep,避免阻塞异步事件循环导致机器人响应延迟。

内容的提问来源于stack exchange,提问作者amirali mirzaei zadeh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:01:15