Skip to content

Instantly share code, notes, and snippets.

@rajeshpachaikani
Created May 26, 2025 05:14
Show Gist options
  • Save rajeshpachaikani/ab566ca5e9aefe6a45aff52500ed6e44 to your computer and use it in GitHub Desktop.
Save rajeshpachaikani/ab566ca5e9aefe6a45aff52500ed6e44 to your computer and use it in GitHub Desktop.
Bash Script for creating videos with FFMPEG, ImageMagick and gTTS
#!/bin/bash
# Check if the right number of arguments were passed
if [ $# -ne 6 ]; then
echo "Usage: $0 \"primary_text\" \"secondary_text\" "KURAL_ENN" "Athigaram" input_image.png output.mp4"
echo "Example: $0 "இருள்சேர் இருவினையும் சேரா இறைவன்\nபொருள்சேர் புகழ்புரிந்தார் மாட்டு" "கடவுளின் மெய்மைப் புகழையே விரும்புபவரிடம் அறியாமை இருளால் வரும் நல்வினை தீவினை என்னும் இரண்டும் சேருவதில்லை" "5" "கடவுள் வாழ்த்து" bg.png kural5.mp4"
exit 1
fi
# Assign arguments to variables
PRIMARY_TEXT="$1"
SECONDARY_TEXT="$2"
KURAL_ENN="குறள்: $3"
ATH_ENN="அதிகாரம்: $4"
INPUT_IMAGE="$5"
OUTPUT_VIDEO="$6"
FONT="Samyak-Tamil"
# Check if input image exists
if [ ! -f "$INPUT_IMAGE" ]; then
echo "Error: Input image $INPUT_IMAGE does not exist."
exit 1
fi
# Generate TTS audio using gTTS from SECONDARY_TEXT
AUDIO_FILE=$(mktemp --suffix=.mp3)
echo "Generating audio..."
gtts-cli "$SECONDARY_TEXT" --lang ta --output "$AUDIO_FILE"
# Get duration of audio in seconds
DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$AUDIO_FILE")
DURATION=${DURATION%.*} # convert to integer
DURATION=$((DURATION + 1))
if [ -z "$DURATION" ]; then
echo "Error: Could not determine audio duration."
rm "$TEMP_IMAGE" "$AUDIO_FILE"
exit 1
fi
# Get image dimensions
WIDTH=$(identify -format "%w" "$INPUT_IMAGE" 2>/dev/null)
HEIGHT=$(identify -format "%h" "$INPUT_IMAGE" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "Error: Could not get dimensions of $INPUT_IMAGE. Is ImageMagick installed?"
echo "Install with: sudo apt-get install imagemagick"
exit 1
fi
echo "Creating image with overlaid texts..."
# Create temporary image file
TEMP_IMAGE=$(mktemp --suffix=.png)
# Calculate a suitable text width based on image width (you might need to adjust this)
TEXT_WIDTH=$(( WIDTH * 80 / 100 ))
# Create base composite with primary text using Pango and wrapping within geometry
convert "$INPUT_IMAGE" \
\( -background none -font $FONT -pointsize 32 \
-fill white -stroke black -strokewidth 4 \
-undercolor "rgba(1,0,0,0.1)" \
-size "${TEXT_WIDTH}x" pango:"$PRIMARY_TEXT" \) \
-gravity north -geometry +0+200 -composite "$TEMP_IMAGE"
# Add secondary text with Pango and wrapping within geometry
convert "$TEMP_IMAGE" \
\( -background none -font $FONT -pointsize 32 \
-fill white -stroke black -strokewidth 4 \
-undercolor "rgba(1,0,0,0.1)" \
-size "${TEXT_WIDTH}x" pango:"$SECONDARY_TEXT" \) \
-gravity center -geometry +0-40 -composite "$TEMP_IMAGE"
convert "$TEMP_IMAGE" \
\( -background none -font $FONT -pointsize 32 \
-fill white -stroke black -strokewidth 4 \
-undercolor "rgba(1,0,0,0.1)" \
-size "${TEXT_WIDTH}x" pango:"பொருள்:" \) \
-gravity center -geometry +0-190 -composite "$TEMP_IMAGE"
convert "$TEMP_IMAGE" \
\( -background none -font $FONT -pointsize 32 \
-fill white -stroke black -strokewidth 4 \
-undercolor "rgba(1,0,0,0.1)" \
-size "${TEXT_WIDTH}x" pango:"$KURAL_ENN" \) \
-gravity north -geometry +0+20 -composite "$TEMP_IMAGE"
convert "$TEMP_IMAGE" \
\( -background none -font $FONT -pointsize 32 \
-fill white -stroke black -strokewidth 4 \
-undercolor "rgba(1,0,0,0.1)" \
-size "${TEXT_WIDTH}x" pango:"$ATH_ENN" \) \
-gravity north -geometry +0+80 -composite "$TEMP_IMAGE"
echo "Creating video from the composite image with audio..."
ffmpeg -hide_banner -y -loop 1 -i "$TEMP_IMAGE" -i "$AUDIO_FILE" \
-c:v libx264 -t "$DURATION" -pix_fmt yuv420p \
-c:a aac -b:a 192k -shortest "$OUTPUT_VIDEO"
# Check for success
if [ $? -ne 0 ]; then
echo "Error: Failed to create video with audio."
rm "$TEMP_IMAGE" "$AUDIO_FILE"
exit 1
fi
# Clean up
rm "$TEMP_IMAGE" "$AUDIO_FILE"
echo "Video successfully created: $OUTPUT_VIDEO"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment