1
0
This commit is contained in:
2025-01-04 16:36:57 +01:00
parent f94d01298f
commit 82b8935b6c
3 changed files with 742 additions and 398 deletions

View File

@@ -1,351 +1,353 @@
@ECHO OFF
:: By: MDHEXT, Nabi KaramAliZadeh <nabikaz@gmail.com>
:: Description: Video to GIF/APNG/WEBP converter
:: Version: 5.5
:: Url: https://github.com/MDHEXT/video2gif, forked from https://github.com/NabiKAZ/video2gif
:: What this script is based on: http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html
:: License: GNU General Public License v3.0 (GPLv3)
:: Enable delayed variable expension
SETLOCAL ENABLEDELAYEDEXPANSION
:: Storing Paths
SET input="%~1"
SET vid="%~dpnx1"
SET output=%~dpn1
SET FILEPATH=%~dp1
:: Setting the path to the Working Directory
SET WD=%TEMP%\VID2ANI
:: Checking for blank input or help commands
IF %input% == "" GOTO :help_message
IF %input% == "-?" GOTO :help_message
IF %input% == "/?" GOTO :help_message
IF %input% == "help" GOTO :help_message
IF %input% == "--help" GOTO :help_message
:: Clearing all variables
SET "scale="
SET "fps="
SET "mode="
SET "dither="
SET "bayerscale="
SET "filetype="
SET "start_time="
SET "end_time="
SET "webp_lossy="
SET "colormax="
SET "version="
SET "build="
SET "loglevel="
GOTO :varin
:varin
:: Using SHIFT command to go through the input and storing each setting into its own variable
IF NOT "%~1" =="" (
IF "%~1" =="-r" SET "scale=%~2" & SHIFT
IF "%~1" =="-f" SET "fps=%~2" & SHIFT
IF "%~1" =="-m" SET "mode=%~2" & SHIFT
IF "%~1" =="-d" SET "dither=%~2" & SHIFT
IF "%~1" =="-b" SET "bayerscale=%~2" & SHIFT
IF "%~1" =="-t" SET "filetype=%~2" & SHIFT
IF "%~1" =="-o" SET "output=%~dpnx2" & SHIFT
IF "%~1" =="-s" SET "start_time=%~2" & SHIFT
IF "%~1" =="-e" SET "end_time=%~2" & SHIFT
IF "%~1" =="-c" SET "colormax=%~2" & SHIFT
IF "%~1" =="-l" SET "webp_lossy=%~2" & SHIFT
IF "%~1" =="-v" SET "loglevel=%~2" & SHIFT
IF "%~1" =="-k" SET "errorswitch=1"
IF "%~1" =="-p" SET "picswitch=1"
SHIFT & GOTO :varin
)
GOTO :help_check_2
:help_check_2
:: Noob proofing the script to prevent it from breaking should critical settings not be defined
IF NOT DEFINED scale SET "scale=-1"
IF NOT DEFINED fps SET fps=15
IF NOT DEFINED mode SET mode=1
IF NOT DEFINED dither SET dither=0
IF NOT DEFINED filetype SET "filetype=gif"
IF NOT DEFINED loglevel SET "loglevel=error"
GOTO :safchek
:safchek
:: Setting a clear range of acceptable setting values and noob proofing bayerscale
:: Output file type
echo %filetype% | findstr /r "\<gif\> \<png\> \<apng\> \<webp\>" >nul
IF %errorlevel% NEQ 0 (
ECHO Not a valid file type
GOTO :EOF
)
IF "%filetype%"=="png" SET filetype=apng
IF "%filetype%"=="apng" SET output=%output%.png
IF "%filetype%"=="webp" SET output=%output%.webp
IF "%filetype%"=="gif" SET output=%output%.gif
:: Palettegen
IF %mode% GTR 3 (
ECHO Not a valid palettegen mode
GOTO :EOF
) ELSE IF %mode% LSS 1 (
ECHO Not a valid palettegen mode
GOTO :EOF
)
:: Dithering
IF %dither% GTR 8 (
ECHO Not a valid dither algorithm
GOTO :EOF
) ELSE IF %dither% LSS 0 (
ECHO Not a valid dither algorithm
GOTO :EOF
)
:: Bayerscale
IF DEFINED bayerscale (
IF !bayerscale! GTR 5 (
ECHO Not a valid bayerscale value
GOTO :EOF
) ELSE IF !bayerscale! LSS 0 (
ECHO Not a valid bayerscale value
GOTO :EOF
)
IF !bayerscale! LEQ 5 (
IF %dither% NEQ 1 (
ECHO This setting only works with bayer dithering
GOTO :EOF
)
)
)
:: Lossy WEBP
IF DEFINED webp_lossy (
IF NOT "%filetype%" == "webp" (
ECHO Lossy is only valid for filetype webp
GOTO :EOF
) ELSE IF !webp_lossy! GTR 100 (
ECHO Not a valid lossy quality value
GOTO :EOF
) ELSE IF !webp_lossy! LSS 0 (
ECHO Not a valid lossy quality value
GOTO :EOF
)
)
:: Noob Proofing clipping
IF DEFINED start_time (
IF DEFINED end_time SET "trim=-ss !start_time! -to !end_time!"
IF NOT DEFINED end_time (
ECHO Please input the end time
GOTO :EOF
)
)
IF NOT DEFINED start_time (
IF DEFINED end_time (
ECHO Please input the start time
GOTO :EOF
)
)
GOTO :script_start
:script_start
:: Storing FFmpeg version string
FOR /F "delims=" %%a in ('ffmpeg -version') DO (
IF NOT DEFINED version (
SET "version=%%a"
) ELSE IF NOT DEFINED build (
SET "build=%%a"
)
)
:: Displaying FFmpeg version string and creating the working directory
ECHO %version%
ECHO %build%
ECHO Output file: %output%
ECHO Creating working directory...
MD "%WD%"
:palettegen
:: Putting together command to generate palette
SET palette=%WD%\palette
SET frames=%palette%_%%05d
SET filters=fps=%fps%,scale=%scale%:-1:flags=lanczos
:: Palettegen mode
IF %mode% EQU 1 SET encode=palettegen=stats_mode=diff
IF %mode% EQU 2 SET encode="palettegen=stats_mode=single"
IF %mode% EQU 3 SET encode=palettegen
:: Max colors
IF DEFINED colormax (
IF %mode% LEQ 2 SET "mcol=:max_colors=%colormax%"
IF %mode% EQU 3 SET "mcol==max_colors=%colormax%"
)
:: Executing command to generate palette
ECHO Generating palette...
ffmpeg -v %loglevel% %trim% -i %vid% -vf "%filters%,%encode%%mcol%" -y "%frames%.png"
:: Checking if the palette file is in the Working Directory, if not cleaning up
IF NOT EXIST "%palette%_00001.png" (
IF NOT EXIST "%palette%.png" (
ECHO Failed to generate palette file
GOTO :cleanup
)
)
:: Setting variables to put the encode command together
:: Checking for Error Diffusion if using Bayer Scale and adjusting the command accordingly
IF %mode% EQU 1 SET decode=paletteuse
IF %mode% EQU 2 SET "decode=paletteuse=new=1"
IF %mode% EQU 3 SET decode=paletteuse
:: Error diffusion
IF DEFINED errorswitch (
IF %mode% EQU 1 SET "errordiff==diff_mode=rectangle"
IF %mode% EQU 2 SET "errordiff=:diff_mode=rectangle"
IF %mode% EQU 3 SET "errordiff==diff_mode=rectangle"
)
:: WEBP pixel format and lossy quality
IF "%filetype%" == "webp" (
IF DEFINED webp_lossy (
SET "webp_lossy=-lossless 0 -pix_fmt yuv420p -quality %webp_lossy%"
) ELSE SET "webp_lossy=-lossless 1"
)
:: Dither algorithm
IF %dither% EQU 0 SET ditheralg=none
IF %dither% EQU 1 SET ditheralg=bayer
IF %dither% EQU 2 SET ditheralg=heckbert
IF %dither% EQU 3 SET ditheralg=floyd_steinberg
IF %dither% EQU 4 SET ditheralg=sierra2
IF %dither% EQU 5 SET ditheralg=sierra2_4a
IF %dither% EQU 6 SET ditheralg=sierra3
IF %dither% EQU 7 SET ditheralg=burkes
IF %dither% EQU 8 SET ditheralg=atkinson
IF NOT %mode% EQU 2 (
IF DEFINED errorswitch SET ditherenc=:dither=!ditheralg!
IF NOT DEFINED errorswitch SET ditherenc==dither=!ditheralg!
) ELSE SET ditherenc=:dither=!ditheralg!
:: Checking for Bayer Scale and adjusting command
IF NOT DEFINED bayerscale SET "bayer="
IF DEFINED bayerscale SET bayer=:bayer_scale=%bayerscale%
:: Executing the encoding command
ECHO Encoding animation...
ffmpeg -v %loglevel% %trim% -i %vid% -thread_queue_size 512 -i "%frames%.png" -lavfi "%filters% [x]; [x][1:v] %decode%%errordiff%%ditherenc%%bayer%" -f %filetype% %webp_lossy% -loop 0 -plays 0 -y "%output%"
:: Checking if file was created and cleaning up if not
IF NOT EXIST "%output%" (
ECHO Failed to generate animation
GOTO :cleanup
)
:: Starting default Photo Viewer
IF DEFINED picswitch START "" "%output%"
:cleanup
:: Cleaning up
ECHO Deleting temporary files...
RMDIR /S /Q "%WD%"
ENDLOCAL
ECHO Done!
GOTO :EOF
:help_message
:: Print usage message
ECHO:
ECHO Video to GIF/APNG/WEBP converter v5.5
ECHO ^(C^) 2017-2022, MDHEXT ^&^ Nabi KaramAliZadeh ^<nabikaz@gmail.com^>
ECHO:
ECHO You can download this fork from here:
ECHO https://github.com/MDHEXT/video2gif
ECHO You can download the original release here:
ECHO https://github.com/NabiKAZ/video2gif
ECHO This tool uses ffmpeg, you can download that here:
ECHO https://www.ffmpeg.org/download.html#build-windows
ECHO This tool wouldn't be possible without the research listed here:
ECHO https://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html
ECHO:
ECHO Usage:
ECHO vid2ani [input_file] [Arguments]
ECHO:
ECHO Arguments:
ECHO:
ECHO -t Output file type.
ECHO Valid: 'gif' (default), 'png', 'webp'.
ECHO:
ECHO -o Output file.
ECHO The default is the same name as the input video.
ECHO:
ECHO -r Scale or size.
ECHO Width of the animation in pixels.
ECHO The default is the same scale as the original video.
ECHO:
ECHO -s Start time of the animation (HH:MM:SS.MS)
ECHO:
ECHO -e End time of the animation (HH:MM:SS.MS)
ECHO:
ECHO -f Framerate in frames per second.
ECHO The default is 15.
ECHO:
ECHO -d Dithering algorithm to be used.
ECHO The default is 0 (None).
ECHO:
ECHO -b Bayer Scale setting.
ECHO This can only be used when Bayer dithering is applied.
ECHO Range 0 - 5, default is 2.
ECHO:
ECHO -m Palettegen mode - one of 3 modes listed below.
ECHO The default is 1 (diff).
ECHO:
ECHO -c The maximum amount of colors useable per palette.
ECHO Range 3 - 256 (default)
ECHO:
ECHO -k Enables paletteuse error diffusion.
ECHO:
ECHO -l Enable lossy WebP compression and quality.
ECHO The default for WebP is lossless.
ECHO Range 0 - 100, default 75.
ECHO:
ECHO -v Set FFmpeg log level, for troubleshooting.
ECHO The default log level is 'error'
ECHO:
ECHO -p Opens the resulting animation in your default Photo Viewer.
ECHO:
ECHO Dithering Modes:
ECHO 0: None
ECHO 1: Bayer
ECHO 2: Heckbert
ECHO 3: Floyd Steinberg
ECHO 4: Sierra2
ECHO 5: Sierra2_4a
ECHO 6: sierra3
ECHO 7: burkes
ECHO 8: atkinson
ECHO:
ECHO Palettegen Modes:
ECHO 1: diff - only what moves affects the palette
ECHO 2: single - one palette per frame
ECHO 3: full - one palette for the whole animation
ECHO:
ECHO About Bayerscale:
ECHO When bayer dithering is selected, the Bayer Scale option defines the
ECHO scale of the pattern (how much the crosshatch pattern is visible).
ECHO A low value means more visible pattern for less banding, a higher value
ECHO means less visible pattern at the cost of more banding.
ECHO:
ECHO People who made this project come to fruition:
ECHO ubitux, Nabi KaramAliZadeh, and the very kind and patient people in the
ECHO Batch Discord Server. Without these people's contributions, this script
ECHO would not be possible. Thank you all for your contributions and
ECHO assistance^^!
GOTO :EOF
@ECHO OFF
:: Description: Video to GIF/APNG/WEBP converter
:: By: MDHEXT, Nabi KaramAliZadeh, Pathduck
:: Version: 6.0
:: Url: https://github.com/Pathduck/vid2ani/ forked from https://github.com/MDHEXT/video2gif
:: What this script is based on: http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html
:: License: GNU General Public License v3.0 (GPLv3)
:: Enable delayed variable expension
SETLOCAL ENABLEDELAYEDEXPANSION
:: Define ANSI Colors
SET "OFF="
SET "RED="
SET "GREEN="
SET "YELLOW="
SET "BLUE="
SET "CYAN="
:: Clearing vars and setting defaults
SET "fps=15"
SET "mode=1"
SET "dither=0"
SET "scale=-1"
SET "filetype=gif"
SET "webp_lossy="
SET "webp_lossy_def=75"
SET "loglevel=error"
SET "bayerscale="
SET "colormax="
SET "start_time="
SET "end_time="
SET "version="
SET "build="
SET "errorswitch="
SET "picswitch="
:: Assign input and output
SET input="%~1"
SET output=%~dpn1
:: Input file validation
IF NOT EXIST %input% (
ECHO %RED%Input file not found: %input%%OFF%
GOTO :EOF
)
:: Setting the path to the Working Directory
SET WD=%TEMP%\VID2ANI
:: Checking for blank input or help commands
IF %input% == "" GOTO :help_message
IF %input% == "-?" GOTO :help_message
IF %input% == "/?" GOTO :help_message
IF %input% == "help" GOTO :help_message
IF %input% == "--help" GOTO :help_message
GOTO :varin
:varin
:: Using SHIFT command to go through the input and storing each setting into its own variable
IF NOT "%~1" =="" (
IF "%~1" =="-r" SET "scale=%~2" & SHIFT
IF "%~1" =="-f" SET "fps=%~2" & SHIFT
IF "%~1" =="-m" SET "mode=%~2" & SHIFT
IF "%~1" =="-d" SET "dither=%~2" & SHIFT
IF "%~1" =="-b" SET "bayerscale=%~2" & SHIFT
IF "%~1" =="-t" SET "filetype=%~2" & SHIFT
IF "%~1" =="-o" SET "output=%~dpn2" & SHIFT
IF "%~1" =="-s" SET "start_time=%~2" & SHIFT
IF "%~1" =="-e" SET "end_time=%~2" & SHIFT
IF "%~1" =="-c" SET "colormax=%~2" & SHIFT
:: IF "%~1" =="-l" SET "webp_lossy=%~2" & SHIFT
IF "%~1" =="-l" (IF "%2" == "" ( SET "webp_lossy=%webp_lossy_def%"
) ELSE IF 1%2 NEQ +1%~2 ( SET "webp_lossy=%webp_lossy_def%"
) ELSE ( SET "webp_lossy=%~2" & SHIFT )
)
IF "%~1" =="-v" SET "loglevel=%~2" & SHIFT
IF "%~1" =="-k" SET "errorswitch=1"
IF "%~1" =="-p" SET "picswitch=1"
SHIFT & GOTO :varin
)
GOTO :safchek
:safchek
:: Setting a clear range of acceptable setting values and noob proofing bayerscale
:: Validate output file extension
echo %filetype% | findstr /r "\<gif\> \<png\> \<apng\> \<webp\>" >nul
IF %errorlevel% NEQ 0 (
ECHO %RED%Not a valid file type: %filetype%%OFF%
GOTO :EOF
)
IF "%filetype%"=="gif" SET "output=%output%.gif"
IF "%filetype%"=="png" SET "filetype=apng"
IF "%filetype%"=="apng" SET "output=%output%.png"
IF "%filetype%"=="webp" SET "output=%output%.webp"
:: Validate Palettegen
IF %mode% GTR 3 (
ECHO %RED%Not a valid palettegen ^(-m^) mode%OFF%
GOTO :EOF
) ELSE IF %mode% LSS 1 (
ECHO %RED%Not a valid palettegen ^(-m^) mode%OFF%
GOTO :EOF
)
:: Validate Dithering
IF %dither% GTR 8 (
ECHO %RED%Not a valid dither ^(-d^) algorithm %OFF%
GOTO :EOF
) ELSE IF %dither% LSS 0 (
ECHO %RED%Not a valid dither ^(-d^) algorithm%OFF%
GOTO :EOF
)
:: Validate Bayerscale
IF DEFINED bayerscale (
IF !bayerscale! GTR 5 (
ECHO %RED%Not a valid bayerscale ^(-b^) value %OFF%
GOTO :EOF
) ELSE IF !bayerscale! LSS 0 (
ECHO %RED%Not a valid bayerscale ^(-b^) value%OFF%
GOTO :EOF
)
IF %dither% NEQ 1 (
IF !bayerscale! LEQ 5 (
ECHO %RED%Bayerscale ^(-b^) only works with Bayer dithering%OFF%
GOTO :EOF
)
)
)
:: Validate Lossy WEBP
IF DEFINED webp_lossy (
IF NOT "%filetype%" == "webp" (
ECHO %RED%Lossy ^(-l^) is only valid for filetype webp%OFF%
GOTO :EOF
) ELSE IF !webp_lossy! GTR 100 (
ECHO %RED%Not a valid lossy ^(-l^) quality value%OFF%
GOTO :EOF
) ELSE IF !webp_lossy! LSS 0 (
ECHO %RED%Not a valid lossy ^(-l^) quality value%OFF%
GOTO :EOF
)
)
:: Validate Clipping
IF DEFINED start_time (
IF DEFINED end_time SET "trim=-ss !start_time! -to !end_time!"
IF NOT DEFINED end_time (
ECHO %RED%Please input the end time ^(-e^)%OFF%
GOTO :EOF
)
)
IF NOT DEFINED start_time (
IF DEFINED end_time (
ECHO %RED%Please input the start time ^(-s^)%OFF%
GOTO :EOF
)
)
:: Validate Framerate
IF DEFINED fps (
IF !fps! LSS 0 (
ECHO %RED%Framerate ^(-f^) must be greater than 0.%OFF%
GOTO :EOF
)
)
:: Validate Max Colors
IF DEFINED colormax (
IF !colormax! LSS 3 (
ECHO %RED%Max colors ^(-c^) must be between 3 and 256.%OFF%
GOTO :EOF
)
IF !colormax! GTR 256 (
ECHO %RED%Max colors ^(-c^) must be between 3 and 256.%OFF%
GOTO :EOF
)
)
GOTO :script_start
:script_start
:: Storing FFmpeg version string
FOR /F "delims=" %%a in ('ffmpeg -version') DO (
IF NOT DEFINED version (
SET "version=%%a"
) ELSE IF NOT DEFINED build (
SET "build=%%a"
)
)
:: Displaying FFmpeg version string and creating the working directory
ECHO %YELLOW%%version%%OFF%
ECHO %YELLOW%%build%%OFF%
ECHO %GREEN%Output file:%OFF% %output%
ECHO %GREEN%Creating working directory...%OFF%
MD "%WD%"
:palettegen
:: Putting together command to generate palette
SET palette=%WD%\palette_%%05d.png
SET filters=fps=%fps%,scale=%scale%:-1:flags=lanczos
:: APNG muxer does not support multiple palettes so fallback to using palettegen diff mode
IF "%filetype%"=="apng" (
IF %mode% EQU 2 (
ECHO %YELLOW%APNG does not support multiple palettes - falling back to Palettegen mode 1 ^(diff^)%OFF%
SET mode=1
)
)
:: Palettegen encode mode
IF %mode% EQU 1 SET "encode=palettegen=stats_mode=diff"
IF %mode% EQU 2 SET "encode=palettegen=stats_mode=single"
IF %mode% EQU 3 SET "encode=palettegen"
:: Max colors
IF DEFINED colormax (
IF %mode% LEQ 2 SET "mcol=:max_colors=%colormax%"
IF %mode% EQU 3 SET "mcol==max_colors=%colormax%"
)
:: Executing command to generate palette
ECHO %GREEN%Generating palette...%OFF%
echo ffmpeg -v %loglevel% %trim% -i %input% -vf "%filters%,%encode%%mcol%" -y "%palette%"
ffmpeg -v %loglevel% %trim% -i %input% -vf "%filters%,%encode%%mcol%" -y "%palette%"
:: Checking if the palette file is in the Working Directory, if not cleaning up
IF NOT EXIST "%WD%\palette_00001.png" (
ECHO %RED%Palette generation failed: %palette% not found.%OFF%
GOTO :cleanup
)
:: Setting variables to put the encode command together
:: Palettegen decode mode
IF %mode% EQU 1 SET "decode=paletteuse"
IF %mode% EQU 2 SET "decode=paletteuse=new=1"
IF %mode% EQU 3 SET "decode=paletteuse"
:: Error diffusion
IF DEFINED errorswitch (
IF %mode% EQU 1 SET "errordiff==diff_mode=rectangle"
IF %mode% EQU 2 SET "errordiff=:diff_mode=rectangle"
IF %mode% EQU 3 SET "errordiff==diff_mode=rectangle"
)
:: Prepare dithering and encoding options
IF %dither% EQU 0 SET "ditheralg=none"
IF %dither% EQU 1 SET "ditheralg=bayer"
IF %dither% EQU 2 SET "ditheralg=heckbert"
IF %dither% EQU 3 SET "ditheralg=floyd_steinberg"
IF %dither% EQU 4 SET "ditheralg=sierra2"
IF %dither% EQU 5 SET "ditheralg=sierra2_4a"
IF %dither% EQU 6 SET "ditheralg=sierra3"
IF %dither% EQU 7 SET "ditheralg=burkes"
IF %dither% EQU 8 SET "ditheralg=atkinson"
:: Paletteuse error diffusion
IF NOT %mode% EQU 2 (
IF DEFINED errorswitch SET "ditherenc=:dither=!ditheralg!"
IF NOT DEFINED errorswitch SET "ditherenc==dither=!ditheralg!"
) ELSE SET "ditherenc=:dither=!ditheralg!"
:: Checking for Bayer Scale and adjusting command
IF NOT DEFINED bayerscale SET "bayer="
IF DEFINED bayerscale SET "bayer=:bayer_scale=%bayerscale%"
:: WEBP pixel format and lossy quality
IF "%filetype%" == "webp" (
IF DEFINED webp_lossy (
SET "webp_lossy=-lossless 0 -pix_fmt yuva420p -quality %webp_lossy%"
) ELSE SET "webp_lossy=-lossless 1"
)
:: Executing the encoding command
ECHO %GREEN%Encoding animation...%OFF%
echo ffmpeg -v %loglevel% %trim% -i %input% -thread_queue_size 512 -i "%palette%" -lavfi "%filters% [x]; [x][1:v] %decode%%errordiff%%ditherenc%%bayer%" -f %filetype% %webp_lossy% -loop 0 -plays 0 -y "%output%"
ffmpeg -v %loglevel% %trim% -i %input% -thread_queue_size 512 -i "%palette%" -lavfi "%filters% [x]; [x][1:v] %decode%%errordiff%%ditherenc%%bayer%" -f %filetype% %webp_lossy% -loop 0 -plays 0 -y "%output%"
:: Checking if file was created and cleaning up if not
IF NOT EXIST "%output%" (
ECHO %RED%Failed to generate animation: %output% not found.%OFF%
GOTO :cleanup
)
:: Open output file if picswitch is set
IF DEFINED picswitch START "" "%output%"
:cleanup
:: Cleaning up
ECHO %GREEN%Deleting temporary files...%OFF%
RMDIR /S /Q "%WD%"
ECHO %GREEN%Done.%OFF%
ENDLOCAL
GOTO :EOF
:help_message
:: Print usage message
ECHO:
ECHO %GREEN%Video to GIF/APNG/WEBP converter v6.0%OFF%
ECHO %BLUE%By MDHEXT, Nabi KaramAliZadeh, Pathduck%OFF%
ECHO:
ECHO %GREEN%Usage:%OFF%
ECHO %~nx0 [input_file] [arguments]
ECHO:
ECHO %GREEN%Arguments:%OFF%
ECHO -t Output file type. Valid: 'gif' (default), 'apng', 'png', 'webp'.
ECHO -o Output file. The default is the same name as the input video.
ECHO -r Scale or size. Width of the animation in pixels.
ECHO -s Start time of the animation (HH:MM:SS.MS).
ECHO -e End time of the animation (HH:MM:SS.MS).
ECHO -f Framerate in frames per second (default: 15).
ECHO -d Dithering algorithm to be used (default: 0).
ECHO -b Bayer Scale setting. Range 0 - 5 (default: 2).
ECHO -m Palettegen mode: 1 (diff), 2 (single), 3 (full) (default: 1).
ECHO -c Maximum colors usable per palette. Range 3 - 256 (default).
ECHO -k Enables paletteuse error diffusion.
ECHO -l Enable lossy WebP compression and quality. Range 0 - 100.
ECHO -v Set FFmpeg log level (default: error).
ECHO -p Opens the resulting animation in the default viewer.
ECHO:
ECHO %GREEN%Dithering Mode%OFF%
ECHO 0: None
ECHO 1: Bayer
ECHO 2: Heckbert
ECHO 3: Floyd Steinberg
ECHO 4: Sierra2
ECHO 5: Sierra2_4a
ECHO 6: Sierra3
ECHO 7: Burkes
ECHO 8: Atkinson
ECHO:
ECHO %GREEN%Palettegen Modes%OFF%
ECHO 1: diff - only what moves affects the palette
ECHO 2: single - one palette per frame
ECHO 3: full - one palette for the whole animation
ECHO:
ECHO %GREEN%About Bayerscale%OFF%
ECHO When bayer dithering is selected, the Bayer Scale option defines the
ECHO scale of the pattern (how much the crosshatch pattern is visible).
ECHO A low value means more visible pattern for less banding, a higher value
ECHO means less visible pattern at the cost of more banding.
ECHO:
ECHO %GREEN%People who made this project come to fruition%OFF%
ECHO ubitux, Nabi KaramAliZadeh, and the very kind and patient people in the
ECHO Batch Discord Server. Without these people's contributions, this script
ECHO would not be possible. Thank you all for your contributions and
ECHO assistance^^!
GOTO :EOF

331
Batch/vid2ani.sh Executable file
View File

@@ -0,0 +1,331 @@
#!/bin/bash
# Description: Video to GIF/APNG/WEBP converter
# By: MDHEXT, Nabi KaramAliZadeh, Pathduck
# Version: 6.0
# Url: https://github.com/Pathduck/vid2ani/ forked from https://github.com/MDHEXT/video2gif
# What this script is based on: http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html
# License: GNU General Public License v3.0 (GPLv3)
# Enable error handling
# set -euo pipefail
### Start Main ###
main() {
# Define ANSI Colors
OFF=$(tput sgr0)
RED=$(tput setaf 1)
GREEN=$(tput setaf 10)
YELLOW=$(tput setaf 11)
BLUE=$(tput setaf 12)
CYAN=$(tput setaf 14)
# Clearing vars and setting defaults
fps=15
mode=1
dither=0
scale="-1"
filetype="gif"
webp_lossy=""
webp_lossy_def=75
loglevel="error"
bayerscale=""
colormax=""
start_time=""
end_time=""
trim=""
errorswitch=""
errordiff=""
picswitch=""
# Assign input and output
if [ $# -eq 0 ]; then print_help; exit; fi
input="$1"
output="${input%.*}"
echo "Input file: $input"
echo "Output file: $output"
# Input file validation
if [[ ! -f "$input" ]]; then
echo ${RED}"Input file not found: $input"${OFF}; exit 1
fi
# Fix paths for Cygwin and create working dir
if [[ "$(uname -o)" == "Cygwin" ]]; then
# Use Windows-compatible directories for Cygwin
input=$(cygpath -w "$input")
output=$(cygpath -w "$output")
WD=$(cygpath -w "$(mktemp -d -t vid2ani-XXXXXX)")
else
# Use POSIX-compatible directories
WD=$(mktemp -d -t vid2ani-XXXXXX)
fi
# Cleanup on exit, interrupt, termination
trap 'rm -rf "$WD"' EXIT INT TERM
# Parse Arguments
shift
while [[ $# -gt 0 ]]; do
case "$1" in
-r) scale="$2"; shift 2;;
-f) fps="$2"; shift 2;;
-m) mode="$2"; shift 2;;
-d) dither="$2"; shift 2;;
-b) bayerscale="$2"; shift 2;;
-t) filetype="$2"; shift 2;;
-o) output="${2%.*}"; shift 2;;
-s) start_time="$2"; shift 2;;
-e) end_time="$2"; shift 2;;
-c) colormax="$2"; shift 2;;
# -l) webp_lossy="$2"; shift 2;;
-l) if [[ ! "$2" =~ ^[0-9]+$ ]]; then webp_lossy=$webp_lossy_def; shift
else webp_lossy="$2"; shift 2; fi ;;
-v) loglevel="$2"; shift 2;;
-k) errorswitch=1; shift;;
-p) picswitch=1; shift;;
-h|-?) print_help; exit;;
*) echo ${RED}"Unknown option $1"${OFF}; exit 1;;
esac
done
# Validate output file extension
case "$filetype" in
gif) output="$output.gif";;
png) output="$output.png"; filetype="apng";;
apng) output="$output.png";;
webp) output="$output.webp";;
*) echo ${RED}"Invalid file type: $filetype"${OFF}; exit 1;;
esac
echo "Input file: $input"
echo "Output file: $output"
# Validate Palettegen
if [[ "$mode" -lt 1 || "$mode" -gt 3 ]]; then
echo ${RED}"Not a valid palettegen (-m) mode"${OFF}; exit 1
fi
# Validate Dithering
if [[ "$dither" -gt 8 || "$dither" -lt 0 ]]; then
echo ${RED}"Not a valid dither (-d) algorithm"${OFF}; exit 1
fi
# Validate Bayerscale
if [[ -n "$bayerscale" ]]; then
if [[ "$bayerscale" -gt 5 || "$bayerscale" -lt 0 ]]; then
echo ${RED}"Not a valid bayerscale (-b) value"${OFF}; exit 1
fi
if [[ "$dither" -ne 1 ]]; then
echo ${RED}"Bayerscale (-b) only works with Bayer dithering"${OFF}; exit 1
fi
fi
# Validate Lossy WEBP
if [[ -n "$webp_lossy" ]]; then
if [[ "$filetype" != "webp" ]]; then
echo ${RED}"Lossy (-l) is only valid for filetype webp"${OFF}; exit 1
fi
if [[ "$webp_lossy" -gt 100 || "$webp_lossy" -lt 0 ]]; then
echo ${RED}"Not a valid lossy (-l) quality value"${OFF}; exit 1
fi
fi
# Validate Clipping
if [[ -n "$start_time" && -z "$end_time" ]]; then
echo ${RED}"End time (-e) is required when Start time (-e) is specified."${OFF}; exit 1
elif [[ -n "$end_time" && -z "$start_time" ]]; then
echo ${RED}"Start time (-s) is required when End time (-e) is specified."${OFF}; exit 1
elif [[ -n "$end_time" && -n "$start_time" ]]; then
trim="-ss $start_time -to $end_time"
fi
# Validate Framerate
if [[ "$fps" -le 0 ]]; then
echo ${RED}"Framerate (-f) must be greater than 0."${OFF}; exit 1
fi
# Validate Max Colors
if [[ -n "$colormax" && "$colormax" -lt 3 || "$colormax" -gt 256 ]]; then
echo ${RED}"Max colors (-c) must be between 3 and 256."${OFF}; exit 1
fi
# Displaying FFmpeg version string
ffmpeg_version=$(ffmpeg -version | head -n2)
echo ${YELLOW}"$ffmpeg_version"${OFF}
echo ${GREEN}Output file:${OFF} $output
## Putting together command to generate palette ##
palette="$WD/palette_%05d.png"
filters="fps=$fps,scale=$scale:-1:flags=lanczos"
# APNG muxer does not support multiple palettes so fallback to using palettegen diff mode
if [[ "$filetype" == "apng" && "$mode" -eq 2 ]]; then
echo ${YELLOW}"APNG does not support multiple palettes - falling back to Palettegen mode 1 (diff)"${OFF}
mode=1
fi
# Palettegen encode mode
encode=""
if [[ -n "$mode" ]]; then
case "$mode" in
1) encode="palettegen=stats_mode=diff";;
2) encode="palettegen=stats_mode=single";;
3) encode="palettegen";;
*) echo ${RED}"Invalid palettegen (-m) mode"${OFF}; exit 1;;
esac
fi
# Max colors
mcol=""
if [[ -n "$colormax" ]]; then
if [[ "$mode" -le 2 ]]; then mcol=":max_colors=${colormax}"; fi
if [[ "$mode" -eq 3 ]]; then mcol="=max_colors=${colormax}"; fi
fi
# Executing command to generate palette
echo ${GREEN}"Generating palette..."${OFF}
echo ffmpeg -v "${loglevel}" ${trim:-} -i "${input}" -vf "${filters},${encode}${mcol}" -y "${palette}"
ffmpeg -v "${loglevel}" ${trim:-} -i "${input}" -vf "${filters},${encode}${mcol}" -y "${palette}"
# Checking if the palette file is in the Working Directory, if not cleaning up
if [[ ! -f "$WD/palette_00001.png" ]]; then
echo ${RED}"Palette generation failed: $palette not found."${OFF}; exit 1
fi
## Setting variables to put the encode command together ##
# Palettegen decode mode
if [[ -n "$mode" ]]; then
case "$mode" in
1) decode="paletteuse";;
2) decode="paletteuse=new=1";;
3) decode="paletteuse";;
*) echo ${RED}"Invalid palettegen (-m) mode"${OFF}; exit 1;;
esac
fi
# Error diffusion
if [[ -n "$errorswitch" ]]; then
case "$mode" in
1) errordiff="=diff_mode=rectangle";;
2) errordiff=":diff_mode=rectangle";;
3) errordiff="=diff_mode=rectangle";;
*) echo ${RED}"Invalid palettegen (-m) mode"${OFF}; exit 1;;
esac
fi
# Prepare dithering and encoding options
ditheralg="none"
case "$dither" in
0) ditheralg="none";;
1) ditheralg="bayer";;
2) ditheralg="heckbert";;
3) ditheralg="floyd_steinberg";;
4) ditheralg="sierra2";;
5) ditheralg="sierra2_4a";;
6) ditheralg="sierra3";;
7) ditheralg="burkes";;
8) ditheralg="atkinson";;
*) echo ${RED}"Invalid dither (-d )mode"${OFF}; exit 1;;
esac
# Paletteuse error diffusion
ditherenc=""
if [[ "$mode" -ne 2 ]]; then
if [[ -n "$errorswitch" ]]; then ditherenc=":dither=$ditheralg"; fi
if [[ -z "$errorswitch" ]]; then ditherenc="=dither=$ditheralg"; fi
else
ditherenc=":dither=$ditheralg"
fi
# Checking for Bayer Scale and adjusting command
if [[ -n "$bayerscale" ]]; then bayer=":bayer_scale=$bayerscale"; fi
if [[ -z "$bayerscale" ]]; then bayer=""; fi
# WEBP pixel format and lossy quality
if [[ "$filetype" == "webp" && -n "$webp_lossy" ]]; then
webp_lossy="-lossless 0 -quality $webp_lossy -pix_fmt yuva420p"
elif [[ "$filetype" == "webp" && -z "$webp_lossy" ]]; then
webp_lossy="-lossless 1"
fi
# Executing the encoding command
echo ${GREEN}"Encoding animation..."${OFF}
echo ffmpeg -v "${loglevel}" ${trim:-} -i "${input}" -thread_queue_size 512 -i "${palette}" -lavfi "${filters} [x]; [x][1:v] ${decode}${errordiff}${ditherenc}${bayer}" -f "${filetype}" ${webp_lossy:-} -loop 0 -plays 0 -y "${output}"
ffmpeg -v "${loglevel}" ${trim:-} -i "${input}" -thread_queue_size 512 -i "${palette}" -lavfi "${filters} [x]; [x][1:v] ${decode}${errordiff}${ditherenc}${bayer}" -f "${filetype}" ${webp_lossy:-} -loop 0 -plays 0 -y "${output}"
# Checking if output file was created
if [[ ! -f "$output" ]]; then
echo ${RED}"Failed to generate animation: $output not found"${OFF}; exit 1
fi
# Open output file if picswitch is enabled
if [[ -n "$picswitch" ]]; then
xdg-open "$output"
fi
echo ${GREEN}"Done."${OFF}
}
### End Main ###
### Function to print the help message ###
print_help() {
cat << EOF
${GREEN}Video to GIF/APNG/WEBP converter v6.0${OFF}
${BLUE}By MDHEXT, Nabi KaramAliZadeh, Pathduck${OFF}
${GREEN}Usage:${OFF}
$(basename $0) [input_file] [arguments]
${GREEN}Arguments:${OFF}
-t Output file type. Valid: 'gif' (default), 'apng', 'png', 'webp'.
-o Output file. The default is the same name as the input video.
-r Scale or size. Width of the animation in pixels.
-s Start time of the animation (HH:MM:SS.MS).
-e End time of the animation (HH:MM:SS.MS).
-f Framerate in frames per second (default: 15).
-d Dithering algorithm to be used (default: 0).
-b Bayer Scale setting. Range 0 - 5 (default: 2).
-m Palettegen mode: 1 (diff), 2 (single), 3 (full) (default: 1).
-c Maximum colors usable per palette. Range 3 - 256 (default).
-k Enables paletteuse error diffusion.
-l Enable lossy WebP compression and quality. Range 0 - 100.
-v Set FFmpeg log level (default: error).
-p Opens the resulting animation in the default viewer.
${GREEN}Dithering Mode${OFF}
0: None
1: Bayer
2: Heckbert
3: Floyd Steinberg
4: Sierra2
5: Sierra2_4a
6: Sierra3
7: Burkes
8: Atkinson
${GREEN}Palettegen Modes${OFF}
1: diff - only what moves affects the palette
2: single - one palette per frame
3: full - one palette for the whole animation
${GREEN}About Bayerscale${OFF}
When bayer dithering is selected, the Bayer Scale option defines the
scale of the pattern (how much the crosshatch pattern is visible).
A low value means more visible pattern for less banding, a higher value
means less visible pattern at the cost of more banding.
${GREEN}People who made this project come to fruition${OFF}
ubitux, Nabi KaramAliZadeh, and the very kind and patient people in the
Batch Discord Server. Without these people's contributions, this script
would not be possible. Thank you all for your contributions and
assistance^^!
EOF
}
### End print_help ###
# Call Main function
main "$@"; exit;

