@echo off
setlocal EnableDelayedExpansion
REM Default values
set "RESOLUTION=360"
set "DEFAULT_QUALITY=40"
set "DEFAULT_EFFORT=8"
REM Parameter validation - if any required parameter is missing, show usage
if "%~1"=="" goto :show_usage
if "%~2"=="" goto :show_usage
if "%~3"=="" goto :show_usage
REM Process input parameters (remove quotes if present)
set "input=%~1"
set "start_time=%~2"
set "duration=%~3"
REM Set quality parameter with default
if "%~4"=="" (
set "quality=%DEFAULT_QUALITY%"
) else (
set "quality=%~4"
)
REM Set effort parameter with default
if "%~5"=="" (
set "effort=%DEFAULT_EFFORT%"
) else (
set "effort=%~5"
)
REM Generate output filename
set "output=%~n1-%RESOLUTION%p.avif"
REM Validate input file exists
if not exist "%input%" (
echo ERROR: Input file "%input%" does not exist!
pause
exit /b 1
)
echo Converting "%input%" to "%output%"
echo Start time: %start_time%, Duration: %duration%s
echo Resolution: %RESOLUTION%p, Quality: %quality%, Effort: %effort%
echo.
REM FFmpeg command with parameter explanations:
REM -ss: Seek to start time (skip beginning)
REM -i: Input video file
REM -t: Duration in seconds to process
REM -vf "scale=-2:360": Video filter - scale to 360p height, auto width (even)
REM -c:v libsvtav1: Video codec - SVT-AV1 encoder
REM -crf: Quality 0-63 (lower=better quality, higher=smaller file)
REM -preset: Effort 0-12 (lower=slower encoding/better compression)
REM -an: Remove all audio streams
REM -loop 0: Infinite loop for AVIF animation
REM -y: Overwrite output file without prompting
echo ^> ffmpeg -ss "%start_time%" -i "%input%" -t "%duration%" -vf "scale=-2:%RESOLUTION%" -c:v libsvtav1 -crf %quality% -preset %effort% -an -loop 0 "%output%" -y
ffmpeg -ss "%start_time%" -i "%input%" -t "%duration%" -vf "scale=-2:%RESOLUTION%" -c:v libsvtav1 -crf %quality% -preset %effort% -an -loop 0 "%output%" -y
REM Check if output file was created
if not exist "%output%" (
echo ERROR: Failed to create output file!
pause
exit /b 1
)
REM File exists, check size
for %%A in ("%output%") do set "filesize=%%~zA"
set /a filesizeKB=!filesize!/1024
echo.
echo File created: %output%
echo File size: !filesizeKB! KB
REM Check if file is too large
if !filesize! gtr 1000000 (
echo.
echo WARNING: File size exceeds 1000 KB!
echo Images over 1MB can't be used as topic previews
echo.
set /a suggested_quality=%quality%+10
if !suggested_quality! gtr 63 set suggested_quality=63
echo Suggestions to reduce file size:
echo - Increase quality value ^(current: %quality%, try e.g. !suggested_quality!^)
echo - Reduce duration ^(current: %duration%s, try shorter clips^)
) else (
echo File size is acceptable for use as topic preview.
)
pause
goto :eof
:show_usage
echo Usage: %~nx0 ^<input_video_file^> ^<start_time^> ^<duration^> [quality] [effort]
echo Example: %~nx0 "Big Buck Bunny.mp4" 00:00:30 20
echo Example: %~nx0 "Big Buck Bunny.mp4" 00:00:30 20 50 (lower quality)
echo Quality: 0-63 (lower=better, default=%DEFAULT_QUALITY%)
echo Effort: 0-12 (lower=slower/better, default=%DEFAULT_EFFORT%)
pause
exit /b 1
If you are not on Windows or don’t like running bat files, just run the exactly same ffmpeg command
Cool so this can created moving images for under 1mb. Nice, but my god, this looks very advanced. Any chance it can be dumbed down a bit. Or point me some where to learn.
I tried command prompt:
ffmpeg -ss “00:00:30” -i “name of video and .mp4” -t “20” -vf “scale=-2:360” -c:v libsvtav1 -crf 40 -preset 8 -an -loop 0 “name of video again.avif” -y
Error
‘ffmpeg’ is not recognized as an internal or external command,
Hello, sorry to be a pain. I’m really keen to get this to work. I followed a youtube vidoe to install command prompt winget install ffmpeg. So I think that is done.
I took that bat script put into note pad and saved it in the same folder as the video.
I run command prompt it runs
C:\Users\kelvi\Documents>GIF Usage: Gif.bat [quality] [effort] Example: Gif.bat “Big Buck Bunny.mp4” 00:00:30 20 Example: Gif.bat “Big Buck Bunny.mp4” 00:00:30 20 50 (lower quality) Quality: 0-63 (lower=better, default=40) Effort: 0-12 (lower=slower/better, default=8) Press any key to continue . . .
‘’Place it together with ffmpeg.exe and the video and run’’
This bit I’m not getting. How does one place together ffmpeg and video.
Do I need to edit the last part of the bat script in note pad to get the conversion done?
I mostly use my Macbook or Linux to do ffmpeg related things, I also like to batch create multiple files after cutting up the parts. Here’s the bash script I use to do that based off the above parameters.
Thank you chatGPT.
generatePreviews.sh
#!/bin/bash
set -e
# --- Default values ---
RESOLUTION=360
DEFAULT_QUALITY=40
DEFAULT_EFFORT=8
DEFAULT_START="00:00:00"
DEFAULT_DURATION=10
# --- Input directory ---
INPUT_DIR="${1:-.}"
OUTPUT_DIR="$INPUT_DIR/previews"
mkdir -p "$OUTPUT_DIR"
echo "Generating previews for videos in: $INPUT_DIR"
echo "Output folder: $OUTPUT_DIR"
echo
# --- Supported extensions ---
shopt -s nullglob nocaseglob
VIDEO_EXTS=("*.mp4" "*.mkv" "*.mov" "*.avi" "*.webm" "*.av1")
# --- Loop through all video files ---
for pattern in "${VIDEO_EXTS[@]}"; do
for file in "$INPUT_DIR"/$pattern; do
[ -e "$file" ] || continue
filename="$(basename "$file")"
base="${filename%.*}"
output="$OUTPUT_DIR/${base}-${RESOLUTION}p.avif"
echo "Processing: $filename"
echo " → Output: $(basename "$output")"
echo " Resolution: ${RESOLUTION}p | Quality: ${DEFAULT_QUALITY} | Effort: ${DEFAULT_EFFORT}"
echo
ffmpeg -hide_banner -loglevel error \
-ss "$DEFAULT_START" -i "$file" -t "$DEFAULT_DURATION" \
-vf "scale=-2:${RESOLUTION}" \
-c:v libsvtav1 -crf "$DEFAULT_QUALITY" -preset "$DEFAULT_EFFORT" \
-an -loop 0 "$output" -y
if [ ! -f "$output" ]; then
echo "Failed to create preview for: $filename"
echo
continue
fi
filesize_bytes=$(stat -f%z "$output" 2>/dev/null || stat -c%s "$output")
filesize_kb=$((filesize_bytes / 1024))
if [ "$filesize_bytes" -gt 1000000 ]; then
echo "Preview too large (${filesize_kb} KB) — consider lowering quality or duration."
else
echo "Preview created (${filesize_kb} KB)"
fi
echo
done
done
echo "All previews saved in: $OUTPUT_DIR"
The script takes an argument of a folder where you want to create previews. If I have {Preview1.mov, Preview2.mp4, Preview3.mp4} in /Volumes/path/to/videos, then running