합리적인 품질로 ffmpeg를 사용하여 비디오를 GIF로 변환하려면 어떻게해야합니까?


310

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%

감사.


1
APNG가 일인 경우 사람들이 GIF로 팔레트 작업을 수행하는 방법이 재미 있습니다.
Константин Ван

답변:


447

ffmpeg

ffmpeg에서 GIF 출력
183k

ffmpeg고품질 GIF를 출력 할 수 있습니다. : 항상 최신 버전 사용 권장 다운로드를 하거나 컴파일 .

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
  • 이 예제는 -ss 30입력 의 처음 30 초 ( )를 건너 뛰고 3 초 출력 ( -t 3)을 만듭니다.
  • fps 필터는 프레임 속도를 설정합니다.
  • 스케일 필터는 출력을 320 픽셀 너비로 조정하고 가로 세로 비율을 유지하면서 높이를 자동으로 결정합니다.
  • palettegenpaletteuse 필터는 입력에서 생성 된 사용자 정의 팔레트를 생성하고 사용합니다.
  • split 필터는 모든 것을 하나의 명령으로 수행 할 수있게합니다.
  • -loop출력 옵션으로 제어 루핑 . 값 0은 무한 반복입니다.

더 많은 예제와 옵션 은 FFmpeg가 포함 된 고품질 GIF를 참조하십시오 .


Imagemagick convert예제

ffmpeg에서 GIF 출력
227k

또 다른 명령 줄 방법은 ImageMagick에서 파이프로 또는 파이프에서 파이프하는 ffmpeg것 입니다.convertmagick

 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

프레임 속도 설정

fps필터의 in ffmpeg-delayin을 조합하여 프레임 속도를 설정하십시오 convert. convertfps가 보존되지 않은 이미지 스트림을 가져 오기 때문에 복잡해질 수 있습니다 . 둘째, -delay의 값 convert 하지 초당 프레임 (초당 100 틱이있다). 예를 들어 fps=12.5= 100 / 12.5 = 8 = -delay 8입니다.

convert-delay값을 정수로 반올림 하므로 8.4의 결과 8과 8.5의 결과는 9입니다. 이는 모든 프레임에서 균일 한 지연을 설정할 때 일부 프레임 속도 만 지원됨을 의미합니다 (프레임 당 특정 지연을 설정할 수 있지만 그 이상임) 이 답변).

-delay출력 옵션으로 사용되는 경우 무시되는 것처럼 보이므로 -예제에 표시된대로 이전에 사용해야 합니다.

마지막으로, 브라우저 및 이미지 뷰어는 최소 지연을 구현할 -delay수 있으므로 어쨌든 무시 될 수 있습니다.

미국 어류 및 야생 생물 서비스 국가 보존 교육 센터의 비디오 제공.


4
예제 결과를 추가했습니다 (단지 여전히 프레임). 여기서 첫 번째 파일은 4.1MB이고 두 번째 파일은 약 8MB입니다.
slhck

2
@LordNeckbeard, 당신은 굉장합니다! 많은 감사를위한-vf scale=320:-1,format=rgb8,format=rgb24
카밀 Hismatullin

6
그건 그렇고, convertPNG 프레임에서 변환 명령은 내가 사용하여 결국 convert -delay 5 -loop 0 -dither None -colors 80 "frames/ffout*.png" -fuzz "40%" -layers OptimizeFrame "output.gif"전체 파일 크기가 약간 줄어 듭니다
Wilf

2
좋아, 내가 사용 scale=0:-1했으므로 스케일을로 설정 0하면 비디오에서 스케일을 가져옵니다.
Mousa Alfhaily

2
이 Q & A는 100 년 후에 모든 커뮤니케이션이 밈을 통해 이루어질 것이기 때문에 한 Tome으로 영구적으로 인코딩되어야합니다. 이 게시물의 활동만으로도 그렇게 생각합니다.
Jonathan Neufeld

87

중간 이미지 파일을 피하려면 중간 파일이 필요하지 않도록 LordNeckBeard에서 제공하는 명령을 ffmpegImageMagick 간에 파이프 할 수 있습니다 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포맷이 PNG로되면 어떤 이유로 (PPM로 출력 형식을 지정하거나 convert파이프에서 모든 이미지를 판독하지 않거나는 FFmpeg는 않는다 모두 출력하지는 않습니다). -두 명령을위한 파이프는 각각 출력과 입력에 사용되도록 지정.

파일을 저장하지 않고 결과를 최적화하기 위해 출력을 convert두 번째 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:-지시 convertGIF 형식의 데이터로서 파이프의 출력과 -layers Optimize상기 제 지시 convert수행 optimize-frameoptimize-transparancy방법 (참조 ImageMagick의 애니메이션 최적화 입문 ). 의 출력이 -layers Optimize항상 작은 파일 크기를 제공하지는 않을 수 있으므로 먼저 최적화하지 않고 gif로 변환을 시도 할 수 있습니다.

이 전체 과정에서 모든 것이 메모리에 있으므로 이미지가 상당히 큰 경우 충분한 메모리가 필요할 수 있습니다.


1
명령 세트도 함께 작동avconv
라파엘

마지막 두 변환 명령을 병합해야합니다.convert -delay 5 -loop 0 -layers Optimize - output.gif
Clément

gif가 소스 비디오 속도의 2 배 속도로 실행되고 있습니까?
Titan

@Titan은 첫 번째 명령에서 -r 10이고 두 번째 명령에서 -delay 5라고 생각합니다. 나는 또한 지연을 10으로 변경했으며 지금은 정상적으로 재생되는 것 같습니다.
Steven Huang

2
splitffmpeg 에서 필터를 사용하여 중간 이미지 파일을 피할 수도 있습니다 . 아무것도 배관 할 필요가 없습니다 :ffmpeg -ss 30 -t 3 -i "input.flv fps=10,scale=320:-1:flags=lanczos,split[x][z];[z]palettegen[y];[x][y]paletteuse" output.gif
Ajedi32

37

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


18

출력 해상도와 프레임 속도를 매개 변수화하는 자체 버전의 스크립트를 만들었습니다.

실행 ./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가 설치되었으며 스크립트는 다른 파일과 동일한 폴더에 있습니다.


3
대본 감사합니다. 방금 테스트했으며 훌륭하게 작동합니다!
orschiro

15

@Stephane의 답변은 매우 좋습니다. 그러나 Buffer queue overflow, dropping.일부 비디오 와 같은 경고가 표시 되고 생성 된 gif프레임이 떨어졌습니다.

fifo필터를 Buffer queue overflow사용할 때 피하기 위해 필터 가있는 더 나은 버전이 paletteuse있습니다. split중간 팔레트 PNG 파일의 생성을 피하기 위해 필터를 사용 합니다.

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

올바르게 이해하면 입력을 o1과 o2로 나누고 o2를 o3으로 복사합니다. 그렇다면 왜 o3가 필요합니까? 왜 o2를 직접 사용하지 않습니까?
Chloe

1
@Chloe 와 fifo사이 의 필터 작동을 보셨습니까 ? 경고 를 피하기 위해 . o2o3Buffer queue overflow
alijandro

+1 이것은 나에게 정말 효과적이며 참조 된 문제를 해결했습니다.
Iain Collins

나는이 솔루션을 절대적으로 좋아합니다. 명성!
Leonid Usov

10

스크립트를 작성하고 테스트하고 작동했습니다.

용법:

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

펀치가있다 :)

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를위한 뛰어난 ScreenCapturing 도구입니다. :)

많은 감사합니다 Michael Kohaupt :) Rock steady.

일부 파일 크기 통계 :

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

투시 여기에 결과를.


10

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필터 덕분에 가능합니다 .


10

리눅스 / 유닉스 / macOS

다음 @LordNeckbeard 방식 으로 ffmpeg명령하는 것은, 당신에 추가 할 수있는 다음과 같은 유용한 배쉬 기능을 찾아주십시오 ~/.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_profilevideo2gif명령 이 있어야합니다 .

사용법 예 :

video2gif input.flv

또는:

video2gif input.flv 320 10

초당 10 프레임으로 320 너비로 조정하십시오.

다른 비디오 형식 (예 : mp4)을 지정할 수도 있습니다.


맥 OS

비디오 파일에서 GIF를 만들 수있는 GIF Brewery 앱을 사용해 볼 수 있습니다.


또는 온라인으로 무료 변환을 수행하는 여러 웹 사이트가 있습니다.


스크립트가 png 파일이없고 gif 출력이 없다는 오류가 발생하지만 .mp4 입력 파일은 변경되지 않습니다
lacostenycoder

7

선택한 답변은 소스 비디오의 크기를 조정하고 생성 된 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를 원할 때 유용했습니다.


6

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


2
난 당신이 여기에 두 가지 일을 한 것을 볼 수 : (1) 윈도우 (.BAT) 명령을 스크립트로 명령을 작성하고, (2) 필터의 다른 조합을 (다른 답변 중 어느 것도 사용하지 않습니다 제공 fps=10scale=-1:-1).  Sun의 답변은 이미 배치 파일을 제공했으며 그 파일 (예 : pje의 답변복음주의 자의 답변 )은 필터 목록을 변수 ( 한 번 )에 할당한다는 이점이 있습니다 ... (계속)
Scott

1
(계속)… 따라서 배치 파일처럼 목록을 두 번 철자 할 필요는 없습니다. (이것은 사용자가 목록 중 하나를 변경하기 위해 스크립트를 편집하면 다른 목록은 변경하지 않으면 문제가 발생할 위험이 있다고 가정합니다.) 필터 선택 ( fps=10,scale=-1:-1) 을 적어도 설명 할 수 있습니까? ( 명령의 일부에 대한 설명은 주목할만한 답변 을 참조하십시오 .)
Scott

1
@Scott 당신이 맞다고 말 했으므로 여기에 새로운 유용한 스크립트를 작성하십시오 : github.com/NabiKAZ/video2gif
Nabi KAZ

4

아래는 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 : 샘플 추출

하나의 입력 변수 만 사용하고 출력 이름에 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

비디오 파일을 GIF로 변환하기 위해 Windows 7/10 "오른쪽 클릭"컨텍스트 메뉴 항목을 추가하는 방법

다른 답변 중 일부는 내가 사용한 video2gif 스크립트를 언급했습니다 . 그러나 모든 스크립트를 사용할 수 있습니다.

상황에 맞는 메뉴 옵션을 만들려면 레지스트리를 편집해야합니다. admin privs를 실행하여 powershell 명령 프롬프트를 엽니 다. 다음 명령을 실행하십시오.

$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"옵션이 나타납니다!

btw ffmpeg를 설치 C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\하고 video2gif.bat바로 옆의 bin 디렉토리에 스크립트를 넣었습니다 ffmpeg.exe. 나는 또한 C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin내 창문에 추가 PATH했지만 당신이 필요하다고 생각하지 않습니다.

스크립트에 추가 명령 행 플래그 / 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 키를 누르면 기본값을 빠르게 얻을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.