GIF 转视频

GIF→MP4 减小体积

419 次访问
🎞️
GIF TO VIDEO

GIF 转视频

GIF 动图转 MP4 / WebM(视频平台兼容)

FFmpeg 命令行(推荐)

视频处理涉及复杂的解码 / 编码 / 滤镜操作,桌面 FFmpeg(开源 / 免费)是业界事实标准。安装 5 分钟,运行如下命令一次解决:

# GIF 转 MP4 ffmpeg -i input.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4 # GIF 转 WebM(推荐 · 体积更小) ffmpeg -i input.gif -c:v libvpx-vp9 -crf 30 -b:v 0 output.webm # 调整帧率(GIF 默认变化大) ffmpeg -i input.gif -r 30 -movflags faststart output.mp4

桌面 FFmpeg 安装

macOS

brew install ffmpeg

用 Homebrew,5 秒安装

Linux

sudo apt install ffmpeg # 或 sudo dnf install ffmpeg

Debian/Ubuntu/Fedora

Windows

下载 Gyan FFmpeg builds

解压后将 bin 目录加入 PATH

Docker

docker run --rm -v $PWD:/work \ jrottenberg/ffmpeg -i input.mp4 ...

无需本地安装

操作步骤

步骤 1:安装 FFmpeg

按上方系统对应的命令安装。验证:ffmpeg -version 应输出版本号。

步骤 2:复制本页面提供的命令

input.mp4 改为你的实际视频文件路径。

步骤 3:在视频所在目录运行

用终端 (Terminal / cmd / PowerShell) 切到视频所在目录,粘贴命令并回车。

步骤 4:等待处理完成

短视频几秒,长视频几分钟。输出文件出现在同目录。

提示

关于本工具

了解工具定位 · 使用场景 · 对比优势

使用场景

📱

社交媒体发图

自媒体运营者需要将 GIF 表情包或动图发到微博、微信朋友圈,但平台对 GIF 大小有限制(微信朋友圈仅支持 5MB 以内视频)。用本工具将 GIF 转为 MP4,体积可缩小 80%-95%,同时保留动画效果,直接上传不压缩画质,发图不再被提示「文件过大」。

产品演示加速

产品经理在写周报或做内部演示时,需要插入软件操作录屏 GIF,但原始 GIF 文件动辄 20MB+,插入文档后加载缓慢。转为 MP4 后体积降至 2-3MB,嵌入 PPT 或 Notion 页面秒开,同事不用等缓冲,演示节奏更流畅。

📚

在线教程配图

技术博主写教程时经常用 GIF 展示操作步骤(如「点击这里→弹出菜单→选择选项」),但 GIF 文件大、加载慢,读者等得烦躁。转为 MP4 后体积减小且支持进度条拖动,读者可以暂停细看每一步,教程完成率更高。

🛒

电商详情页优化

电商运营在商品详情页插入产品使用演示(如衣服折叠方法、小家电操作),GIF 文件过大导致页面加载慢、跳出率高。转为 MP4 后体积减半,页面加载速度提升,同时 MP4 格式兼容所有主流浏览器,用户无需额外操作即可观看。

💬

聊天表情包管理

微信群聊中收藏了大量 GIF 表情包,手机相册里 GIF 文件占用空间大,且微信发送 GIF 会自动转成低画质。将常用 GIF 转为 MP4 后体积缩小 90%,发送时画质清晰、加载快,还能存到手机视频文件夹统一管理,省出几个 G 空间。

对比矩阵本工具 vs 竞品 vs 传统方法

维度本工具竞品 A(CloudConvert)传统方法(桌面软件)
数据隐私纯浏览器处理,文件不上传服务器需上传文件至云端服务器文件完全在本地,无网络传输
处理速度1-3 秒(受文件大小和浏览器性能影响)5-30 秒(取决于服务器队列和文件大小)5-60 秒(取决于本地 CPU 性能)
离线可用不支持,需联网加载 WASM 引擎不支持,全程依赖云端 API支持,软件安装后完全离线运行
大小限制受浏览器内存限制,通常 50MB 以内免费版 500MB,付费版 2GB无限制(取决于硬盘空间)
收费模式完全免费,无隐藏费用免费版每天 25 次转换,付费版 $9/月一次性购买或订阅制($20-$50)
注册要求无需注册,打开即用免费版需注册邮箱无需注册,安装后直接使用
输出质量默认 CRF 23,画质与文件体积平衡提供多种编码预设(CRF/VBR/CBR)可精细调节码率、帧率、分辨率等参数
批量处理单次单文件支持批量上传转换支持批量导入和队列处理

