2013-02-22 20:06:30 +0000 2013-02-22 20:06:30 +0000
335
335

如何使用ffmpeg将视频转换为GIF,并有合理的质量?

我正在用ffmpeg将一个视频转换为GIF文件:

ffmpeg -i input.flv -ss 00:00:00.000 -pix_fmt rgb24 -r 10 -s 320x240 -t 00:00:10.000 output.gif

,效果很好,但是输出的GIF文件质量很低。

答案 (12)

505
505
505
2013-02-22 21:31:46 +0000

ffmpeg

183k

ffmpegは高品質なGIFを出力することができます。始める前に、常に最新のバージョンを使用することをお勧めします。ダウンロード](https://ffmpeg.org/download.html)または[コンパイル](https://trac.ffmpeg.org/wiki/CompilationGuide).

ffmpeg -ss 30 -t 3 -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif
  • この例では、入力の最初の30秒(-ss 30)をスキップし、3秒の出力(-t 3)を作成します。この例では 1 秒あたり 10 フレームのレートを使用しています。
  • scale フィルタは出力を 320 ピクセル幅にリサイズし、アスペクト比を維持したまま自動的に高さを決定します。この例では lanczos スケーリングアルゴリズム を使用しています。
  • palettegen paletteuse フィルターは、入力から生成されたカスタムパレットを生成して使用します。これらのフィルタには多くのオプションがありますので、利用可能なすべてのオプションと値の一覧はリンク先を参照してください。また、下記の 高度なオプション の項も参照してください。
  • split フィルタはすべてを一つのコマンドで実行できるようにし、 パレットの一時的な PNG ファイルを作成する必要がありません。
  • -loop 出力オプションでループを制御することができますが、値がわかりにくいです。0 の値は無限ループ、-1 はループしない、1 は一度だけループする、つまり二度再生されるということです。つまり、値を 10 にすると GIF は 11 回再生されます。

高度なオプション

palettegen paletteuse フィルタには、多くのオプションが追加されています。最も重要なのは

  • stats_mode (palettegen) です。このフィルターはパレットの焦点を画像全体に合わせる (full がデフォルトです) か、 可動部分のみに合わせる (diff) か、 個々のフレームに合わせる (single) かのいずれかに強制することができます。たとえば、 個々のフレームごとにパレットを生成するには palettegen=stats_mode=single & paletteuse=new=1 を使用します。ディザリングアルゴリズムを選択します。主に3つのタイプがあります:決定論的(dither)、誤差拡散(デフォルトのbayerを含む他のすべてのタイプ)、そして何もしない。あなたの GIF は、特定のディザリングアルゴリズムを使った方がよく見えるかもしれませんし、ディザリングを全く使わない方がよく見えるかもしれません。

説明、画像の例、高度な使い方の詳細については、FFmpeg で高品質 GIF を参照してください。


ImageMagick sierra2_4a の例

227k

もう一つのコマンドライン方式は、ImageMagick から bayer から bayer_scale (または convert) へパイプすることです。

ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v pam -f image2pipe - | convert -delay 10 - -loop 0 -layers optimize output.gif

ffmpeg オプション:

  • convert fps scale フィルタを使用した filtergraph 。本例では lanczos scaling algorithm を使用しています。

  • magick PAM イメージエンコーダを選択します。この例では、PAM (Portable AnyMap) 画像フォーマットを出力していますが、これは透明度(アルファ)をサポートし、ffmpeg でサポートされているシンプルでロスレスな RGB フォーマットです。

  • -vf "fps=10,scale=320:-1:flags=lanczos" は image2pipe muxer を選択します。これは、パイプに出力する際にどの muxer を使用するかを伝える必要があるためです。詳しくは ImageMagickアニメーション最適化 を参照してください。出力が小さくなることを保証するものではありませんので、-c:v pamを使わずに試して結果を比較してみる価値はあります。

フレームレートの設定

convert fps フィルタと-f image2pipe ffmpeg を組み合わせてフレームレートを設定します。これは、convertが画像の生のストリームを取得するだけなので、fpsが保持されないため、ややこしくなることがあります。第二に、-delay-loop 0 の値は、毎秒のフレーム数ではなく、ticks(毎秒 100 回)の単位です。例えば、-layers optimize = 100/12.5 = 8 = -layers optimize とすると、

ffmpeg-delay の値を整数に丸めるので、8.4 は 8、8.5 は 9 となります。これは、全てのフレームで一様な遅延を設定する場合、一部のフレームレートのみがサポートされていることを意味します(フレームごとに特定の遅延を設定することもできますが、それはこの答えの範囲を超えています)。

最後に、ブラウザや画像ビューアは最小遅延を実装している場合がありますので、あなたのconvertはいずれにせよ無視される可能性があります。

ビデオ提供:U.S. Fish & Wildlife Service National Conservation Training Center

88
88
88
2014-03-18 09:47:53 +0000

如果你希望避免中间的图像文件,可以在ffmpeg和ImageMagick的convert之间管道化,这样就不需要中间文件了。

ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 5 -loop 0 - output.gif
ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 5 -loop 0 - gif:- | convert -layers Optimize - output.gif

-f image2pipe告诉ffmpeg将视频分割成图像,使其适合被管道输出,而-vcodec ppm则指定输出格式为PPM(由于某种原因,如果格式为png,要么convert没有从管道中读取所有的图像,要么ffmpeg没有将其全部输出)。这两条命令的-中的convert分别指定了输出和输入用一个管道,如果要优化结果而不保存文件,可以将convert的输出用管道输出到第二个gif:-命令中:

&001

&001

告诉convert将其输出为gif格式的数据进行管道输出,-layers Optimize告诉第二个convert执行optimize-frameoptimize-transparancy的方法(参见ImageMagick【动画优化介绍】(http://www.imagemagick.org/Usage/anim_opt/))。需要注意的是,`-layers Optimize`的输出不一定能提供更小的文件大小,所以你可以先尝试转换为GIF格式,而不做优化来确定。

请记住,在整个过程中,所有的东西都在内存中,所以如果图像相当大,你可能需要足够的内存。

38
38
38
2015-03-23 18:39:20 +0000

在ffmpeg 2.6中,我们可以做得更好:

palette="/tmp/palette.png"
filters="fps=15,scale=320:-1:flags=lanczos"

ffmpeg -i input.flv -vf "$filters,palettegen" -y $palette
ffmpeg -i input.flv -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y output.gif

HT

20
20
20
2017-10-05 12:04:32 +0000

由@Stephane 提供的答案很好。但是会得到一个类似于Buffer queue overflow, dropping.的警告,而且生成的gif会有一些掉帧的情况,

这里有一个比较好的版本,使用fifo滤镜的时候可以避免Buffer queue overflow。通过使用paletteuse滤镜,避免了中间调色板PNG文件的生成。

18
18
18
2015-07-12 09:35:07 +0000

运行./gifenc.sh input.mov output.gif 720 10会从你给的电影中输出720p宽10fps的GIF。

#!/bin/sh

palette="/tmp/palette.png"

filters="fps=$4,scale=$3:-1:flags=lanczos"

ffmpeg -v warning -i "$1" -vf "$filters,palettegen" -y "$palette"
ffmpeg -v warning -i "$1" -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y "$2"

&001

你可以在我的Github

假设:ffmpeg已经安装好了,脚本和其他文件在同一个文件夹里。

12
12
12
2017-09-30 15:23:29 +0000

ffmpeg与调色板方法可以在一个命令中运行,不需要中间的.png文件。

ffmpeg -y -ss 30 -t 3 -i input.flv -filter_complex \
"fps=10,scale=320:-1:flags=lanczos[x];[x]split[x1][x2]; \
[x1]palettegen[p];[x2][p]paletteuse" output.gif

这要归功于split过滤器。

11
11
11
2015-05-28 10:55:51 +0000

使用方法:

./avi2gif.sh ./vokoscreen-2015-05-28_12-41-56.avi

HAVE PHUN :)

vim avi2gif.sh

#!/bin/sh

INPUT=$1

# default settings, modify if you want.

START_AT_SECOND=0; # in seconds, if you want to skip the first 30 seconds put 30 here

LENGTH_OF_GIF_VIDEO=9999999; # in seconds, how long the gif animation should be

echo "Generate a palette:"
ffmpeg -y -ss $START_AT_SECOND -t $LENGTH_OF_GIF_VIDEO -i $INPUT -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png

echo "Output the GIF using the palette:"
ffmpeg -ss $START_AT_SECOND -t $LENGTH_OF_GIF_VIDEO -i $INPUT -i palette.png -filter_complex "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" $INPUT.gif

btw: vokoscreen是一个非常好的Linux屏幕捕捉工具 :)

感谢 Michael Kohaupt :) 5.3M = vokoscreen-2015-04-2815-43-17.avi -> vokoscreen-2015-05-2812-41-56.avi.gif = 1013K

10
10
10
2016-12-09 17:34:16 +0000

Linux/Unix/macOS

按照@LordNeckbeard的方法使用ffmpeg命令,请找到以下有用的Bash函数,可以添加到你的~/.bash_profile文件中:

# Convert video to gif file.
# Usage: video2gif video_file (scale) (fps)
video2gif() {
  ffmpeg -y -i "${1}" -vf fps=${3:-10},scale=${2:-320}:-1:flags=lanczos,palettegen "${1}.png"
  ffmpeg -i "${1}" -i "${1}.png" -filter_complex "fps=${3:-10},scale=${2:-320}:-1:flags=lanczos[x];[x][1:v]paletteuse" "${1}".gif
  rm "${1}.png"
}

一旦加载了这个函数(手动或从. ~/.bash_profile中加载),你应该会有新的video2gif命令。

示例用法:

video2gif input.flv

或:

video2gif input.flv 320 10

缩放到320宽度,每秒10帧。

你也可以指定不同的视频格式(如mp4)。


OS macOS

你可以尝试GIF Brewery应用程序,它可以从视频文件中创建GIF。

9
9
9
2017-11-14 23:01:37 +0000

选择的答案是假设你想在制作的GIF中缩放源视频并改变它的帧数。如果你不需要这样做,下面的方法就可以:

src="input.flv"
dest="output.gif"
palette="/tmp/palette.png"

ffmpeg -i $src -vf palettegen -y $palette
ffmpeg -i $src -i $palette -lavfi paletteuse -y $dest

这在我想要一个忠实地重现源视频的GIF时派上了用场。

6
6
6
2017-04-21 15:36:34 +0000

对于windows用户: 在windows目录下创建video2gif.bat文件,内容如下:

@echo off
set arg1=%1
set arg2=%arg1:~0,-4%
ffmpeg -y -i %arg1% -vf fps=10,scale=-1:-1:flags=lanczos,palettegen %TEMP%\palette.png
ffmpeg -i %arg1% -i %TEMP%\palette.png -filter_complex "fps=10,scale=-1:-1:flags=lanczos[x];[x][1:v]paletteuse" %arg2%.gif
del /f %TEMP%\palette.png
video2gif myvideo.mp4

,然后在任何地方都可以使用,就像这样的例子:

&001

,那么你就在当前目录下有了myvideo.gif

EDIT:*

我建议使用这个批处理脚本 https://github.com/NabiKAZ/video2gif

4
4
4
2016-06-23 22:31:26 +0000

以下是Windows用户的批处理文件:

gifenc.bat:

set start_time=0
set duration=60
set palette="c:\temp\palette.png"
set filters="fps=15,scale=-1:-1:flags=lanczos"
ffmpeg -v warning -ss %start_time% -t %duration% -i %1 -vf "%filters%,palettegen" -y %palette%
ffmpeg -v warning -ss %start_time% -t %duration% -i %1 -i %palette% -lavfi "%filters% [x]; [x][1:v] paletteuse" -y %2

源。高质量的GIF与FFmpeg:只提取一个样本](http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html)

如果你只想使用一个输入变量,而输出的名字只有GIF(发音为JIF)扩展名,那么用这个来代替:

set start_time=0
set duration=60
set palette="c:\temp\palette.png"
set filters="fps=15,scale=-1:-1:flags=lanczos"
ffmpeg -v warning -ss %start_time% -t %duration% -i %1 -vf "%filters%,palettegen" -y %palette%
set var1=%1
set var2=%var1:~0,-4%
ffmpeg -v warning -ss %start_time% -t %duration% -i %1 -i %palette% -lavfi "%filters% [x]; [x][1:v] paletteuse" -y %var2%.gif
3
3
3
2018-04-15 23:48:54 +0000

如何添加一个windows 7/10 “右键点击 "上下文菜单条目,将视频文件转换为gif

其他一些回答中提到了video2gif脚本,我用的是这个脚本。

要创建上下文菜单选项,你需要编辑你的注册表。打开一个powershell命令提示符,用admin privs运行。执行这些命令:

$key = "Registry::HKEY_CLASSES_ROOT# 如何添加一个windows 7/10 "右键点击 "上下文菜单条目,将视频文件转换为gif 


其他一些回答中提到了[video2gif]&003脚本,我用的是这个脚本。


要创建上下文菜单选项,你需要编辑你的注册表。打开一个powershell命令提示符,用admin privs运行。执行这些命令:


*\shell\Run Video2Gif"
New-Item -Path $key"\Command" -Value "C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat `"%1`"" -Force

现在当你右键点击一个文件,你会有一个 "Run Video2Gif "选项!

btw我把ffmpeg安装到`C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static# 如何添加一个windows 7/10 "右键点击 "上下文菜单条目,将视频文件转换为gif

其他一些回答中提到了[video2gif]&003脚本,我用的是这个脚本。

要创建上下文菜单选项,你需要编辑你的注册表。打开一个powershell命令提示符,用admin privs运行。执行这些命令:

$key = "Registry::HKEY_CLASSES_ROOT# 如何添加一个windows 7/10 "右键点击 "上下文菜单条目,将视频文件转换为gif 


其他一些回答中提到了[video2gif]&003脚本,我用的是这个脚本。


要创建上下文菜单选项,你需要编辑你的注册表。打开一个powershell命令提示符,用admin privs运行。执行这些命令:


*\shell\Run Video2Gif"
New-Item -Path $key"\Command" -Value "C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat `"%1`"" -Force

现在当你右键点击一个文件,你会有一个 "Run Video2Gif "选项!

btw我把ffmpeg安装到,并把video2gif.bat脚本放在ffmpeg.exe旁边的bin dir里。我也把C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin添加到了我的windows PATH中,但我认为你不需要这样做。