View File

@@ -1,54 +1,65 @@
@echo off
setlocal
call :setESC
cls
echo  STYLES 
echo ^<ESC^>[0m Reset
echo ^<ESC^>[1m Bold
echo ^<ESC^>[4m Underline
echo ^<ESC^>[7m Inverse
echo %ESC%[101;93m STYLES %ESC%[0m
echo ^<ESC^>[0m %ESC%[0mReset%ESC%[0m
echo ^<ESC^>[1m %ESC%[1mBold%ESC%[0m
echo ^<ESC^>[4m %ESC%[4mUnderline%ESC%[0m
echo ^<ESC^>[7m %ESC%[7mInverse%ESC%[0m
echo.
echo  NORMAL FOREGROUND COLORS 
echo ^<ESC^>[30m Black (black)
echo ^<ESC^>[31m Red
echo ^<ESC^>[32m Green
echo ^<ESC^>[33m Yellow
echo ^<ESC^>[34m Blue
echo ^<ESC^>[35m Magenta
echo ^<ESC^>[36m Cyan
echo ^<ESC^>[37m White
echo %ESC%[101;93m NORMAL FOREGROUND COLORS %ESC%[0m
echo ^<ESC^>[30m %ESC%[30mBlack%ESC%[0m (black)
echo ^<ESC^>[31m %ESC%[31mRed%ESC%[0m
echo ^<ESC^>[32m %ESC%[32mGreen%ESC%[0m
echo ^<ESC^>[33m %ESC%[33mYellow%ESC%[0m
echo ^<ESC^>[34m %ESC%[34mBlue%ESC%[0m
echo ^<ESC^>[35m %ESC%[35mMagenta%ESC%[0m
echo ^<ESC^>[36m %ESC%[36mCyan%ESC%[0m
echo ^<ESC^>[37m %ESC%[37mWhite%ESC%[0m
echo.
echo  NORMAL BACKGROUND COLORS 
echo ^<ESC^>[40m Black
echo ^<ESC^>[41m Red
echo ^<ESC^>[42m Green
echo ^<ESC^>[43m Yellow
echo ^<ESC^>[44m Blue
echo ^<ESC^>[45m Magenta
echo ^<ESC^>[46m Cyan
echo ^<ESC^>[47m White (white)
echo %ESC%[101;93m NORMAL BACKGROUND COLORS %ESC%[0m
echo ^<ESC^>[40m %ESC%[40mBlack%ESC%[0m
echo ^<ESC^>[41m %ESC%[41mRed%ESC%[0m
echo ^<ESC^>[42m %ESC%[42mGreen%ESC%[0m
echo ^<ESC^>[43m %ESC%[43mYellow%ESC%[0m
echo ^<ESC^>[44m %ESC%[44mBlue%ESC%[0m
echo ^<ESC^>[45m %ESC%[45mMagenta%ESC%[0m
echo ^<ESC^>[46m %ESC%[46mCyan%ESC%[0m
echo ^<ESC^>[47m %ESC%[47mWhite%ESC%[0m (white)
echo.
echo  STRONG FOREGROUND COLORS 
echo ^<ESC^>[90m White
echo ^<ESC^>[91m Red
echo ^<ESC^>[92m Green
echo ^<ESC^>[93m Yellow
echo ^<ESC^>[94m Blue
echo ^<ESC^>[95m Magenta
echo ^<ESC^>[96m Cyan
echo ^<ESC^>[97m White
echo %ESC%[101;93m STRONG FOREGROUND COLORS %ESC%[0m
echo ^<ESC^>[90m %ESC%[90mWhite%ESC%[0m
echo ^<ESC^>[91m %ESC%[91mRed%ESC%[0m
echo ^<ESC^>[92m %ESC%[92mGreen%ESC%[0m
echo ^<ESC^>[93m %ESC%[93mYellow%ESC%[0m
echo ^<ESC^>[94m %ESC%[94mBlue%ESC%[0m
echo ^<ESC^>[95m %ESC%[95mMagenta%ESC%[0m
echo ^<ESC^>[96m %ESC%[96mCyan%ESC%[0m
echo ^<ESC^>[97m %ESC%[97mWhite%ESC%[0m
echo.
echo  STRONG BACKGROUND COLORS 
echo ^<ESC^>[100m Black
echo ^<ESC^>[101m Red
echo ^<ESC^>[102m Green
echo ^<ESC^>[103m Yellow
echo ^<ESC^>[104m Blue
echo ^<ESC^>[105m Magenta
echo ^<ESC^>[106m Cyan
echo ^<ESC^>[107m White
echo %ESC%[101;93m STRONG BACKGROUND COLORS %ESC%[0m
echo ^<ESC^>[100m %ESC%[100mBlack%ESC%[0m
echo ^<ESC^>[101m %ESC%[101mRed%ESC%[0m
echo ^<ESC^>[102m %ESC%[102mGreen%ESC%[0m
echo ^<ESC^>[103m %ESC%[103mYellow%ESC%[0m
echo ^<ESC^>[104m %ESC%[104mBlue%ESC%[0m
echo ^<ESC^>[105m %ESC%[105mMagenta%ESC%[0m
echo ^<ESC^>[106m %ESC%[106mCyan%ESC%[0m
echo ^<ESC^>[107m %ESC%[107mWhite%ESC%[0m
echo.
echo  COMBINATIONS 
echo ^<ESC^>[31m red foreground color
echo ^<ESC^>[7m inverse foreground ^<-^> background
echo ^<ESC^>[7;31m inverse red foreground color
echo ^<ESC^>[7m and nested ^<ESC^>[31m before nested
echo ^<ESC^>[31m and nested ^<ESC^>[7m before nested
echo %ESC%[101;93m COMBINATIONS %ESC%[0m
echo ^<ESC^>[31m %ESC%[31mred foreground color%ESC%[0m
echo ^<ESC^>[7m %ESC%[7minverse foreground ^<-^> background%ESC%[0m
echo ^<ESC^>[7;31m %ESC%[7;31minverse red foreground color%ESC%[0m
echo ^<ESC^>[7m and nested ^<ESC^>[31m %ESC%[7mbefore %ESC%[31mnested%ESC%[0m
echo ^<ESC^>[31m and nested ^<ESC^>[7m %ESC%[31mbefore %ESC%[7mnested%ESC%[0m
:setESC
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set ESC=%%b
exit /B 0
)
exit /B 0