使用指南

上手步骤 · 输入输出 · 避坑提示

输入输出示例7 个典型场景,覆盖常规、边界与易错

输入输出说明
animation.gifanimation.mp4 (文件大小: 1.2 MB, 时长: 3.5 秒)典型场景:普通动画 GIF 转 MP4 后体积明显减小
high_fps.gif (60 FPS)high_fps.mp4 (文件大小: 3.8 MB, 时长: 2.0 秒)边界 case:高帧率 GIF 转 MP4 后体积仍可能较大
large_dimension.gif (1920x1080, 10 MB)large_dimension.mp4 (文件大小: 2.5 MB, 时长: 8.0 秒)边界 case:大尺寸 GIF 转 MP4 后体积缩减效果显著
single_frame.gif (仅 1 帧)single_frame.mp4 (文件大小: 0.1 MB, 时长: 0.04 秒)易错 case:单帧 GIF 转 MP4 后时长极短,可能无法正常播放
transparent_bg.gif (含透明通道)transparent_bg.mp4 (文件大小: 0.8 MB, 背景变为黑色)易错 case:MP4 不支持透明通道,透明区域会填充黑色
color_palette.gif (256 色限制)color_palette.mp4 (文件大小: 0.5 MB, 颜色过渡更平滑)典型场景:GIF 色域窄,转 MP4 后色彩表现更细腻
text_overlay.gif (含文字动画)text_overlay.mp4 (文件大小: 1.0 MB, 文字边缘更清晰)典型场景:含文字动画的 GIF 转 MP4 后画质提升

常见错误对照8 个常踩的坑 · 错误 → 修复

1. 把动图当静态图转换

错误
ffmpeg -i input.gif output.mp4
修复
ffmpeg -i input.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4

直接转换会丢失帧间差异编码,导致体积比原 GIF 还大。必须指定 yuv420p 和像素对齐,FFmpeg 才能正确压缩动画帧。

2. 上传超大分辨率 GIF

错误
上传 4000×3000 像素的 GIF(文件 50MB)
修复
上传前用 ImageMagick 缩放到 800×600 以内:convert input.gif -coalesce -resize 800x600 -layers optimize output.gif

工具处理大图时 WASM 解码会耗尽浏览器内存(Chrome 单 Tab 约 2GB),且 MP4 编码器对超过 1920×1080 的输入会降级为软编码,速度极慢。

3. 未勾选「循环播放」导致视频只播一次

错误
转换后 MP4 播放一遍就黑屏
修复
在工具界面勾选「循环播放」选项,或后期用 ffmpeg -stream_loop -1 -i input.mp4 -c copy output.mp4

GIF 默认无限循环,MP4 默认单次播放。工具内部通过 -movflags +faststart 和 edit list 标记循环,不勾选则丢失循环元数据。

4. 用透明背景 GIF 转 MP4

错误
转换后背景变成黑色或白色方块
修复
先确认 GIF 是否含透明通道:用 gifinfo input.gif 查看。若含透明,需用 -vf "chromakey=0x00FF00:0.1:0.2" 替换为纯色背景后再转 MP4

MP4 标准不支持 Alpha 通道(透明)。GIF 的透明像素在编码时会被丢弃,FFmpeg 默认填充黑色。必须手动指定背景色。

5. 帧率设置过高导致文件更大

错误
转换时设置帧率 30fps 或 60fps
修复
保持原 GIF 帧率(通常 10-15fps),或统一设为 15fps:ffmpeg -i input.gif -r 15 output.mp4

大多数 GIF 只有 10-20 帧/秒。强行提高帧率会让 FFmpeg 复制重复帧,MP4 编码器会分配更多关键帧,体积反而增加 2-3 倍。

