Câu hỏi Làm cách nào để chuyển đổi video sang GIF bằng ffmpeg, với chất lượng hợp lý?


Tôi đang chuyển đổi .flv phim để .gif tập tin với ffmpeg.

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

Nó hoạt động rất tốt, nhưng tệp gif đầu ra có chất lượng rất thấp.

Bất kỳ ý tưởng làm thế nào tôi có thể cải thiện chất lượng của gif chuyển đổi?

Đầu ra của lệnh:

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%

Cảm ơn.


247
2018-02-22 20:06


gốc




Các câu trả lời:


ffmpeg bây giờ có thể xuất GIF chất lượng cao hơn. Nếu bạn đang sử dụng một phiên bản cũ hơn, hãy xem xét tải xuống một bản dựng tĩnh gần đây hoặc là biên dịch ffmpeg.

ffmpeg thí dụ

gif with ffmpeg
203k

Ví dụ này sẽ bỏ qua 30 giây đầu tiên của đầu vào và tạo ra 3 giây đầu ra. Nó sẽ mở rộng đầu ra rộng 320 pixel và tự động xác định chiều cao trong khi vẫn giữ nguyên tỉ lệ khung hình. Các palettegen và paletteuse bộ lọc sẽ tạo và sử dụng bảng màu tùy chỉnh được tạo từ nguồn của bạn.

  1. Tạo bảng màu:

    ffmpeg -y -ss 30 -t 3 -i input.flv \
    -vf fps=10,scale=320:-1:flags=lanczos,palettegen palette.png
    
  2. Xuất GIF bằng bảng màu:

    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
    

Xem GIF chất lượng cao với FFmpeg cho nhiều ví dụ và tùy chọn hơn.


convert thí dụ

Một phương pháp dòng lệnh khác là xuất phim sang khung bằng ffmpeg sau đó tạo GIF convert từ ImageMagick (hoặc GraphicsMagick).

ffmpeg and convert
246k

  1. Xuất khung:

     mkdir frames
     ffmpeg -i input -vf scale=320:-1:flags=lanczos,fps=10 frames/ffout%03d.png
    
  2. Sau đó sử dụng convert (hoặc là gm convert nếu bạn thích GraphicsMagick) để tạo GIF động:

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

Với convert bạn có thể kiểm soát độ trễ giữa các khung với -delay nếu muốn.


374
2018-02-22 21:31



Thêm một số kết quả ví dụ (chỉ còn khung hình). Ở đây, tệp đầu tiên là 4,1 MB, tệp thứ hai khoảng 8 MB. - slhck
@LordNeckbeard, bạn thật tuyệt vời! cảm ơn nhiều vì -vf scale=320:-1,format=rgb8,format=rgb24 - Kamil Hismatullin
Nhân tiện, cho convert lệnh để chuyển đổi từ các khung PNG mà tôi đã sử dụng convert -delay 5 -loop 0 -dither None -colors 80 "frames/ffout*.png" -fuzz "40%" -layers OptimizeFrame "output.gif", làm giảm kích thước tệp tổng thể khá nhiều - Wilf
Tôi nghĩ rằng convert lệnh nên sử dụng -delay 10 (0,1 giây giữa các khung hình) để khớp với -r 10 (Tốc độ khung hình 10 khung hình / giây) bạn đang cho ffmpeg. Khi tôi sử dụng -delay 5, Tôi thấy trò chơi gif ở tốc độ gấp đôi. - Jack O'Connor
Được rồi, tôi đã có nó, tôi đã sử dụng scale=0:-1, vì vậy khi bạn đặt tỷ lệ thành 0, nó sẽ lấy tỷ lệ từ video. - Mousa Alfhaily


Nếu bạn muốn tránh các tệp hình ảnh trung gian, các lệnh được cung cấp bởi LordNeckBeard có thể được nối giữa ffmpeg và ImageMagick's convert để không yêu cầu tệp trung gian:

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

Các -f image2pipe yêu cầu ffmpeg tách video thành hình ảnh và làm cho nó phù hợp để được rút ra, và -vcodec ppm chỉ định định dạng đầu ra là ppm (vì một số lý do nếu định dạng là png, hoặc convert không đọc tất cả các hình ảnh từ đường ống, hoặc ffmpeg không xuất ra tất cả). Các - cho cả hai lệnh xác định rằng một đường ống sẽ được sử dụng cho đầu ra và đầu vào tương ứng.

Để tối ưu hóa kết quả mà không lưu tệp, bạn có thể tạo đầu ra từ convert đến một giây convert chỉ huy:

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

Các gif:- nói convert để đầu ra của nó dưới dạng dữ liệu định dạng gif và -layers Optimize nói với người thứ hai convert để thực hiện optimize-frame và optimize-transparancy phương pháp (xem ImageMagick Giới thiệu về Tối ưu hóa hoạt ảnh). Lưu ý rằng đầu ra từ -layers Optimize có thể không phải lúc nào cũng cung cấp kích thước tệp nhỏ hơn, vì vậy bạn có thể thử chuyển đổi thành gif mà không tối ưu hóa trước để chắc chắn.

