# png2mp4_x265() # Converts a series of PNG images to an MP4 video using x265 encoding # # Usage: png2mp4_x265 [--max ] [--step ] [--repeat ] # # Options: # --max : Maximum number of images to process # --step : Multiplier for step count in overlay text (default: 1) # --repeat : Number of times to repeat each image (default: 1) # # This function: # 1. Deactivates conda environment # 2. Finds all PNG files in the current directory # 3. Uses the current directory name as the output filename prefix # 4. Uses ffmpeg to create an MP4 with x265 encoding, including: # - Frame rate of 60 fps # - Image scaling to 1024x1024 # - Step count overlay text (divided by 1,000,000 and truncated to remove 6 zeros and decimal places) # - High-quality encoding settings # 5. Adds padding and fade-out effect to the final video # 6. Reactivates conda environment # # Requirements: # - ffmpeg with libx265 support # - Inconsolata-Light.ttf font in /usr/share/fonts/TTF/ png2mp4_x265() { conda deactivate local step_multiplier=1 local repeat=1 while [[ "$#" -gt 0 ]]; do case $1 in --step) step_multiplier="$2"; shift ;; --repeat) repeat="$2"; shift ;; *) echo "Unknown parameter passed: $1"; return 1 ;; esac shift done output_filename="$(basename "$(pwd)")_x265.mp4" echo "Output filename: $output_filename" local nframes=$(find . -type f -name '*.png' | wc -l) local duration=$(($nframes * $repeat / 60.)) local fade_start=$((duration + 3)) echo "Found $nframes for a duration of $duration seconds" echo "Running ffmpeg with x265 encoding..." local font=/usr/share/fonts/TTF/Inconsolata-Light.ttf local drawtext="drawtext=fontfile=${font}:text='Steps\: %{eif\\:trunc(n*$step_multiplier)\\:u\\:3}':x=10:y=h-th-10:fontsize=24:fontcolor=white" local fadeout="tpad=stop_mode=clone:stop_duration=8,fade=t=out:st=${fade_start}:d=5" local output_preset=( -c:v libx265 -preset slower -tune animation -g $repeat -pix_fmt yuv420p -x265-params "crf=20:qcomp=0.8:aq-mode=3:aq-strength=0.8:deblock=-1,-1" ) ffmpeg -framerate "60/$repeat" -pattern_type glob -i "*.png" -r 60 -vf "scale=1024x1024,${drawtext},${fadeout}"\ -c:v ffv1 -f matroska - | ffmpeg -f matroska -i - \ -vf "$fadeout" "${output_preset[@]}" -y output.mp4 if [ $? -ne 0 ]; then echo "Error: ffmpeg command failed." return 1 fi conda activate echo "Process completed successfully." } # png2mp4() # Converts a series of PNG images to an MP4 video using x264 encoding # # Usage: png2mp4 [--max ] [--step ] [--repeat ] # # Options: # --max : Maximum number of images to process # --step : Multiplier for step count in overlay text (default: 1) # --repeat : Number of times to repeat each image (default: 1) # # This function: # 1. Deactivates conda environment # 2. Creates a temporary directory for processing # 3. Finds all PNG files in the current directory # 4. Uses the current directory name as the output filename prefix # 5. Copies and optionally repeats images to the temp directory # 6. Uses ffmpeg to create an MP4 with x264 encoding, including: # - Frame rate of 60 fps # - Image scaling to 1024x1024 # - Step count overlay text (divided by 1,000,000 and truncated to remove 6 zeros and decimal places) # - CRF value of 28 for compression # 7. Adds padding and fade-out effect to the final video # 8. Cleans up temporary files # 9. Reactivates conda environment # # Requirements: # - ffmpeg with libx264 support # - bc (basic calculator) # - Inconsolata-Light.ttf font in /usr/share/fonts/TTF/ png2mp4() { conda deactivate local max_images="" local step_multiplier=1 local repeat=1 local temp_dir="/home/kade/.local/tmp" while [[ "$#" -gt 0 ]]; do case $1 in --max) max_images="$2"; shift ;; --step) step_multiplier="$2"; shift ;; --repeat) repeat="$2"; shift ;; *) echo "Unknown parameter passed: $1"; return 1 ;; esac shift done echo "Creating temporary directory..." mkdir -p "$temp_dir" echo "Checking for PNG files..." png_files=($(/usr/bin/env ls *.png 2>/dev/null)) if [ ${#png_files[@]} -eq 0 ]; then echo "Error: No PNG files found in the current directory." return 1 fi echo "Setting output filename..." output_filename="$(basename "$(pwd)").mp4" echo "Output filename: $output_filename" echo "Creating repeated images..." for img in "${png_files[@]}"; do for i in $(seq 1 $repeat); do cp "$img" "$temp_dir/${img%.*}_${i}.png" done done echo "Running ffmpeg..." if [[ -n "$max_images" ]]; then ffmpeg -framerate 60 -pattern_type glob -i "$temp_dir/*.png" -vf "scale=1024x1024,select='not(mod(n\,$max_images))',drawtext=fontfile=/usr/share/fonts/TTF/Inconsolata-Light.ttf:text='Steps\: %{expr\:trunc(n*$step_multiplier/$repeat/1000000)}':x=10:y=h-th-10:fontsize=24:fontcolor=white" -crf 28 \ -c:v libx264 -pix_fmt yuv420p -y "$temp_dir/temp.mp4" else ffmpeg -framerate 60 -pattern_type glob -i "$temp_dir/*.png" -vf "scale=1024x1024,drawtext=fontfile=/usr/share/fonts/TTF/Inconsolata-Light.ttf:text='Steps\: %{expr\:trunc(n*$step_multiplier/$repeat/1000000)}':x=10:y=h-th-10:fontsize=24:fontcolor=white" -crf 28 \ -c:v libx264 -pix_fmt yuv420p -y "$temp_dir/temp.mp4" fi if [ $? -ne 0 ]; then echo "Error: ffmpeg command failed." rm -rf "$temp_dir" return 1 fi echo "Processing final video..." duration=$(ffmpeg -i "$temp_dir/temp.mp4" 2>&1 | grep 'Duration' | awk '{print $2}' | tr -d , | awk -F: '{print ($1 * 3600) + ($2 * 60) + $3}') fade_start=$(echo "$duration + 3" | bc) ffmpeg -i "$temp_dir/temp.mp4" -vf "tpad=stop_mode=clone:stop_duration=8,fade=t=out:st=$fade_start:d=5" -c:v libx264 -pix_fmt yuv420p -y "$output_filename" if [ $? -ne 0 ]; then echo "Error: Final ffmpeg processing failed." rm -rf "$temp_dir" return 1 fi echo "Cleaning up temporary files..." rm -rf "$temp_dir" conda activate echo "Process completed successfully." }