Powershell视频长度计算

Powershell video length calculation

我有一个无法解决的计算问题,感谢您的帮助!我使用以下代码在更复杂的循环上下文中接收文件的视频长度:

$movs ="..\..\MOV"
        $dura = New-Object -ComObject Shell.Application
        $dura = Get-ChildItem -Path $movs -Recurse -Force | ForEach {
            $Folder = $Shell.Namespace($_.DirectoryName)
            $File = $Folder.ParseName($_.Name)
            $Duration = $Folder.GetDetailsOf($File, 27)
            [PSCustomObject]@{
                vid-file= $_.Name -replace ".mov",""
                duration = $Duration
            }
        } 

稍后我将一些 ID 与 $dura 匹配,结果如下所示:

ID  vid-file    duration
1   move        00:01:08
1   run         00:01:12
1   fly         00:01:30
1   swim        00:01:08
1   sleep       00:02:20
2   move        00:01:08
2   swim        00:01:08
2   sleep       00:02:20
3   move        00:01:08
3   run         00:01:12
3   fly         00:01:30
3   swim        00:01:08
3   sleep       00:02:20
3   think       00:03:20

现在我需要计算每个串联视频案例的起点,即我必须总结每个部分的视频持续时间,直到每个 ID 上下文的当前位置,并用它创建一个新列(每个新 ID 从 00:00:00 开始)。结果将如下所示:

ID  vid-file    duration    videopart-start-at
1   move        00:01:08    00:00:00
1   run         00:01:12    00:01:08
1   fly         00:01:30    00:02:20
1   swim        00:01:08    00:03:50
1   sleep       00:02:20    00:04:58
2   move        00:01:08    00:00:00
2   swim        00:01:08    00:01:08
2   sleep       00:02:20    00:02:16
3   move        00:01:08    00:00:00
3   run         00:01:12    00:01:08
3   fly         00:01:30    00:02:20
3   swim        00:01:08    00:03:50
3   sleep       00:02:20    00:04:58
3   think       00:03:20    00:07:18

我认为 PSCustomObject 中可能有一些计算对象,但我无法弄清楚..

[PSCustomObject]@{
                vid-file= $_.Name -replace ".mov",""
                duration = $Duration
                videopart-start-at= $Duration | Measure-Object -Sum $Duration
            }

谢谢,丹尼尔

要计算 date/time 差异,请尝试这样的操作...

$current = Get-Date
$end     = (Get-Date).AddHours(1)
$diff    = New-TimeSpan -Start $current -End $end
"The time difference is: $diff"
# Results
<#
The time difference is: 01:00:00.0019997
#>

...然后根据需要格式化。

我认为有更简单的方法来处理这个问题 - 但我将时间转换为秒 - 然后处理 [TimeSpan] 数据类型。

$movs = 'c:\temp\sample' | Get-ChildItem -Recurse -Force -ErrorAction Stop
        
$dura = New-Object -ComObject Shell.Application
$result = Foreach ($mov in $movs) {
    $Folder = $dura.Namespace($mov.DirectoryName)
    $File = $Folder.ParseName($mov.Name)
    $Duration = $Folder.GetDetailsOf($File, 27)
    [PSCustomObject]@{
        vidfile           = $mov.Name -replace ".mov", ""
        # Convert the string into an actual time data type
        duration          = $Duration
        durationinseconds = ([TimeSpan]::Parse($Duration)).TotalSeconds  
    }
} 
        
$i = 0
Foreach ($object in $result) {
    # Skipping first and stopping on last (foreach will run out of objects to process)
            
    if ($i -eq 0 -or $i -gt ($result.count)) {
        # Adding one to counter
        $i++
        continue
    }

    $object.durationinseconds = $Object.durationinseconds + $result.durationinseconds[$i - 1]
    $object.duration = [timespan]::fromseconds($object.durationinseconds)
    ("{0:hh\:mm\:ss}" -f $object.duration)
    $i++

}

感谢塞巴斯蒂安,我找到了以下解决方案(我在 pscustomobject 中添加了“startat”列,与 durationinseconds 相同):

        
$i = 0
Foreach ($object in $result) {
    
    # skip lines gt result count
    if ($i -gt ($result.count)) {
        $i++
        continue
    }
    
    # set start to 0 for first line          
    if ($i -eq 0) {
        $object.startat = 0
    }   

    # calculate start time for all following lines
    if ($i -gt 0) {
        $object.startat = $result.durationinseconds[$i - 1] + $result.startat[$i - 1]
    } 

    # transform seconds to time value in duration var
    $object.duration = [timespan]::fromseconds($object.startat)

    # counter +1
    $i++

}

$result