Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / PowerShell

Rename HD Video Camera Files

0.00/5 (No votes)
12 Apr 2021CPOL4 min read 3.1K  
A Powershell script to rename HD video camera files using their original creation date
Sick of sequentially named video filenames? This Powershell script will rename all 5 digit video filenames to their original date and time of creation to allow for easy sorting and cataloging.

Introduction

HD video files stored on camcorders are usually named using a 5 digit sequential filename followed by the video file extension such as MTS. The sequential filenames give no clue as to the video's content or when it was created thus making it difficult to sort and catalog the files once copied to the main computer for processing. This Powershell script will rename the files according to their original date and time of creation.

Background

My camcorder's hard drive developed a problem whereby I could not download the files to my computer. The camera's application software would simply hang on a particular file and stay frozen until I disconnected the camera and forced the app closed. This meant I could not download and then clear the hard drive ready for the next shoot. The only way to get the files off the hard drive was to manually copy the files across to my computer using Windows File Explorer.

The problem with this method is that the files are named in a sequential fashion starting at 00000.mts and incrementing by one for each subsequent video file. Using the camera's application software, the files would be copied over to the PC and renamed based on the file's original creation date and time, e.g., 20190223113432.m2ts, i.e., YYYYMMDDHHMMSS.ext format.

I needed a way to do this myself without the app and I had 1600 files to rename and thus I developed this Powershell script to do the work for me.

Using the Code

The script should be saved to a folder on the PC, e.g., D:\Scripts or C:\Utils. Someplace where you keep all your utility programs, etc.

The script can be executed from the Windows Cmd line using this syntax:

powershell ./script_path/ConvertVideoFilename.ps1 'Video_Files_Path' options

where:

  • script_path is the full path to the location of this script, and
  • Video_Files_Path is the full path to the location where the video files are located
  • options are:
    • q = quietmode, no messages, and
    • e = show error messages if in quiet mode

If no options are specified, then each file found is listed. Both options can be specified together like "qe" or "eq". The order is not important. Note the lack of a space between the options if both are specified.

Be sure to include any punctuation as shown above or the command will not work.

Here is the script:

PowerShell
# ConvertVideoFilename.ps1
#
# Author: Walter H. Kiess
#   Date: 10/04/2021
#
# Powershell script to rename sequentially numbered video files
# to the standard date/time format YYYYMMDDHHMMSS.
#
# To use this script:
#    1) Save the script to a folder on the computer, e.g. D:\Scripts
#    2) Make sure the exiftool has been downloaded and saved and the
#       toolpath below set accordingly
#    3) Open a CMD window
#    4) Change to the scripts folder
#    5) Enter command: 
#       powershell ./script_path/ConvertVideoFilename.ps1 'Video_Files_Path' options
#       where script_path is the full path to the location of this script, and
#       Video_Files_Path is the full path to the location where the video files are located
#       options are: q = quietmode, no messages, and
#                    e = show error messages if in quiet mode
#       If no options are specified then each file found is listed.
#       Be sure to include any punctuation as shown above or the command will not work.
#
# This software is provided "as is" with no implied or explicit warranties or guarantees.
# No liabilty of any kind is accepted or provided. Use this script at your own peril.
#
# Note:
# This utility uses a program called exiftool.exe to extract
# the original video file creation date from the file's meta data.
# The program can be found here: https://exiftool.org/
# Download and extract the tool from the zip file and store it
# somewhere on your computer. Make a copy and rename it to exiftool.exe.
# Set the toolpath below to its location.
$ToolPath = "F:\Downloads\Utils\exiftool-12.23\"

# Let's go!

# Check if exiftool.exe exists in the path specified
if (!(Test-Path -Path $ToolPath\exiftool.exe)){
    Write-Host "The path $($ToolPath) does not contain the tool exiftool.exe."
    Write-Host "Download the exiftool from https://exiftool.org/"
    Write-Host "follow the instructions and save exiftool.exe"
    Write-Host "somewhere on your computer, then change the toolpath"
    Write-Host "in this script to the correct location and try again."
    Exit
}
$Exe = $ToolPath + "exiftool.exe"

# Check if any parameters were specified. Need one parameter which
# is the path to the folder containing the video files
if ($args.Count -lt 1){
    Write-Host "Missing parameter: The path to the video files has not been specified."
    Exit
}

# Check the specified video files path exists
if (!(Test-Path -Path $args[0])){
    Write-Host "Invalid video files path specified. Path $($args[0]) not found."
    Exit
}
$VideoFilesPath = $args[0]

# Check for 2nd parameter. If specified and it's a "q",
# then enter quiet mode where no messages are shown
$QuietMode = $false
$ShowErrors = $true
if ($args[1] -ne $null){
    if ($args[1] -like "*q*"){
        $QuietMode = $true
        $ShowErrors = $false
    }
    if ($args[1] -like "*e*"){
        $ShowErrors = $true
    }
}
$Verbose = !($QuietMode)

# Get a list of files for the specified path
$Files = Get-ChildItem -Path $VideoFilesPath

# Loop through list and process each file
$FileCount = 0
$MissingTimeCount = 0
$RenamedCount = 0
$InvalidFilenameCount = 0
$ExistsCount = 0
foreach ($File in $Files){
    $FileCount += 1

    # Since the filename SHOULD be a valid sequential filename
    # consisting of 5 digits, split the full filename by the "."
    # to obtain just the digits and the extension
    $Name = $File.Name.Split("{.}")

    # If the filename is indeed 5 chars long, perform the rename
    if ($Name[0].Length -eq 5 -and $Name[0] -match "^\d+$"){

        # Extract the original date/time stamp from the video
        $Orig = &$Exe "$($VideoFilesPath)\$($File.Name)" | 
                Select-String -Pattern "Date/Time Original"

        # Check if a timestamp was found. If not, then use the previous file's timestamp
        # and increment the seconds by 1 as a best guess. 
        # If greater than 60, then increment minutes and so on...
        if ($Orig -eq $Null){
            $MissingTimeCount += 1
            if ($Verbose -or $ShowErrors){
                Write-host "$($File.Name) has no original timestamp, using previous + 1s"
            }
            $HH = [int]::Parse($PrevTimeHH) # Convert strings to integers for math
            $MM = [int]::Parse($PrevTimeMM)
            $SS = [int]::Parse($PrevTimeSS)
            $SS += 1                        # Increment seconds
            if ($SS -gt 59){                # Check if over 59 etc
                $SS = 0
                $MM += 1
            }
            if ($MM -gt 59){
                $MM = 0
                $HH += 1
            }
            if ($HH -gt 23){
                $HH = 0
            }
            $PrevTimeHH = "{0:D2}" -f $HH # Convert numbers back to 2 char string, e.g. 1 => 01
            $PrevTimeMM = "{0:D2}" -f $MM
            $PrevTimeSS = "{0:D2}" -f $SS
            $OrigTimeShort = $PrevTimeHH + $PrevTimeMM + $PrevTimeSS
            $OrigDateShort = $PrevOrigDateShort
        }
        else{ # If the timestamp was found 
              # then process the video file and use its original date/time

            # Extract the date and remove the ":" chars
            $OrigDate = $Orig.ToString().Substring(34,10)
            $OrigDateShort = $OrigDate.Substring(0,4) + `
                             $OrigDate.Substring(5,2) + $OrigDate.Substring(8,2)

            # Extract the time and remove the ": chars
            $OrigTime = $Orig.ToString().Substring(45,8)
            $OrigTimeHH = $OrigTime.Substring(0,2)
            $OrigTimeMM = $OrigTime.Substring(3,2)
            $OrigTimeSS = $OrigTime.Substring(6,2)
            $OrigTimeShort = $OrigTimeHH + $OrigTimeMM + $OrigTimeSS

            # Save the Original timestamp in case the next file doesn't have one
            $PrevOrigDateShort = $OrigDateShort
            $PrevTimeHH = $OrigTimeHH
            $PrevTimeMM = $OrigTimeMM
            $PrevTimeSS = $OrigTimeSS
        }

        # Create the new name from the date, time and extension
        $NewName = $OrigDateShort + $OrigTimeShort + "." + $Name[1]

        # Check if the new filename already exists
        if (Test-Path -Path $VideoFilesPath\$NewName){
            $ExistsCount += 1
            if ($Verbose -or $ShowErrors){
                Write-Host "$($NewName) already exists. Skipped"
            }
        } else {
            # Rename the file
            Rename-Item "$($VideoFilesPath)\$($File.Name)" $NewName
            $RenamedCount += 1

            if ($Verbose -or $ShowErrors){
                Write-Host "$($File.Name) renamed to $($NewName)"
            }
        }
    } else {
        $InvalidFilenameCount += 1
        if ($Verbose -or $ShowErrors){
            Write-host "$($File.Name) skipped, filename not valid 5 digit sequential filename"
        }
    }
}

Write-Host "Stats:"
Write-Host "$($FileCount) Files processed"
Write-Host "$($MissingTimeCount) Files with missing original date/time stamp"
Write-Host "$($InvalidFilenameCount) Files had an invalid filename, i.e. not 5 digits"
Write-Host "$($ExistsCount) Files already exists and were skipped"
Write-Host "$($RenamedCount) Files were renamed successfully"
Write-Host "Done."

Points of Interest

This script relies on the exiftool to do the heavy lifting. I came across this utility quite by accident and am glad I did as it saved my bacon. Check out the web page for this extremely powerful and useful program.

It took me two days to write this script with a lot of help from the internet. I don't know Powershell very well, but know it's extremely powerful. I learnt quite a bit by scouring Powershell web sites for the usage of commands and how to do things I wanted to do but had no inkling of the commandlet or syntax.

Update

I found the Powershell method of renaming the files a little slow in execution and was looking for a better way to this when I came across an internet article that also used the exiftool, but interestingly, just the tool itself to rename a whole bunch of files at once! Just what I was after. Apparently, it is much, much faster to let the tool rename all the files than to repeatedly call it to rename a single file. After digging deeper into the documentation, I learned how to do it myself. It's not as straightforward as one would think, this tool has a myriad of options allowing it to perform quite complex tasks.

The short of it is this command:

ToolPath\exiftool -r "-FileName<DateTimeOriginal" 
-d "Destination\%Y%m%d_%H%M%S%%-c.%%e" -ext * "SourcePath"

where:

  • ToolPath is the full path to the location of this script,
  • Destination is the full path to the location where the renamed files should be saved, and
  • SourcePath is the full path to the location of the files to be renamed.

Check the tool's extensive documentation for the full syntax and the many, many more options and possibilities available. I particularly like the example given to use the file's original timestamp to create subfolders for the year and month (and day), thereby distributing the files nicely into a folder tree by date.

On a personal note, I found the easiest way to use this tool is to add the ToolPath to Windows' default app search path and executing the exiftool command in the destination folder, thereby only having to specify the source path.

History

  • 10th April, 2021: Initial version
  • 16th April, 2021: Using tool on its own

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)