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

¿Cómo convierto un vídeo a GIF usando ffmpeg, con una calidad razonable?

Estoy convirtiendo un vídeo a un archivo GIF con ffmpeg:

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

Funciona muy bien, pero el archivo gif de salida tiene una calidad muy baja.

¿Alguna idea de cómo puedo mejorar la calidad del gif convertido?

Respuestas (12)

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

ffmpeg ejemplo

183k

ffmpeg puede emitir GIF de alta calidad. Antes de empezar se recomienda siempre usar una versión reciente: descargar o compilar .

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
  • Este ejemplo saltará los primeros 30 segundos (-ss 30) de la entrada y creará una salida de 3 segundos (-t 3).
  • fps filtro fija la velocidad de cuadro. En el ejemplo se utiliza una tasa de 10 cuadros por segundo.
  • escala el filtro redimensionará la salida a 320 píxeles de ancho y determinará automáticamente la altura preservando la relación de aspecto. El lanczos algoritmo de escalado se utiliza en este ejemplo.
  • palettegen y paletteuse los filtros generarán y utilizarán una paleta personalizada generada a partir de su entrada. Estos filtros tienen muchas opciones, por lo tanto, consulte los enlaces para obtener una lista de todas las opciones y valores disponibles. También consulta la sección Opciones avanzadas más abajo.
  • El filtro split permitirá que todo se haga con un solo comando y evita tener que crear un archivo PNG temporal de la paleta.
  • Control de bucle con la opción de salida -loop pero los valores son confusos. Un valor de 0 es un looping infinito, -1 no es un looping, y 1 hará un looping una vez, lo que significa que se reproducirá dos veces. Así que un valor de 10 hará que el GIF se reproduzca 11 veces.

Opciones avanzadas

Los filtros palettegen y paletteuse tienen muchas opciones adicionales. Las más importantes son:

  • stats_mode (palettegen). Puedes forzar a los filtros a enfocar la paleta en la imagen general (full que es la predeterminada), sólo las partes móviles (diff), o cada cuadro individual (single). Por ejemplo, para generar una paleta para cada cuadro individual usa palettegen=stats_mode=single & paletteuse=new=1.

  • dither (paletteuse). Elija el algoritmo de vacilación. Hay tres tipos principales: determinístico (bayer), de difusión de errores (todos los demás incluyendo el predeterminado sierra2_4a), y ninguno. Tu GIF puede verse mejor usando un algoritmo de titubeo particular, o sin titubeo alguno. Si quieres probar bayer asegúrate de probar también la opción bayer_scale.

Consulta GIF de alta calidad con FFmpeg para obtener explicaciones, imágenes de ejemplo, e información más detallada para un uso avanzado.

Consulta también la documentación de palettegen y paletteuse para todas las opciones y valores disponibles.


ImageMagick convert ejemplo

227k

Otro método de la línea de comandos es hacer un pipe de ffmpeg a convert (o magick) desde ImageMagick.

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 opciones:

  • -vf "fps=10,scale=320:-1:flags=lanczos" un filtrógrafo usando los filtros fps y escala . fps establece la velocidad de cuadro a 10, y escala establece el tamaño a 320 píxeles de ancho y la altura se determina automáticamente y usa un valor que preserva la relación de aspecto. El lanczos algoritmo de escalado se utiliza en este ejemplo.

  • -c:v pam Elige el codificador de imágenes pam. El ejemplo da como resultado el formato de imagen PAM (Portable AnyMap) que es un formato RGB simple y sin pérdidas que soporta la transparencia (alfa) y es soportado por convert. Es más rápido de codificar que PNG.

  • -f image2pipe elige el muxer de imagen2pipe porque cuando sale a un pipe ffmpeg necesita que se le diga qué muxer usar.

convert opciones:

  • -delay Ver Ajustando la velocidad de cuadro sección más abajo.

  • -loop 0 hace un bucle infinito.

  • -layers optimize Habilitará el optimizador GIF de propósito general. Ver ImageMagick Animation Optimization para más detalles. No se garantiza que produzca una salida más pequeña, por lo que vale la pena intentarlo sin -layers optimize y comparar los resultados.

Configurar la velocidad de fotogramas

Configurar la velocidad de fotogramas con una combinación del filtro fps en ffmpeg y -delay en convert. Esto puede complicarse porque convert sólo obtiene un flujo de imágenes en bruto, por lo que no se conserva ningún fps. En segundo lugar, el valor de -delay en convert está en ticks (hay 100 ticks por segundo), no en fotogramas por segundo. Por ejemplo, con fps=12.5 = 100/12,5 = 8 = -delay 8.

convert redondea el valor de -delay a un número entero, por lo que 8,4 resulta en 8 y 8,5 en 9. Esto significa efectivamente que sólo se admiten algunas velocidades de trama al establecer un retardo uniforme en todas las tramas (se puede establecer un retardo específico por trama pero eso está más allá de esta respuesta).

-delay parece ser ignorado si se utiliza como una opción de salida, por lo que tiene que ser utilizado antes de - como se muestra en el ejemplo.

Por último, los navegadores y los visualizadores de imágenes pueden implementar una demora mínima, por lo que su -delay puede ser ignorado de todos modos.

Video cortesía del Centro Nacional de Entrenamiento para la Conservación del Servicio de Pesca y Vida Silvestre de los Estados Unidos.

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

Si prefiere evitar los archivos de imagen intermedios, los comandos proporcionados por LordNeckBeard pueden ser canalizados entre ffmpeg y el convert de ImageMagick, de modo que no se requieran archivos intermedios:

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

El -f image2pipe le dice a ffmpeg que divida el vídeo en imágenes y lo haga apto para ser canalizado, y el -vcodec ppm especifica que el formato de salida sea ppm (por alguna razón si el formato es png, o bien el convert no lee todas las imágenes del pipe, o bien ffmpeg no las emite todas). El - para ambos comandos especifica que se usará un pipe para la salida y la entrada respectivamente.

Para optimizar el resultado sin guardar un archivo, puedes pipetear la salida de convert a un segundo comando 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

El gif:- le dice al convert que pipetee su salida como datos con formato gif y el -layers Optimize le dice al segundo convert que realice los métodos optimize-frame y optimize-transparancy (ver el ImageMagick Introducción a la optimización de la animación ). Ten en cuenta que la salida de -layers Optimize no siempre puede proporcionar un tamaño de archivo más pequeño, así que es posible que quieras probar a convertir a un gif sin optimización primero para estar seguro.

Recuerda que durante todo este proceso todo está en la memoria, así que puede que necesites suficiente memoria si las imágenes son bastante grandes.

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

A partir de ffmpeg 2.6, podemos hacerlo aún mejor:

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

La respuesta de @Stephane es muy buena. Pero recibirá una advertencia como Buffer queue overflow, dropping. para algún video, y el gif generado tiene algún cuadro caído.

Aquí hay una versión mejor con el filtro fifo para evitar Buffer queue overflow cuando se usa el filtro paletteuse. Usando el filtro split para evitar la creación de un archivo PNG de paleta intermedia.

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
18
18
18
2015-07-12 09:35:07 +0000

Hice mi propia versión del guión, que parametriza la resolución de salida y la velocidad de cuadro también.

Running ./gifenc.sh input.mov output.gif 720 10 producirá un GIF de 720p de ancho 10fps de la película que le diste. Puede que necesites hacer chmod +x gifenc.sh para el archivo.

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

Puedes leer los detalles en mi Github

Supuestos: ffmpeg está instalado, y el guión está en la misma carpeta que los otros archivos.

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

El ffmpeg con la paleta método puede ser ejecutado en un solo comando, sin el archivo .png intermediario.

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

Esto puede hacerse gracias al filtro split .

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

hizo un guión, lo probó y funciona.

uso:

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

TENER 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 es una EXCELENTE herramienta de captura de pantalla para Linux :)

MUCHAS GRACIAS Michael Kohaupt :)

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

Linux/Unix/macOS

Siguiendo @LordNeckbeard approach con el comando ffmpeg, por favor encuentra la siguiente útil función Bash que puede ser añadida a tu archivo ~/.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"
}

Una vez que la función es cargada (manualmente o desde . ~/.bash_profile), deberías tener el nuevo comando video2gif.

Ejemplo de uso:

video2gif input.flv

o:

video2gif input.flv 320 10

Escala a 320 de ancho con 10 cuadros por segundo.

También puede especificar un formato de vídeo diferente (como mp4).


macOS

Puede probar la aplicación GIF Brewery que puede crear GIFs a partir de archivos de vídeo.

  • *

Alternativamente hay varios sitios web que están haciendo la conversión en línea de forma gratuita.

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

La respuesta seleccionada asume que desea escalar el video fuente y cambiar sus fps en el gif producido. Esto fue útil cuando quise un gif que recreara fielmente el video fuente que estaba usando.

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

Para los usuarios de Windows: crear el archivo video2gif.bat en el directorio de Windows con el siguiente contenido:

@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

Y luego, en cualquier lugar donde pueda usarlo, sea como este ejemplo:

video2gif myvideo.mp4

Entonces tienes myvideo.gif en el directorio actual. Si myvideo.gif existe, pregunta por ti para sobrescribirlo.

EDIT:

Sugiero usar este script de lote https://github.com/NabiKAZ/video2gif

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

A continuación se encuentra el archivo batch para usuarios de 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

Fuente: GIF de alta calidad con FFmpeg: Extrayendo solo una muestra

Si solo quieres usar una variable de entrada y que el nombre de salida tenga solo la extensión GIF (pronunciado JIF), entonces usa esto en su lugar:

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

Cómo agregar una entrada del menú contextual de Windows 7/10 “click derecho” para convertir tu archivo de video a gif

Algunas de las otras respuestas mencionaron el script video2gif , que yo usé. Pero, podrías usar cualquier script.

Para crear la opción de menú contextual, necesitas editar tu registro. Abre un símbolo de comando de powerhell, ejecutándose con privilegios de administrador. Ejecuta estos comandos:

$key = "Registry::HKEY_CLASSES_ROOT# Cómo agregar una entrada del menú contextual de Windows 7/10 "click derecho" para convertir tu archivo de video a gif 

Algunas de las otras respuestas mencionaron el script [ video2gif ]&003, que yo usé. Pero, podrías usar cualquier script. 

Para crear la opción de menú contextual, necesitas editar tu registro. Abre un símbolo de comando de powerhell, ejecutándose con privilegios de administrador. Ejecuta estos comandos: 

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

Ahora cuando hagas clic con el botón derecho del ratón en un archivo tendrás la opción “Ejecutar Video2Gif”!

btw He instalado ffmpeg a `C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static# Cómo agregar una entrada del menú contextual de Windows 7/10 “click derecho” para convertir tu archivo de video a gif

Algunas de las otras respuestas mencionaron el script [ video2gif ]&003, que yo usé. Pero, podrías usar cualquier script.

Para crear la opción de menú contextual, necesitas editar tu registro. Abre un símbolo de comando de powerhell, ejecutándose con privilegios de administrador. Ejecuta estos comandos:

$key = "Registry::HKEY_CLASSES_ROOT# Cómo agregar una entrada del menú contextual de Windows 7/10 "click derecho" para convertir tu archivo de video a gif 

Algunas de las otras respuestas mencionaron el script [ video2gif ]&003, que yo usé. Pero, podrías usar cualquier script. 

Para crear la opción de menú contextual, necesitas editar tu registro. Abre un símbolo de comando de powerhell, ejecutándose con privilegios de administrador. Ejecuta estos comandos: 

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

Ahora cuando hagas clic con el botón derecho del ratón en un archivo tendrás la opción “Ejecutar Video2Gif”!

btw He instalado ffmpeg a y he puesto el script video2gif.bat en el bin dir justo al lado de ffmpeg.exe. También añadí C:\dev\ffmpeg\ffmpeg-3.4.2-win64-static\bin a mi Windows PATH, pero no creo que lo necesites.

Si quieres la opción de poder suministrar algunas banderas / args de línea de comandos adicionales al script, entonces haz un nuevo archivo llamado video2gif-prompt.bat, y haz que el registro lo refiera en lugar de 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%

Todavía puedes pulsar enter para obtener rápidamente los valores por defecto.