make-gif
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVideo GIF
视频转GIF
Convert a video clip to a high-quality GIF using the mandatory 2-pass palette workflow.
Single-pass GIF always produces banding and color artifacts. The palettegen → paletteuse pipeline analyzes the actual clip to build an optimal 256-color palette, then renders with it. Never skip this.
使用必选的两步调色板工作流将视频剪辑转换为高质量GIF。
单步生成的GIF总会出现色带和色彩失真问题。palettegen → paletteuse流程会分析实际剪辑内容来构建最优的256色调色板,再基于该调色板渲染GIF。切勿跳过这一步。
Process
操作流程
1. Gather parameters
1. 收集参数
Ask for any not already provided in the request:
- Start time — default
0 - Duration or end time — required; warn if >30s (file size grows rapidly)
- Width — default px; height auto-calculated to preserve aspect ratio
480 - FPS — default ; higher = smoother + larger file
15
If the user asks about aspect ratio or the source has unusual dimensions, probe first:
bash
ffprobe -v quiet -print_format json -show_streams "$INPUT" | \
python3 -c "import json,sys; s=[s for s in json.load(sys.stdin)['streams'] if s['codec_type']=='video'][0]; print(s['width'], 'x', s['height'])"询问请求中未提供的以下参数:
- 开始时间 —— 默认值为
0 - 时长或结束时间 —— 必填项;若超过30秒需发出警告(文件大小会快速增长)
- 宽度 —— 默认值为px;高度会自动计算以保持宽高比
480 - 帧率(FPS) —— 默认值为;帧率越高,画面越流畅,但文件体积越大
15
若用户询问宽高比,或源视频尺寸特殊,先执行以下命令探测:
bash
ffprobe -v quiet -print_format json -show_streams "$INPUT" | \
python3 -c "import json,sys; s=[s for s in json.load(sys.stdin)['streams'] if s['codec_type']=='video'][0]; print(s['width'], 'x', s['height'])"2. Build the 2-pass command
2. 构建两步执行命令
Pass 1 — generate optimized palette:
bash
ffmpeg -ss $START -t $DURATION -i "$INPUT" \
-vf "fps=$FPS,scale=$WIDTH:-1:flags=lanczos,palettegen=stats_mode=full" \
/tmp/palette_$$.png -yPass 2 — render GIF using palette:
bash
ffmpeg -ss $START -t $DURATION -i "$INPUT" -i /tmp/palette_$$.png \
-lavfi "fps=$FPS,scale=$WIDTH:-1:flags=lanczos [x]; [x][1:v] paletteuse=dither=bayer:bayer_scale=5" \
"$OUTPUT" -yUse (shell PID) in the palette temp path to avoid collisions with concurrent runs.
$$第一步——生成优化调色板:
bash
ffmpeg -ss $START -t $DURATION -i "$INPUT" \
-vf "fps=$FPS,scale=$WIDTH:-1:flags=lanczos,palettegen=stats_mode=full" \
/tmp/palette_$$.png -y第二步——使用调色板渲染GIF:
bash
ffmpeg -ss $START -t $DURATION -i "$INPUT" -i /tmp/palette_$$.png \
-lavfi "fps=$FPS,scale=$WIDTH:-1:flags=lanczos [x]; [x][1:v] paletteuse=dither=bayer:bayer_scale=5" \
"$OUTPUT" -y在调色板临时路径中使用(Shell进程ID),避免并发运行时发生冲突。
$$3. Confirm before running
3. 运行前确认
Show the full 2-pass command and estimated output path. Add a size warning if is large (rough heuristic: >20s at 15fps at 480px → likely >10MB).
duration × fps展示完整的两步执行命令和预估输出路径。若数值较大(大致判断标准:480px分辨率下15帧率超过20秒 → 文件体积可能超过10MB),需添加大小警告。
时长 × 帧率4. Run both passes, then clean up
4. 执行两步命令,然后清理临时文件
bash
rm -f /tmp/palette_$$.pngReport output path and file size.
bash
rm -f /tmp/palette_$$.png报告输出路径和文件大小。
Key Decisions
关键决策说明
- on palettegen analyzes the entire clip — not just the first frame — for better palette coverage across motion.
stats_mode=full - is the sweet spot for photographic content. Use
dither=bayer:bayer_scale=5for flat-color content (illustrations, slides, screen recordings with solid backgrounds).dither=none - placed before
-ssuses container-level fast seek. Apply to both passes for consistent start points and dramatically faster seeks on long source files.-i - on scale gives sharper downsampling than the default
flags=lanczos.bilinear - To control loop count, add to pass 2:
-loop $N= infinite,0= play once,1= play twice.2
- palettegen的会分析整个剪辑(而非仅第一帧),以便在动态画面中获得更好的调色板覆盖效果。
stats_mode=full - 是摄影类内容的最佳选择。对于纯色内容(插画、幻灯片、纯色背景的屏幕录制),使用
dither=bayer:bayer_scale=5。dither=none - 将放在
-ss之前会使用容器级快速定位。两步命令都应用该设置,可确保起始点一致,并大幅提升长源文件的定位速度。-i - scale的比默认的
flags=lanczos能提供更清晰的下采样效果。bilinear - 如需控制循环次数,在第二步命令中添加:
-loop $N=无限循环,0=播放一次,1=播放两次。2