使用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
相关产品推荐
相关产品推荐

