web-dev-qa-db-ja.com

適切な品質のffmpegを使用してビデオをGIFに変換する方法を教えてください。

私はffmpegでFLV映画を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ファイルは非常に低品質です。

どのように変換gifの品質を向上させることができますか?

コマンドの出力:

ffmpeg -i input.flv -ss 00:00:00.000 -pix_fmt rgb24 -r 10 -s 320x240 -t 00:00:10.000  output.gif
ffmpeg version 0.8.5-6:0.8.5-0ubuntu0.12.10.1, Copyright (c) 2000-2012 the Libav developers
  built on Jan 24 2013 14:52:53 with gcc 4.7.2
*** THIS PROGRAM IS DEPRECATED ***
This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.flv':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2013-02-14 04:00:07
  Duration: 00:00:18.85, start: 0.000000, bitrate: 3098 kb/s
    Stream #0.0(und): Video: h264 (High), yuv420p, 1280x720, 2905 kb/s, 25 fps, 25 tbr, 50 tbn, 50 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 192 kb/s
    Metadata:
      creation_time   : 2013-02-14 04:00:07
[buffer @ 0x92a8ea0] w:1280 h:720 pixfmt:yuv420p
[scale @ 0x9215100] w:1280 h:720 fmt:yuv420p -> w:320 h:240 fmt:rgb24 flags:0x4
Output #0, gif, to 'output.gif':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2013-02-14 04:00:07
    encoder         : Lavf53.21.1
    Stream #0.0(und): Video: rawvideo, rgb24, 320x240, q=2-31, 200 kb/s, 90k tbn, 10 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
Stream mapping:
  Stream #0.0 -> #0.0
Press ctrl-c to stop encoding
frame=  101 fps= 32 q=0.0 Lsize=    8686kB time=10.10 bitrate=7045.0kbits/s dup=0 drop=149    
video:22725kB audio:0kB global headers:0kB muxing overhead -61.778676%

ありがとう。

292

ffmpegは高品質のGIFを出力できるようになりました。古いビルドを使っているなら、 最近の静的ビルドをダウンロードするffmpeg をコンパイルすることを検討してください。

ffmpegの例

gif with ffmpeg
203k

この例では、入力の最初の30秒をスキップして3秒の出力を作成します。それは幅320ピクセルになるように出力を拡大縮小し、アスペクト比を維持しながら自動的に高さを決定します。 palettegen および paletteuse フィルタは、ソースから生成されたカスタムパレットを生成して使用します。

  1. パレットを生成する:

    ffmpeg -y -ss 30 -t 3 -i input.flv \
    -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
    
  2. パレットを使用してGIFを出力します。

    ffmpeg -ss 30 -t 3 -i input.flv -i palette.png -filter_complex \
    "fps=10,scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif
    

もっと多くの例とオプションについては FFmpeg を使った高品質GIFを見てください。


convertの例

別のコマンドラインメソッドは、ffmpegを使用してムービーをフレームにエクスポートしてから、ImageMagick(またはGraphicsMagick)のconvertを使用してGIFを作成することです。

ffmpeg and convert
246k

  1. フレームをエクスポートする:

     mkdir frames
     ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
    
  2. それから、アニメーションGIFを作成するためにconvert(またはGraphicsMagickが好きならgm convert)を使ってください:

     convert -loop 0 frames/ffout*.png output.gif
    

convertを使用すると、必要に応じて-delayを使用してフレーム間の遅延を制御できます。

422
llogan

中間画像ファイルを使用したくない場合は、LordNeckBeardが提供するコマンドをffmpegとImageMagickのconvertの間に配置して、中間ファイルを必要としないようにすることができます。

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

