dashcamd v3: trip directories, state machine, graceful shutdown
Dashcam recording now organized by trip in /data/media/0/videos/YYYYMMDD-HHMMSS/. Starts recording immediately on launch (with 10-min idle timer), transitions to continuous recording when drive gear detected. New trip on every ignition cycle. Graceful shutdown via DashcamShutdown param with 15s ack timeout in thermald. - Bitrate reduced to 2500 kbps (was 4 Mbps) - Trip state machine: IDLE → RECORDING ↔ IDLE_TIMEOUT → TRIP_ENDED - Deleter: trip-aware deletion (oldest trip first, then segments within active trip) - camerad changed to always_run (was driverview) so dashcam works offroad - DashcamShutdown param for graceful close before device power-off Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -49,18 +49,51 @@ def get_preserved_segments(dirs_by_creation: list[str]) -> list[str]:
|
||||
|
||||
|
||||
def delete_oldest_video():
|
||||
"""CLEARPILOT: delete the oldest screen recording MP4 when disk space is low."""
|
||||
"""CLEARPILOT: delete oldest dashcam footage when disk space is low.
|
||||
Trip directories are /data/media/0/videos/YYYYMMDD-HHMMSS/ containing .mp4 segments.
|
||||
Deletes entire oldest trip directory first. If only one trip remains (active),
|
||||
deletes individual segments oldest-first within it. Also cleans up legacy flat .mp4 files."""
|
||||
try:
|
||||
if not os.path.isdir(VIDEOS_DIR):
|
||||
return False
|
||||
videos = sorted(
|
||||
(f for f in os.listdir(VIDEOS_DIR) if f.endswith('.mp4')),
|
||||
key=lambda f: os.path.getctime(os.path.join(VIDEOS_DIR, f))
|
||||
)
|
||||
if not videos:
|
||||
|
||||
# Collect legacy flat mp4 files and trip directories
|
||||
legacy_files = []
|
||||
trip_dirs = []
|
||||
for entry in os.listdir(VIDEOS_DIR):
|
||||
path = os.path.join(VIDEOS_DIR, entry)
|
||||
if os.path.isfile(path) and entry.endswith('.mp4'):
|
||||
legacy_files.append(entry)
|
||||
elif os.path.isdir(path):
|
||||
trip_dirs.append(entry)
|
||||
|
||||
# Delete legacy flat files first (oldest by name)
|
||||
if legacy_files:
|
||||
legacy_files.sort()
|
||||
delete_path = os.path.join(VIDEOS_DIR, legacy_files[0])
|
||||
cloudlog.info(f"deleting legacy video {delete_path}")
|
||||
os.remove(delete_path)
|
||||
return True
|
||||
|
||||
if not trip_dirs:
|
||||
return False
|
||||
delete_path = os.path.join(VIDEOS_DIR, videos[0])
|
||||
cloudlog.info(f"deleting video {delete_path}")
|
||||
|
||||
trip_dirs.sort() # sorted by timestamp name = chronological order
|
||||
|
||||
# If more than one trip, delete the oldest entire trip directory
|
||||
if len(trip_dirs) > 1:
|
||||
delete_path = os.path.join(VIDEOS_DIR, trip_dirs[0])
|
||||
cloudlog.info(f"deleting trip {delete_path}")
|
||||
shutil.rmtree(delete_path)
|
||||
return True
|
||||
|
||||
# Only one trip left (likely active) — delete oldest segment within it
|
||||
trip_path = os.path.join(VIDEOS_DIR, trip_dirs[0])
|
||||
segments = sorted(f for f in os.listdir(trip_path) if f.endswith('.mp4'))
|
||||
if not segments:
|
||||
return False
|
||||
delete_path = os.path.join(trip_path, segments[0])
|
||||
cloudlog.info(f"deleting segment {delete_path}")
|
||||
os.remove(delete_path)
|
||||
return True
|
||||
except OSError:
|
||||
|
||||
Reference in New Issue
Block a user