【问题标题】:How to Modify "Media Created" Field in File Properties via Powershell如何通过 Powershell 修改文件属性中的“媒体创建”字段
【发布时间】:2021-06-10 05:09:09
【问题描述】:

我正在尝试将几千个家庭视频转换为更小的格式。但是,对视频进行编码会将创建和修改的时间戳更改为今天的日期。我编写了一个 powershell 脚本,它通过将原始文件的修改时间戳写入新文件来成功(以某种方式)工作。

但是,我在 powershell 中找不到修改文件详细信息属性中“媒体创建”时间戳的方法。有没有办法添加一个例程来复制原始文件中的所有元数据,或者至少将“媒体创建”字段设置为修改日期?

当我搜索文件属性时,看起来唯一的选项是存档,隐藏等。附上我制作的powershell脚本(请不要笑得太厉害,哈哈)。谢谢

$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)
    }

更新:

我想我需要使用 Shell.Application,但我收到一条错误消息“哈希文字中不允许重复键 ''” 并且不知道如何将其合并到原始脚本。

我只需要“修改日期”属性与“lastwritetime”相同。添加其他字段只是为了测试。感谢您的帮助!

$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

【问题讨论】:

  • 你试过Set-ItemProperty吗?
  • 感谢@zett42 的帮助。当我运行Get-ItemProperty C:\Temp\video1.MOV | Format-List 时,它显示了更多字段,但我没有找到扩展属性、相机型号、创建的媒体等。
    在搜索 Set-ItemProperty 时,我遇到了这篇文章。 stackoverflow.com/questions/9420055/…
    我想我需要使用“shell.application”的东西我将尝试在上面的代码中添加一个部分,1)复制“媒体创建”日期和2)手动添加相机型号。
  • 重复键错误可能是因为最后一行应该是GetDetailsOf($_,208)而不是GetDetailsOf($_,32)
  • 感谢@MisterSmith 抓住了这一点!在更正它工作之后,但是一旦我取消注释脚本的一部分以设置扩展属性,就会给出错误。一旦我调用 -ComObject,这是否会暂时让我离开 powershell 领域?
  • *在 Powershell 中,我希望这条线不能工作 "Name = $com..." 而不是 "$Name = $com..."

标签: powershell file-properties


【解决方案1】:

我认为你最好的选择是从 Powershell 驱动一个外部工具/库,而不是使用 shell(不确定你是否可以通过这种方式实际设置值)。

绝对可以使用FFMpeg 来设置文件的媒体创建元数据,如下所示:

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

这会将 input.MOV 文件复制到新文件 output.MOV 并在新的 output.MOV 上设置 Media Created 元数据。这是非常低效的 - 但它确实有效。

您可以编写 ffmpeg 脚本,如下所示。该脚本当前会将FFMpeg命令输出到屏幕,注释掉的Start-Process行可用于执行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,这正是我所需要的。我没有考虑过使用 ffmpeg(当时使用的是 Adob​​e Media Encoder),但看起来它可以节省时间,让文件准备好进行编码,同时编写正确的元数据。我将进行一些更改并分享我更新的脚本。再次感谢!
  • 我发现了一个名为“TagLibSharp.dll”的东西,它可能也可以改变部分元数据(而不是尝试使用不起作用的 GetDetailsOf)。由于我计划再次使用 ffmpeg 对我的素材进行编码,因此我认为没有必要使用它。 stackoverflow.com/questions/48906243/…
猜你喜欢
  • 2021-10-19
  • 1970-01-01
  • 2017-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多