-f image2pipeは、ffmpegにビデオを分割してパイプライン処理に適したものにするよう指示し、-vcodec ppmは出力フォーマットをppmに指定します(フォーマットがpngの場合、何らかの理由でconvertはパイプからすべてのイメージを読み取らない、またはffmpegはそれらすべてを出力しません。両方のコマンドの-は、パイプがそれぞれ出力と入力に使用されることを指定します。

ファイルを保存せずに結果を最適化するために、convertからの出力を2番目のconvertコマンドに渡すことができます。

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

gif:-convertにその出力をgifフォーマットのデータとしてパイプするように伝え、-layers Optimizeは2番目のconvertoptimize-frameおよびoptimize-transparancyメソッドを実行するように伝えます(ImageMagick Animation Optimizationの紹介 を参照)。 -layers Optimizeからの出力が常に小さいファイルサイズを提供するわけではないので、最初に最適化せずにgifに変換してみることをお勧めします。

このプロセス全体を通して、すべてがメモリ内にあるため、イメージが非常に大きい場合は十分なメモリが必要になる可能性があります。

85
notedible

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

35
pje

私はスクリプトの私自身のバージョンを作りました。それは同様に出力解像度とフレームレートをパラメータ化します。

./gifenc.sh input.mov output.gif 720 10を実行すると、あなたが渡した映画から幅720p、幅10fpsのGIFが出力されます。ファイルに対してchmod +x gifenc.shを実行する必要があるかもしれません。

#!/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"

あなたは私の Github の詳細を読むことができます

仮定:ffmpegがインストールされていて、スクリプトが他のファイルと同じフォルダーにある。

17
thevangelist

@ステファンからの答えはとても良いです。しかし、ビデオによってはBuffer queue overflow, dropping.のような警告が表示され、生成されたgifではフレームがドロップされます。

これはfifoフィルタを使うときにBuffer queue overflowを避けるためのpaletteuseフィルタのより良いバージョンです。中間パレットPNGファイルの作成を回避するためにsplitフィルタを使用することによって。

ffmpeg -i input.mp4 -filter_complex 'fps=10,scale=320:-1:flags=lanczos,split [o1] [o2];[o1] palettegen [p]; [o2] fifo [o3];[o3] [p] paletteuse' out.gif
13
alijandro

スクリプトを作成し、テストして動作します。

使用法:

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

HAUN 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

ところで: vokoscreen はLinux用の素晴らしいScreenCapturingツールです:)

ありがとうございますMichael Kohaupt :)しっかりとロック。

いくつかのファイルサイズ統計:

5.3M = vokoscreen-2015-04-28_15-43-17.avi - > vokoscreen-2015-05-28_12-41-56.avi.gif = 1013K

ここで の結果をご覧ください。

10
canoodle

Linux/Unix/macOS

ffmpegコマンドで @ LordNeckbeardアプローチ に従って、~/.bash_profileファイルに追加できる次の便利なBash関数を見つけてください。

# 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

毎秒10フレームで320幅に拡大縮小します。

別のビデオフォーマット(mp4など)を指定することもできます。


マックOS

あなたは ビデオファイルからGIFを作成できるGIF Brewery アプリを試すことができます。


代わりに無料でオンラインで変換をしているいくつかのウェブサイトがあります。

9
kenorb

ffmpeg with palette メソッド は、中間の.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 フィルタのおかげで可能です。

8
Stephane

選択された答えは、あなたがソースビデオを拡大縮小して、生成されたgifのそのfpsを変更したいと仮定します。これを行う必要がない場合は、次のように動作します。

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が欲しいときにこれは役に立ちました。

7
Jet Blue

以下は、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

出典: FFmpegを使った高品質GIF:サンプルだけを抽出する

1つの入力変数だけを使用し、出力名に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
4
Sun

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

それから現在のディレクトリにmyvideo.gifがあります。
myvideo.gifが存在する場合、それを上書きするようにあなたから質問してください。

編集:

このバッチスクリプトを使用することをお勧めします。 https://github.com/NabiKAZ/video2gif

4
Nabi K.A.Z.

あなたのビデオファイルをGIFに変換するためのWindows 7/10「右クリック」コンテキストメニューエントリを追加する方法

他の答えのいくつかは私が使用した video2gif スクリプトを述べました。しかし、あなたはどんなスクリプトを使うこともできます。

コンテキストメニューオプションを作成するには、レジストリを編集する必要があります。 w/admin privsを実行して、powershellコマンドのPromptを開きます。これらのコマンドを実行して下さい:

$key = "Registry::HKEY_CLASSES_ROOT\`*\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"オプションが表示されます。

ところで私はffmpegをC:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\にインストールし、video2gif.batスクリプトをffmpeg.exeのすぐ隣のbinディレクトリに置きました。私は自分のウィンドウのPATHC:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\binを追加しましたが、あなたがそうする必要はないと思います。

スクリプトに追加のコマンドラインフラグ/ argsを提供できるオプションが必要な場合は、video2gif-Prompt.batという名前の新しいファイルを作成し、video2gif.batの代わりにそれをレジストリに参照させます。

@echo off
set /p inp=Enter extrta args, if desired:
C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin\video2gif.bat %* %inp%

あなたはまだすぐにデフォルト値を取得するためにenterを押すことができます。

2
chris