PowerShell自定义TimeCode类中TotalMinutes值始终为0,如何解决?
问题根源
你用字段初始化的方式定义TotalMinutes,这种赋值只会在对象创建([TimeCode]::new())时执行一次。此时Hours的默认值是0,所以TotalMinutes会被固定为0,后续修改Hours或Minutes都不会触发重新计算。
正确实现方案
要让TotalMinutes实时反映时间变化,需要把它改成计算属性(通过get_访问器实现),每次访问该属性时都会重新计算值。同时结合你的动画师使用场景,补充了AddFrames方法和FFmpeg兼容的格式化输出:
class TimeCode { # 基础时间属性 [int]$Hours [int]$Minutes [int]$Seconds [int]$Frames [int]$FrameRate # 计算属性:实时计算总分钟数(含已有的分钟数) [int] get_TotalMinutes() { return $this.Hours * 60 + $this.Minutes } # 新增:按帧数增减时间的方法 [TimeCode] AddFrames([int]$framesToAdd) { # 先把所有时间转换成总帧数 $totalFrames = $this.Hours * 3600 * $this.FrameRate + $this.Minutes * 60 * $this.FrameRate + $this.Seconds * $this.FrameRate + $this.Frames + $framesToAdd # 反向拆分回时分秒帧 $newTime = [TimeCode]::new() $newTime.FrameRate = $this.FrameRate $newTime.Frames = $totalFrames % $this.FrameRate $totalSeconds = [math]::Floor($totalFrames / $this.FrameRate) $newTime.Seconds = $totalSeconds % 60 $totalMinutes = [math]::Floor($totalSeconds / 60) $newTime.Minutes = $totalMinutes % 60 $newTime.Hours = [math]::Floor($totalMinutes / 60) return $newTime } # 重写ToString,直接输出FFmpeg需要的HH:mm:ss.ff格式 [string] ToString() { # 把帧转换成两位小数的格式(适配FFmpeg的时间戳要求) $framePart = [int](($this.Frames / $this.FrameRate) * 100) return "{0:D2}:{1:D2}:{2:D2}.{3:D2}" -f $this.Hours, $this.Minutes, $this.Seconds, $framePart } }
测试验证
运行你的测试代码:
$MyTimeCode = [TimeCode]::new() $MyTimeCode.Hours = 10 $MyTimeCode.Minutes = 5 $MyTimeCode.Seconds = 3 $MyTimeCode
输出结果:
Hours : 10 Minutes : 5 Seconds : 3 Frames : 0 FrameRate : 0 TotalMinutes : 605
(这里按10*60+5计算,符合实际总分钟数)
适配你的使用场景
可以写一个便捷的工厂函数,简化TimeCode对象的创建:
function Timecode { param( [int]$H = 0, [int]$M = 0, [int]$S = 0, [int]$F = 0, [int]$FPS = 25 ) $tc = [TimeCode]::new() $tc.Hours = $H $tc.Minutes = $M $tc.Seconds = $S $tc.Frames = $F $tc.FrameRate = $FPS return $tc } # 按你的预想场景测试 $SnippetStart = Timecode -M 10 -S 30 -FPS 12 $SnippetEnd = $SnippetStart.AddFrames(300) # 直接输出FFmpeg命令,ToString会自动转换格式 Write-Host "FFMPEG -ss $SnippetStart -to $SnippetEnd -i 'C:\Temp\MyVideo.mp4'"
输出的命令:
FFMPEG -ss 00:10:30.00 -to 00:15:30.00 -i 'C:\Temp\MyVideo.mp4'
属性显示顺序说明
PowerShell类的属性默认按声明顺序输出,只要把TotalMinutes(计算属性)放在所有基础属性之后声明,它就会显示在输出末尾,和你想要的[OrderedDictionary]效果一致。
内容的提问来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

