You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:27:02