Skip to content

Instantly share code, notes, and snippets.

@aschmelyun
Last active June 15, 2025 21:42
Show Gist options
  • Save aschmelyun/d6a90f136e56cd4371404c2313628dad to your computer and use it in GitHub Desktop.
Save aschmelyun/d6a90f136e56cd4371404c2313628dad to your computer and use it in GitHub Desktop.
Dashcam ffmpeg timelapse script
#!/bin/bash
# Extracts frames every 3 seconds from dash cam videos and creates a timelapse
# Save this file, chmod +x ./run.sh, and then run with ./run.sh
# Configuration
INPUT_DIR="./raw_video" # Change this to your video files directory
OUTPUT_DIR="./timelapse_frames"
FINAL_VIDEO="dashcam_timelapse.mp4"
FRAME_RATE=60
RESOLUTION="1280x720"
# Create output directory for frames
mkdir -p "$OUTPUT_DIR"
echo "Starting dash cam timelapse creation..."
echo "Input directory: $INPUT_DIR"
echo "Frame extraction rate: 1 frame every 3 seconds"
echo "Final video frame rate: ${FRAME_RATE}fps"
# Counter for sequential frame numbering
frame_counter=1
# Find and sort all MP4 files
echo "Finding MP4 files..."
mp4_files=($(find "$INPUT_DIR" -name "*.mp4" -type f | sort))
if [ ${#mp4_files[@]} -eq 0 ]; then
echo "Error: No MP4 files found in $INPUT_DIR"
exit 1
fi
echo "Found ${#mp4_files[@]} MP4 files"
# Extract frames from each video
for video_file in "${mp4_files[@]}"; do
echo "Processing: $(basename "$video_file")"
# Extract frames every 3 seconds
# -vf fps=1/3 means 1 frame every 3 seconds
# %08d ensures proper ordering with zero-padding
ffmpeg -i "$video_file" \
-vf "fps=1/3,scale=$RESOLUTION:flags=lanczos" \
-pix_fmt rgb24 \
-compression_level 9 \
-q:v 8 \
"$OUTPUT_DIR/frame_$(printf "%08d" $frame_counter)_%03d.png" \
-y -loglevel warning
# Count how many frames were extracted from this video
extracted_frames=$(ls "$OUTPUT_DIR"/frame_$(printf "%08d" $frame_counter)_*.png 2>/dev/null | wc -l)
if [ $extracted_frames -gt 0 ]; then
echo " Extracted $extracted_frames frames"
# Update counter for next video (each 3-min video at 1 frame per 3 sec = ~60 frames)
frame_counter=$((frame_counter + 100)) # Leave gap for proper sorting
else
echo " Warning: No frames extracted from this video"
fi
done
# Create final timelapse video
echo "Creating final timelapse video..."
ffmpeg -framerate $FRAME_RATE \
-pattern_type glob \
-i "$OUTPUT_DIR/*.png" \
-c:v libx264 \
-pix_fmt yuv420p \
-crf 18 \
-preset medium \
"$FINAL_VIDEO" \
-y
if [ $? -eq 0 ]; then
echo "Success! Timelapse created: $FINAL_VIDEO"
echo "Video stats:"
echo " - Duration: ${duration} seconds"
echo " - Frame rate: ${FRAME_RATE}fps"
echo " - Resolution: $RESOLUTION"
# Ask if user wants to keep frame files
echo ""
read -p "Delete extracted frame files? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -rf "$OUTPUT_DIR"
echo "Frame files deleted."
else
echo "Frame files kept in: $OUTPUT_DIR"
fi
else
echo "Error: Failed to create final video"
exit 1
fi
echo "Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment