#!/bin/bash # Script to check all WebM files with alpha for empty start and end frames # Uses libvpx-vp9 decoder to properly handle alpha channels # Check if directory parameter is provided if [ $# -eq 0 ]; then echo "Usage: sh check_webm_alpha_frames.sh " echo "Example: sh check_webm_alpha_frames.sh /Users/charlesteh/Desktop/mag-group-1/" exit 1 fi # Get the target directory from parameter target_dir="$1" # Check if directory exists if [ ! -d "$target_dir" ]; then echo "Error: Directory '$target_dir' does not exist" exit 1 fi echo "Checking all WebM files in '$target_dir' for empty start and end frames..." # Check if ffmpeg is installed if ! command -v ffmpeg &> /dev/null; then echo "Error: ffmpeg is not installed or not in PATH" exit 1 fi # Change to target directory cd "$target_dir" || { echo "Error: Cannot access directory '$target_dir'" exit 1 } # Count total WebM files webm_count=$(ls *.webm 2>/dev/null | wc -l) if [ $webm_count -eq 0 ]; then echo "No WebM files found in current directory" exit 0 fi echo "Found $webm_count WebM file(s) to check" echo "" # Create temporary directory for frame extraction temp_dir=$(mktemp -d) trap "rm -rf $temp_dir" EXIT # Function to check if a frame is empty (fully transparent) check_frame_empty() { local frame_file="$1" local frame_name="$2" # Check if frame file exists if [ ! -f "$frame_file" ]; then echo " ✗ $frame_name: Frame file not found" return 2 # unclear/error fi # Get file size - very small files are likely empty/transparent file_size=$(stat -f%z "$frame_file" 2>/dev/null || stat -c%s "$frame_file" 2>/dev/null) # If file is very small (less than 2KB), likely empty if [ -n "$file_size" ] && [ "$file_size" -lt 2048 ]; then echo " ✗ $frame_name: EMPTY (tiny file: ${file_size} bytes)" return 0 # definitely empty fi # Use simpler alpha analysis: extract alpha channel and get histogram alpha_info=$(ffmpeg -i "$frame_file" -vf "extractplanes=a" -f null - 2>&1 | grep "mean\|avg") if [ -n "$alpha_info" ]; then # Look for mean value in the output alpha_mean=$(echo "$alpha_info" | grep -o "mean:[0-9.]*" | cut -d: -f2 | head -1) if [ -n "$alpha_mean" ]; then # Check if mean is very low (close to 0 = transparent) is_empty=$(awk "BEGIN {print ($alpha_mean < 2.0) ? 1 : 0}") if [ "$is_empty" = "1" ]; then echo " ✗ $frame_name: EMPTY (alpha mean: $alpha_mean)" return 0 # definitely empty else echo " ✓ $frame_name: Content detected (alpha mean: $alpha_mean)" return 1 # definitely has content fi fi fi # If file is reasonably large, assume it has content if [ "$file_size" -gt 50000 ]; then echo " ✓ $frame_name: Content detected (large file: ${file_size} bytes)" return 1 # definitely has content else echo " ? $frame_name: UNCLEAR - needs manual review (size: ${file_size} bytes)" return 2 # unclear/unsure fi } # Function to get video duration and frame count get_video_info() { local video_file="$1" # Get duration in seconds duration=$(ffprobe -vcodec libvpx-vp9 -v quiet -show_entries format=duration -of csv=p=0 "$video_file" 2>/dev/null) # Get total frame count frame_count=$(ffprobe -vcodec libvpx-vp9 -v quiet -select_streams v:0 -count_frames -show_entries stream=nb_read_frames -csv=p=0 "$video_file" 2>/dev/null) echo "$duration $frame_count" } # Counter for progress count=0 files_with_empty_frames=0 files_with_unclear_frames=0 # Arrays to track files with empty frames files_with_empty_first=() files_with_empty_last=() files_with_both_empty=() # Arrays to track files with unclear frames files_with_unclear_first=() files_with_unclear_last=() files_with_both_unclear=() files_with_mixed_issues=() # Loop through all WebM files in current directory for webm_file in *.webm; do # Check if file actually exists (in case glob doesn't match) if [ ! -f "$webm_file" ]; then continue fi # Increment counter count=$((count + 1)) echo "[$count/$webm_count] Checking: $webm_file" # Test if file is readable by ffprobe if ! ffprobe -v quiet "$webm_file" >/dev/null 2>&1; then echo " ✗ Error: File cannot be read by ffprobe" echo "" continue fi # Detect codec type (VP8 or VP9) to use correct decoder - from working script CODEC_INFO=$(ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 "$webm_file" 2>/dev/null) # Set appropriate decoder based on codec if [ "$CODEC_INFO" = "vp9" ]; then DECODER="libvpx-vp9" echo " → Using VP9 decoder" else DECODER="libvpx" # Default to VP8 decoder echo " → Using VP8 decoder" fi # Get video info - use direct commands duration=$(ffprobe -v quiet -show_entries format=duration -of csv=p=0 "$webm_file" 2>/dev/null) frame_count=$(ffprobe -v quiet -select_streams v:0 -count_frames -show_entries stream=nb_read_frames -of csv=p=0 "$webm_file" 2>/dev/null) if [ -z "$duration" ] || [ "$duration" = "N/A" ]; then echo " ✗ Error: Could not get video duration" echo "" continue fi echo " Duration: ${duration}s, Frames: $frame_count" # Extract first frame (at 0 seconds) - using proper decoder syntax from working script first_frame="$temp_dir/first_frame_${count}.png" ffmpeg -c:v "$DECODER" -i "$webm_file" -vf "select=eq(n\,0)" -frames:v 1 -y "$first_frame" -v quiet 2>/dev/null # Extract last frame - using proper decoder syntax last_frame="$temp_dir/last_frame_${count}.png" # Calculate time for last frame (duration - small offset to ensure we get the last frame) last_frame_time=$(awk "BEGIN {printf \"%.3f\", $duration - 0.1}") # Ensure we don't go before 0 if [ $(awk "BEGIN {print ($last_frame_time < 0) ? 1 : 0}") = "1" ]; then last_frame_time="0" fi ffmpeg -c:v "$DECODER" -ss "$last_frame_time" -i "$webm_file" -frames:v 1 -y "$last_frame" -v quiet 2>/dev/null # Check if frame extraction was successful if [ ! -f "$first_frame" ] || [ ! -f "$last_frame" ]; then echo " ✗ Error: Could not extract frames" echo "" continue fi # Check if frames are empty has_empty_frames=false has_unclear_frames=false has_empty_first=false has_empty_last=false has_unclear_first=false has_unclear_last=false check_frame_empty "$first_frame" "First frame" first_result=$? if [ $first_result -eq 0 ]; then has_empty_first=true has_empty_frames=true elif [ $first_result -eq 2 ]; then has_unclear_first=true has_unclear_frames=true fi check_frame_empty "$last_frame" "Last frame" last_result=$? if [ $last_result -eq 0 ]; then has_empty_last=true has_empty_frames=true elif [ $last_result -eq 2 ]; then has_unclear_last=true has_unclear_frames=true fi # Add to tracking arrays if [ "$has_empty_first" = true ] && [ "$has_empty_last" = true ]; then files_with_both_empty+=("$webm_file") elif [ "$has_unclear_first" = true ] && [ "$has_unclear_last" = true ]; then files_with_both_unclear+=("$webm_file") elif ([ "$has_empty_first" = true ] && [ "$has_unclear_last" = true ]) || ([ "$has_unclear_first" = true ] && [ "$has_empty_last" = true ]); then files_with_mixed_issues+=("$webm_file") elif [ "$has_empty_first" = true ]; then files_with_empty_first+=("$webm_file") elif [ "$has_empty_last" = true ]; then files_with_empty_last+=("$webm_file") elif [ "$has_unclear_first" = true ]; then files_with_unclear_first+=("$webm_file") elif [ "$has_unclear_last" = true ]; then files_with_unclear_last+=("$webm_file") fi if [ "$has_empty_frames" = true ]; then files_with_empty_frames=$((files_with_empty_frames + 1)) fi if [ "$has_unclear_frames" = true ]; then files_with_unclear_frames=$((files_with_unclear_frames + 1)) fi # Clean up temporary frames rm -f "$first_frame" "$last_frame" if [ "$has_empty_frames" = true ]; then echo " ⚠️ WARNING: This file has empty frames!" elif [ "$has_unclear_frames" = true ]; then echo " ❓ NOTE: This file has unclear frames that need manual review" fi echo "" done echo "===================================" echo "Analysis complete!" echo "Total files checked: $count" echo "Files with empty start/end frames: $files_with_empty_frames" echo "Files with unclear frames (need review): $files_with_unclear_frames" total_issues=$((files_with_empty_frames + files_with_unclear_frames)) if [ $total_issues -gt 0 ]; then echo "" echo "===================================" echo "DETAILED SUMMARY - FILES NEEDING ATTENTION:" echo "===================================" # Files with both first and last frames empty if [ ${#files_with_both_empty[@]} -gt 0 ]; then echo "" echo "🚨 Files with BOTH first AND last frames EMPTY (${#files_with_both_empty[@]} files):" for file in "${files_with_both_empty[@]}"; do echo " • $(basename "$file")" done fi # Files with only first frame empty if [ ${#files_with_empty_first[@]} -gt 0 ]; then echo "" echo "⚠️ Files with FIRST frame EMPTY (${#files_with_empty_first[@]} files):" for file in "${files_with_empty_first[@]}"; do echo " • $(basename "$file")" done fi # Files with only last frame empty if [ ${#files_with_empty_last[@]} -gt 0 ]; then echo "" echo "⚠️ Files with LAST frame EMPTY (${#files_with_empty_last[@]} files):" for file in "${files_with_empty_last[@]}"; do echo " • $(basename "$file")" done fi # Files with both first and last frames unclear if [ ${#files_with_both_unclear[@]} -gt 0 ]; then echo "" echo "❓ Files with BOTH first AND last frames UNCLEAR (${#files_with_both_unclear[@]} files):" for file in "${files_with_both_unclear[@]}"; do echo " • $(basename "$file")" done fi # Files with only first frame unclear if [ ${#files_with_unclear_first[@]} -gt 0 ]; then echo "" echo "❓ Files with FIRST frame UNCLEAR (${#files_with_unclear_first[@]} files):" for file in "${files_with_unclear_first[@]}"; do echo " • $(basename "$file")" done fi # Files with only last frame unclear if [ ${#files_with_unclear_last[@]} -gt 0 ]; then echo "" echo "❓ Files with LAST frame UNCLEAR (${#files_with_unclear_last[@]} files):" for file in "${files_with_unclear_last[@]}"; do echo " • $(basename "$file")" done fi # Files with mixed issues if [ ${#files_with_mixed_issues[@]} -gt 0 ]; then echo "" echo "🔀 Files with MIXED issues (empty + unclear frames) (${#files_with_mixed_issues[@]} files):" for file in "${files_with_mixed_issues[@]}"; do echo " • $(basename "$file")" done fi echo "" echo "===================================" echo "RECOMMENDATIONS:" echo "🚨 EMPTY frames: Definitely need trimming with ffmpeg" echo "❓ UNCLEAR frames: Manually review these files" echo "• Files with both empty first/last frames may be completely problematic" echo "• Consider using ffmpeg to trim empty frames where confirmed" else echo "" echo "✅ All files appear to have clear content in start and end frames." fi