6. 上传非动画的静态 GIF

错误
上传一张只有一帧的静态图片(.gif 后缀但无动画)
修复
先确认 GIF 帧数:ffprobe -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames input.gif

单帧 GIF 转 MP4 不会节省空间(MP4 头开销约 6KB,比原 GIF 还大)。工具应提示「检测到静态图像,建议直接使用 JPEG」。

7. 输入文件包含非法字符路径

错误
上传文件名为「动画 (1).gif」或「测试_中文.gif」
修复
重命名为纯英文+数字:animation_v1.gif

浏览器 File API 对中文/空格/括号的编码在不同系统不一致,FFmpeg WASM 读取时可能找不到文件或解析失败。

8. 期望无损压缩但选择低质量参数

错误
使用默认 CRF=23 或 -b:v 500k 转换
修复
需要无损时用 -crf 0(无损模式),或 -preset veryslow -crf 18(视觉无损)

GIF 转 MP4 本质是有损压缩。默认 CRF=23 会丢弃高频细节(如文字边缘、渐变)。若需保留原始画质,必须手动调低 CRF 值。

工作原理

公式推导 · 流程图解 · 依据出处

核心公式

V_mp4 = V_gif × (1 - R_compression)

变量说明

  • V_mp4 — 转换后 MP4 文件体积(KB)
  • V_gif — 原始 GIF 文件体积(KB)
  • R_compression — 压缩率(0~1,取决于帧间冗余)

示例

一个 5 秒动画 GIF,原始体积 2.5 MB(2560 KB),帧间冗余高(R_compression ≈ 0.85)。代入公式:V_mp4 = 2560 × (1 - 0.85) = 2560 × 0.15 = 384 KB。实际输出约 380~400 KB,体积缩减约 85%。

适用范围

适用于色彩简单、帧间变化小的 GIF(如图标、简单动画)。对高帧率、全帧变化的 GIF(如实拍视频转 GIF),压缩率 R_compression 可能降至 0.3~0.5,体积缩减效果减弱。

原理图

上传 GIF选择或拖入文件解码帧序列提取每帧图像FFmpeg 编码H.264 压缩输出 MP4体积减小 60%-80%关键特性• 浏览器内完成• 无需上传服务器
用户输入 本地处理(浏览器内) 输出结果 辅助说明

开发者集成

3 种主流语言 · 复制即用

import subprocess
import os

# 使用 ffmpeg-python 封装库(pip install ffmpeg-python)
import ffmpeg

input_gif = "animation.gif"
output_mp4 = "output.mp4"

# 检查输入文件是否存在
if not os.path.exists(input_gif):
    raise FileNotFoundError(f"输入文件 {input_gif} 不存在")

# GIF 转 MP4:调色板优化减小体积
# 先用 ffmpeg.probe 获取 GIF 信息
probe = ffmpeg.probe(input_gif)
width = probe['streams'][0]['width']
height = probe['streams'][0]['height']
fps = eval(probe['streams'][0].get('r_frame_rate', '10/1'))

# 生成调色板(减少颜色数量,显著减小体积)
(
    ffmpeg
    .input(input_gif)
    .filter('palettegen', stats_mode='diff')
    .output('palette.png')
    .overwrite_output()
    .run(quiet=True)
)

# 使用调色板编码 MP4
(
    ffmpeg
    .input(input_gif)
    .input('palette.png')
    .filter('paletteuse', dither='bayer')
    .output(
        output_mp4,
        vcodec='libx264',
        pix_fmt='yuv420p',
        r=fps,
        crf=23,          # 质量参数(18-28,越小质量越好体积越大)
        preset='medium'  # 编码速度/体积权衡
    )
    .overwrite_output()
    .run(quiet=True)
)

# 清理临时文件
os.remove('palette.png')

print(f"转换完成:{input_gif} → {output_mp4}")
print(f"原始大小:{os.path.getsize(input_gif)/1024:.1f} KB")
print(f"输出大小:{os.path.getsize(output_mp4)/1024:.1f} KB")
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
)

