2

I'm trying to convert a few thousand home videos to a smaller format. However, encoding the video changed the created and modified timestamp to today's date. I wrote a powershell script that successfully (somehow) worked by writing the original file's modified timestamp to the new file.

However, I couldn't find a way in powershell to modify the "Media created" timestamp in the file's details properties. Is there a way to add a routine that would either copy all of the metadata from the original file, or at least set the "media created" field to the modified date?

When I searched for file attributes, it looks like the only options are archive, hidden, etc. Attached is the powershell script that I made (please don't laugh too hard, haha). Thank you

$filepath1 = 'E:\ConvertedMedia\Ingest\'                         # directory with incorrect modified & create date
$filepath2 = "F:\Backup Photos 2020 and DATA\Data\Photos\Photos 2021\2021 Part1\Panasonic 3-2-21\A016\PRIVATE\PANA_GRP\001RAQAM\"           # directory with correct date and same file name (except extension)                                                                
$destinationCodec = "*.mp4"                                      # Keep * in front of extension
$sourceCodec = ".mov"                                            
Get-ChildItem $filepath1 -File $destinationCodec | Foreach-Object {          # change *.mp4 to the extension of the newly encoded files with the wrong date  
    $fileName = $_.Name                                          # sets fileName variable (with extension)
    $fileName                                                    # Optional used during testing- sends the file name to the console
    $fileNameB = $_.BaseName                                     # sets fileNameB variable to the filename without extension
    $filename2 = "$filepath2" + "$fileNameB" + "$sourceCodec"    # assembles filepath for source
    $correctTime = (Get-Item $filename2).lastwritetime           # used for testing - just shows the correct time in the output, can comment out
    $correctTime                                                 # prints the correct time
    $_.lastwritetime = (Get-Item $filename2).lastwritetime       # modifies lastwritetime of filepath1 to match filepath2
    $_.creationTime = (Get-Item $filename2).lastwritetime        # modifies creation times to match lastwritetime (comment out if you need creation time to be the same)
    }

Update:

I think I need to use Shell.Application, but I'm getting an error message "duplicate keys ' ' are not allowed in hash literals" and am not sure how to incorporate it into the original script.

I only need the "date modified" attribute to be the same as "lastwritetime." The other fields were added just for testing. I appreciate your help!

$tags = "people; snow; weather"
$cameraModel = "AG-CX10"
$cameraMaker = "Panasonic"
$mediaCreated = "2/‎16/‎1999 ‏‎5:01 PM"


$com = (New-Object -ComObject Shell.Application).NameSpace('C:\Users\philip\Videos') #Not sure how to specify file type
$com.Items() | ForEach-Object {
    New-Object -TypeName PSCustomObject -Property @{
        Name = $com.GetDetailsOf($_,0)                  # lists current extended properties
        Tags = $com.GetDetailsOf($_,18)
        CameraModel = $com.GetDetailsOf($_,30)
        CameraMaker = $com.GetDetailsOf($_,32)
        MediaCreated = $com.GetDetailsOf($_,208)

        $com.GetDetailsOf($_,18) = $tags               # sets extended properties
        $com.GetDetailsOf($_,30) = $cameraModel
        $com.GetDetailsOf($_,32) = $cameraMaker
        $com.GetDetailsOf($_,32) = $mediaCreated
        
    }
} 

Script Example File Properties Window

SprintUser
  • 23
  • 4
  • Have you tried `Set-ItemProperty`? – zett42 Mar 12 '21 at 09:51
  • 1
    Thank you @zett42 for your help. When I run `Get-ItemProperty C:\Temp\video1.MOV | Format-List` it shows more fields but I didn't find the extended attributes, camera model, Media created, etc.
    While searching Set-ItemProperty I came across this post. https://stackoverflow.com/questions/9420055/enumerate-file-properties-in-powershell
    I think I need to use something with "shell.application" I'm going to try to add a section to the above code that will 1) copy the "Media created" date and 2) manually add camera model.
    – SprintUser Mar 12 '21 at 13:15
  • Duplicate key error is probably because the last line should be `GetDetailsOf($_,208)` not `GetDetailsOf($_,32)` – MisterSmith Mar 12 '21 at 19:49
  • Thank you @MisterSmith for catching that! After correcting that it worked, but then gave the error once I uncommented the part of the script to set extended properties. Once I invoke -ComObject, does that temporarily take me out of powershell land? – SprintUser Mar 13 '21 at 16:18
  • *in Powershell, I would expect this line not to work "Name = $com..." instead of "$Name = $com..." – SprintUser Mar 13 '21 at 16:30

1 Answers1

1

I think your best option is to drive an external tool/library from Powershell rather than using the shell (not sure you can actually set values this way tbh).

Its definitely possible to use FFMpeg to set the Media Created metadata of a file like this:

ffmpeg -i input.MOV -metadata creation_time=2000-01-01T00:00:00.0000000+00:00 -codec copy output.MOV

This would copy input.MOV file to new file output.MOV and set the Media Created metadata on the new output.MOV. This is very inefficient - but it does work.

You can script ffmpeg something like the below. The script will currently output the FFMpeg commands to the screen, the commented out Start-Process line can be used to execute ffmpeg.

gci | where Extension -eq ".mov" | foreach {

    $InputFilename = $_.FullName;
    $OutputFilename = "$($InputFilename)-fixed.mov";

    Write-Host "Reading $($_.Name). Created: $($_.CreationTime). Modifed: $($_.LastWriteTime)";

    $timestamp = Get-Date -Date $_.CreationTime -Format O
            
    Write-Host "ffmpeg -i $InputFilename -metadata creation_time=$timestamp -codec copy $OutputFilename"

    # Start-Process -Wait -FilePath C:\ffmpeg\bin\ffmpeg.exe -ArgumentList @("-i $InputFilename -metadata creation_time=$timestamp -codec copy $($OutputFilename)")   
}
MisterSmith
  • 2,884
  • 1
  • 10
  • 13
  • Thank you for taking the time to give a nice example @MisterSmith, that's exactly what I needed. I hadn't thought about using ffmpeg (was using Adobe Media Encoder), but it looks like it'll save time with getting the files ready for encoding while also writing the correct metadata. I'll make a few changes and share my updated script. Thanks again! – SprintUser Mar 14 '21 at 07:02
  • I found something called "TagLibSharp.dll" that might also have worked to change part of the metadata (instead of trying to use GetDetailsOf which didn't work). Since I plan on encoding my footage again with ffmpeg, I don't see a need to use it though. https://stackoverflow.com/questions/48906243/update-a-song-metadata-with-taglib-sharp-and-powershell – SprintUser Mar 14 '21 at 07:15