Dashcams create a new video file at every n minutes (for valid reasons). But I want to archive some of my trips and prefer to do it with one video file per trip (or “drive”).

A drive is a group of files that created within n minutes. If we merge these group of files, we have a single video of that drive.

Here is a primitive Powershell script that just does this.

param(
    [string]$targetFolder,
    [int]$timegap = 5
)

function Generate-Filename {
    param ([datetime]$previousFileDate, [datetime]$firstDate, [bool]$isRO)

    $outFilename = $null

    if ( ($previousFileDate.Date - $firstDate.Date).Days -gt 0 ) {
        $outFilename = "$($firstDate.ToString("dd.MM.yyyy HH.mm.ss")) - $($previousFileDate.ToString("dd.MM.yyyy HH.mm.ss"))"
    }
    else {
        $outFilename = "$($firstDate.ToString("dd.MM.yyyy HH.mm.ss")) - $($previousFileDate.ToString("HH.mm.ss"))"
    }

    if ($isRO) {
        $outFilename += " [RO]"
    }                

    return $outFilename
}

# Get all files in the folder, ordered by filename (ascending)
$files = Get-ChildItem -Path $targetFolder -Recurse -File | Sort-Object
    
# Initialize variables
$firstDate = $null
$isRO = $false
$outFilename = $null
$previousFile = $null
$driveCollection = @()
$collectionNumber = 1
$outputFolder = "E:\MergedVideos\"

New-Item -ItemType Directory -Force -Path $outputFolder
    
foreach ($file in $files) {
    $fileDate = [datetime]::ParseExact(($file.Name -replace '_.*$'), "yyyyMMddHHmmss", $null)

    if (!$firstDate) {
        $firstDate = $fileDate;
    }

    if ($file.DirectoryName.EndsWith("\RO")) {
        $isRO = $true
    }

    if ($previousFile) {
        # Calculate the time difference in minutes between the current and previous file
        $previousFileDate = [datetime]::ParseExact(($previousFile.Name -replace '_.*$'), "yyyyMMddHHmmss", $null);
        $timeDifference = ($fileDate - $previousFileDate).TotalMinutes

        # If the time difference is more than $timegap minutes, start a new drive collection
        if ($timeDifference -gt $timegap) {
            # Finalize the current drive collection (if not empty)
            if ($driveCollection.Count -gt 0) {
                Write-Output "Drive $collectionNumber - timediff was $timeDifference - file count: $($driveCollection.Count) - First Date: $($firstDate) - Last Date: $($previousFileDate)"

                $outFilename = Generate-Filename $previousFileDate $firstDate $isRO

                $driveCollection.FullName

                cmd /c copy /b "$($driveCollection.FullName -join "+")" "$($outputFolder)$($outFilename).ts"
                Write-Output "==>" "$($outputFolder)$($outFilename).ts"

                $collectionNumber++
            }
            # Start a new drive collection
            $driveCollection = @()
            $firstDate = $fileDate
            $isRO = $false
        }
    }
    
    # Add the current file with its creation time to the current drive collection
    $driveCollection += $file
    
    # Set the current file as the previous file for the next iteration
    $previousFile = $file
}
    
# Add the last drive collection
if ($driveCollection.Count -gt 0) {
    Write-Output "Final Drive $collectionNumber"

    $outFilename = Generate-Filename $previousFileDate $firstDate $isRO

    $driveCollection.FullName

    cmd /c copy /b "$($driveCollection.FullName -join "+")" "$($outputFolder)$($outFilename).ts"
    Write-Output "==>" "$($outputFolder)$($outFilename).ts"
}

Usage

Copy the script to your computer.

script.ps1 DCIMFolderFromDashcam MinuteThreshold

DCIMFolderFromDashcam: Path to your DCIM folder in your dashcam MicroSD card.
MinuteThreshold: Should be more than or equal to “Loop Recording” setting on your dashcam. When your “loop recording” is 3 minutes and MinuteThreshold is 13, it will allow up to 10 minutes of non-recording (parking, etc.) in the same drive.

Features

  • Merges files named 20240829153704_007344.TS and 20240829154004_007345.TS to 29.08.2024 15.37.04 - 15.40.04.ts
  • It will use the filename for date/time, not the created by/modified by attribute. (because if a video moved to RO folder by the camera, these attributes are changed to the date of move, thus being useless)
  • If the video file in RO folder, it’ll append [RO] to the merged filename. (RO - read only - camera will move segments of recordings to the RO folder if you trigger with G-sensor etc. (crash) or you press the ! button when driving - camera will not delete files in RO folder)

Notes

  • I prefer TS (transport stream) format for its simplicity and reliability. It also allows to simply binary concenate the files for merging videos - with MP4 you’ll need something that understands video files such as ffmpeg.
  • I use Viofo A119 V3, file/folder name format is adjusted for it. Feel free to adapt for yours.