Last active
June 15, 2025 21:42
-
-
Save aschmelyun/d6a90f136e56cd4371404c2313628dad to your computer and use it in GitHub Desktop.
Dashcam ffmpeg timelapse script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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