Hãy nhớ rằng trong toàn bộ quá trình này mọi thứ đều có trong bộ nhớ, do đó bạn có thể cần đủ bộ nhớ nếu hình ảnh khá lớn.


79
2018-03-18 09:47



Bộ lệnh này cũng hoạt động với avconv - raphael
Bạn nên hợp nhất hai lệnh chuyển đổi sau cùng: convert -delay 5 -loop 0 -layers Optimize - output.gif - Clément
Hình gif dường như đang chạy ở tốc độ 2x của video nguồn? - Titan
@Titan tin rằng đó là -r 10 trong lệnh đầu tiên và thứ 5 trong 5 giây. Tôi đã thay đổi độ trễ thành 10 và có vẻ như bây giờ chơi bình thường. - Steven Huang
Bạn cũng có thể tránh các tệp hình ảnh trung gian bằng cách sử dụng split lọc trong ffmpeg. Không cần phải làm gì cả: 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


Kể từ ffmpeg 2.6, chúng ta có thể làm tốt hơn nữa:

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 


29
2018-03-23 18:39





Tôi đã tạo phiên bản script của riêng mình, nó cũng tham số hóa độ phân giải đầu ra và tốc độ khung hình.

Đang chạy ./gifenc.sh input.mov output.gif 720 10 sẽ xuất ra hình ảnh GIF rộng 10pps từ phim bạn đã cung cấp. Bạn có thể cần phải làm chmod +x gifenc.sh cho tệp.

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

Bạn có thể đọc chi tiết trên Github

Giả định: ffmpeg được cài đặt, và tập lệnh nằm trong cùng thư mục với các tệp khác.


13
2017-07-12 09:35



Cảm ơn bạn rất nhiều cho kịch bản của bạn. Tôi chỉ thử nghiệm nó và nó hoạt động tuyệt vời! - orschiro


thực hiện một kịch bản, thử nghiệm và hoạt động.

sử dụng:

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

CÓ 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 là một công cụ ScreenCapturing EXCELLENT cho Linux :)

THANKS A LOT Michael Kohaupt :) Đá ổn định.

một số chỉ số kích thước tệp:

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

xem kết quả ở đây.


7
2018-05-28 10:55





Câu trả lời từ @Stephane rất tốt. Nhưng nó sẽ nhận được một cảnh báo như Buffer queue overflow, dropping. cho một số video và được tạo gif có một số khung bị giảm.

Đây là một phiên bản tốt hơn với fifo bộ lọc để tránh Buffer queue overflow khi đang sử dụng paletteuse bộ lọc. Bằng cách sử dụng split bộ lọc để tránh việc tạo tệp PNG bảng màu trung gian.

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

7
2017-10-05 12:04





Linux / Unix / macOS

Tiếp theo Cách tiếp cận @LordNeckbeard với ffmpeg lệnh, vui lòng tìm hàm Bash hữu ích sau đây có thể được thêm vào ~/bash_profile tập tin:

# 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"
}

Sau khi tệp được tải (. ~/.bash_profile), bạn nên có mới video2gif chỉ huy.

Sử dụng ví dụ:

video2gif input.flv

hoặc là:

video2gif input.flv 320 10

Chia tỷ lệ thành 320 chiều với 10 khung hình mỗi giây.

Bạn cũng có thể chỉ định định dạng video khác (chẳng hạn như mp4).


hệ điều hành Mac

Bạn co thể thử Nhà máy bia GIF ứng dụng có thể tạo GIF từ tệp video.


Ngoài ra, có một số trang web đang thực hiện chuyển đổi trực tuyến miễn phí.


6
2017-12-09 17:34



Tiếp tuyến / offtopic: Đối với bất cứ ai tự hỏi tại sao Cộng đồng đã chỉnh sửa điều này, đó là để HTTPSify liên kết trong dòng đầu tiên của câu trả lời. (Quá trình chuyển đổi HTTPS của Stack Overflow đang diễn ra tốt đẹp!) - i336_


Các ffmpeg với bảng màu phương pháp có thể chạy trong một lệnh duy nhất, không có trung gian .png tập tin.

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

Điều này có thể được thực hiện nhờ vào split bộ lọc.


6
2017-09-30 15:23





Dưới đây là tập tin thực thi cho người dùng 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

Nguồn: GIF chất lượng cao với FFmpeg: Chỉ trích xuất mẫu

Nếu bạn chỉ muốn sử dụng một biến đầu vào và có tên đầu ra chỉ có phần mở rộng GIF (phát âm là JIF), thì hãy sử dụng nó thay vào đó:

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
2018-06-23 22:31