func main() {
	inputGIF := "animation.gif"
	outputMP4 := "output.mp4"

	// 检查输入文件
	if _, err := os.Stat(inputGIF); os.IsNotExist(err) {
		panic(fmt.Sprintf("输入文件 %s 不存在", inputGIF))
	}

	// 获取原始文件大小
	inputInfo, _ := os.Stat(inputGIF)
	fmt.Printf("原始大小: %.1f KB\n", float64(inputInfo.Size())/1024)

	// 第一步:生成调色板(减少颜色数,减小体积)
	paletteCmd := exec.Command("ffmpeg",
		"-i", inputGIF,
		"-vf", "palettegen=stats_mode=diff",
		"-y",
		"palette.png",
	)
	if err := paletteCmd.Run(); err != nil {
		panic(fmt.Sprintf("调色板生成失败: %v", err))
	}

	// 第二步:使用调色板编码 MP4
	encodeCmd := exec.Command("ffmpeg",
		"-i", inputGIF,
		"-i", "palette.png",
		"-lavfi", "paletteuse=dither=bayer",
		"-vcodec", "libx264",
		"-pix_fmt", "yuv420p",
		"-crf", "23",
		"-preset", "medium",
		"-y",
		outputMP4,
	)
	if err := encodeCmd.Run(); err != nil {
		panic(fmt.Sprintf("编码失败: %v", err))
	}

	// 清理临时文件
	os.Remove("palette.png")

	// 输出结果
	outputInfo, _ := os.Stat(outputMP4)
	fmt.Printf("输出大小: %.1f KB\n", float64(outputInfo.Size())/1024)
	fmt.Printf("转换完成: %s → %s\n", filepath.Base(inputGIF), filepath.Base(outputMP4))
}
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

const inputGIF = 'animation.gif';
const outputMP4 = 'output.mp4';

// 检查输入文件
if (!fs.existsSync(inputGIF)) {
  throw new Error(`输入文件 ${inputGIF} 不存在`);
}

// 获取原始文件大小
const inputSize = fs.statSync(inputGIF).size;
console.log(`原始大小: ${(inputSize / 1024).toFixed(1)} KB`);

// 执行 ffmpeg 命令
function runFFmpeg(args) {
  execSync(`ffmpeg ${args.join(' ')}`, { stdio: 'pipe' });
}

// 第一步:生成调色板(减少颜色数,显著减小体积)
runFFmpeg([
  '-i', inputGIF,
  '-vf', 'palettegen=stats_mode=diff',
  '-y',
  'palette.png'
]);

// 第二步:使用调色板编码 MP4
runFFmpeg([
  '-i', inputGIF,
  '-i', 'palette.png',
  '-lavfi', 'paletteuse=dither=bayer',
  '-vcodec', 'libx264',
  '-pix_fmt', 'yuv420p',
  '-crf', '23',
  '-preset', 'medium',
  '-y',
  outputMP4
]);

// 清理临时文件
fs.unlinkSync('palette.png');

// 输出结果
const outputSize = fs.statSync(outputMP4).size;
console.log(`输出大小: ${(outputSize / 1024).toFixed(1)} KB`);
console.log(`转换完成: ${path.basename(inputGIF)} → ${path.basename(outputMP4)}`);

常见问题

9 个高频疑问

怎么把一张 GIF 转换成 MP4 视频?具体操作步骤是什么?
进入工具页面后,点击上传区域选择或拖拽 GIF 文件(单文件,最大 100MB)。上传后系统会自动开始转换,进度条走完即可看到 MP4 预览和下载按钮。整个转换在浏览器本地完成(用 FFmpeg.wasm 处理),文件不上传服务器,断网也能用。如果 GIF 较大(>50MB),建议关闭其他标签页以加快处理速度。
为什么转换后 MP4 文件比原来的 GIF 还大?是不是出 bug 了?
不是 bug。GIF 压缩效率很低,尤其颜色丰富的动图(比如游戏录屏、表情包)用 LZW 压缩后体积可能比 MP4 大。但本工具默认用 H.264 编码,码率设为 2Mbps,对大部分 GIF 能实现 5-10 倍压缩。如果原始 GIF 本身很小(<500KB)且帧数少,MP4 文件头开销反而会让体积略增。可以尝试在输出设置中降低分辨率(如 480p)或帧率(如 15fps)来进一步压缩。
转换后 MP4 画面模糊或者颜色不对,怎么解决?
模糊通常是因为 GIF 分辨率低,放大后像素化。本工具默认保持原分辨率,不会强行拉伸。建议上传前确认 GIF 分辨率 ≥ 480p;如果原图就是 200×200 像素,MP4 不会变清晰。颜色不对(偏绿/偏紫)是因为 FFmpeg 在处理某些老 GIF(非标准色板)时颜色空间转换有 bug。可以试试:1) 用 Photoshop 先重存为「标准网络 GIF」;2) 在输出设置勾选「强制 RGB 色彩空间」。如果仍不行,把 GIF 截图发到反馈邮箱,我们会针对性修。
支持把多张 GIF 合并成一个 MP4 吗?或者提取视频中的某一段?
本工具只做「单 GIF → 单 MP4」的格式转换,不支持多文件合并或视频剪辑。如果需要合并多个动图,可以先用 GIF 拼接工具(如 GIF Brewery)合成一个 GIF 再上传。提取视频片段也不支持,建议用剪映或 FFmpeg 命令行:`ffmpeg -i input.mp4 -ss 00:00:10 -t 5 -c copy output.mp4`。
转换后的 MP4 能用于微信/抖音/小红书等平台吗?有尺寸限制吗?
可以。MP4 是 H.264 编码、AAC 音频(静音),兼容主流平台。但各平台有上传限制:微信视频号最大 1GB/15 分钟;抖音最大 4GB/60 分钟;小红书最大 500MB/15 分钟。本工具默认输出分辨率与原 GIF 一致,如果原图是 1920×1080,MP4 也是 1080p,不超限。动图帧率保留原帧率(通常 10-30fps),超过 30fps 的平台会自动降帧。
GIF 里带透明背景,转成 MP4 后背景变成黑色了,能保留透明吗?
不能。MP4 标准不支持 Alpha 通道(透明背景),FFmpeg 会将透明区域自动填充为黑色。这是视频编码格式本身的限制,不是工具 bug。如果需要透明背景,建议改用 WebM 格式(支持 Alpha)或 APNG(支持透明动图)。本工具后续版本可能会增加 WebM 输出选项。作为替代方案,可以先用 GIF 编辑软件把透明区域替换为纯色背景(如绿色/白色)再转换。
工具说在线免费,但转换到一半卡住了怎么办?
卡住通常是因为浏览器内存不足(FFmpeg.wasm 处理大文件时很吃内存)。建议:1) 先确认 GIF 文件大小,>100MB 可能超限;2) 关闭其他占用内存的标签页(尤其视频网站);3) 用 Chrome 或 Edge 最新版,避免 Safari/Firefox(WASM 性能差);4) 如果进度条超过 2 分钟不动,刷新页面重试。仍然不行的话,把 GIF 压缩到 <20MB 再试。工具不保存任何临时文件,刷新不会泄漏数据。
这个工具和那些在线 GIF 转视频网站有什么区别?为什么选这个?
主要区别在隐私和速度。大多数在线网站需要把 GIF 上传到他们的服务器处理,文件会被存储甚至用于训练 AI 模型。本工具所有转换在浏览器本地完成(用 FFmpeg.wasm),文件不离开你的电脑,适合处理包含敏感画面的动图(如产品演示、内部流程截图)。速度方面,本地处理没有排队和下载耗时,100KB 小图 1-2 秒出结果;但大文件(>50MB)受限于浏览器性能,可能比服务器端慢。
能批量转换多个 GIF 成 MP4 吗?比如一次选 10 个文件?
目前不支持批量上传。每次只能选一个 GIF 文件进行转换。如果需要批量处理,可以:1) 手动逐个上传(工具会保留上一次的设置参数);2) 用桌面端 FFmpeg 命令行批量处理:`for f in *.gif; do ffmpeg -i "$f" -c libx264 -pix_fmt yuv420p "${f%.gif}.mp4"; done`。批量功能已列入开发计划,关注工具站公告即可。
选择 打开 +新窗口 esc关闭