86 lines
2.5 KiB
Python
Executable File
86 lines
2.5 KiB
Python
Executable File
#! /usr/bin/env python3
|
|
import argparse
|
|
import sys
|
|
import logging
|
|
import subprocess
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def main() -> int:
|
|
# Handle program arguments
|
|
ap = argparse.ArgumentParser(
|
|
prog="blink-timelapse",
|
|
description="Generates timelapses from blink image captures",
|
|
)
|
|
ap.add_argument("--camera-id", help="Camera ID", default="155295")
|
|
ap.add_argument("--image-dir", help="Image directory", default="~/Pictures/blink")
|
|
ap.add_argument(
|
|
"--output-dir", help="Output directory", default="~/Videos/BlinkTimelapse"
|
|
)
|
|
ap.add_argument(
|
|
"--delete-frames", help="Delete frames after processing", action="store_true"
|
|
)
|
|
ap.add_argument("--frame-rate", help="Frame rate", default="5")
|
|
ap.add_argument(
|
|
"-v", "--verbose", help="Enable verbose logging", action="store_true"
|
|
)
|
|
args = ap.parse_args()
|
|
|
|
# Configure logging
|
|
logging.basicConfig(
|
|
level=logging.DEBUG if args.verbose else logging.INFO,
|
|
format="%(levelname)s: %(message)s",
|
|
)
|
|
|
|
# Find all frames
|
|
image_dir = Path(args.image_dir).expanduser()
|
|
frames = image_dir.glob(f"camera_{args.camera_id}.*.jpg")
|
|
frames = sorted(frames, key=lambda frame: frame.stat().st_mtime)
|
|
logger.info(f"Found {len(frames)} frames")
|
|
logger.info(
|
|
f"Oldest frame is from: {datetime.fromtimestamp(frames[0].stat().st_mtime)}"
|
|
)
|
|
logger.info(
|
|
f"Newest frame is from: {datetime.fromtimestamp(frames[-1].stat().st_mtime)}"
|
|
)
|
|
|
|
# Create output directory
|
|
output_dir = Path(args.output_dir).expanduser()
|
|
output_file = output_dir / f"camera_{args.camera_id}.{datetime.now().strftime('%Y%m%d-%H%M%S')}.mp4"
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Generate timelapse
|
|
logger.info(f"Generating timelapse: {output_file}")
|
|
subprocess.run(
|
|
[
|
|
"ffmpeg",
|
|
"-r",
|
|
args.frame_rate,
|
|
"-pattern_type",
|
|
"glob",
|
|
"-i",
|
|
f"{str(image_dir)}/camera_{args.camera_id}.*.jpg",
|
|
"-c:v",
|
|
"libx264",
|
|
"-pix_fmt",
|
|
"yuv420p",
|
|
str(output_file),
|
|
],
|
|
check=True,
|
|
)
|
|
|
|
# Delete frames if needed
|
|
if args.delete_frames:
|
|
logger.info("Deleting frames")
|
|
for frame in frames:
|
|
frame.unlink()
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|