【问题标题】:Converting Milliseconds to Timecode将毫秒转换为时间码
【发布时间】:2010-03-11 12:25:48
【问题描述】:

我正在使用 Un4seen 的 BASS 处理一个音频项目。这个库主要使用字节,但我有一个转换,让我以毫秒为单位显示歌曲的当前位置。

知道 MS = 样本 * 1000 / SampleRate 并且 Samples = Bytes * 8 / Bits / Channels

所以这是我的主要问题,它相当简单......我的项目中有一个函数可以将毫秒转换为时间码,单位为 Mins:Secs:Milliseconds。

Public Function ConvertMStoTimeCode(ByVal lngCurrentMSTimeValue As Long)
        ConvertMStoTimeCode = CheckForLeadingZero(Fix(lngCurrentMSTimeValue / 1000 / 60)) & ":" & _
        CheckForLeadingZero(Int((lngCurrentMSTimeValue / 1000) Mod 60)) & ":" & _
        CheckForLeadingZero(Int((lngCurrentMSTimeValue / 10) Mod 100))
End Function

现在问题出现在秒计算范围内。任何时候 MS 计算超过 0.5 秒位置都会向上舍入到下一秒。所以 1.5 秒实际上打印为 2.5 秒。我确信使用 Int 转换会导致向下舍入,并且我知道我的数学是正确的,因为我已经在计算器中检查了 100 次。我不明白为什么这个数字会四舍五入。有什么建议吗?

【问题讨论】:

  • 这是我遗漏的一个函数: Private Function CheckForLeadingZero(ByRef intValue As Integer, Optional ByVal intLength As Integer = 2) As String Dim strValue As String strValue = CStr(intValue) If Len(strValue)

标签: vb6 time


【解决方案1】:

您的秒数转换逻辑存在缺陷。例如,假设您要转换 1500 毫秒。您计算秒数的代码:

Int((lngCurrentMSTimeValue / 1000) Mod 60)

将返回 2。1500 毫秒不超过两秒!要计算秒数,请将毫秒数除以 1000(“\”运算符):

(lngCurrentMSTimeValue \ 1000) Mod 60

这会按预期返回 1。以下功能就是您所需要的。它甚至通过使用内置的 Format 函数消除了对 CheckForLeadingZero 函数的需要:

Public Function ConvertMStoTimeCode(ByVal lngCurrentMSTimeValue As Long)

  Dim minutes As Long
  Dim seconds As Long
  Dim milliseconds As Long

  minutes = (lngCurrentMSTimeValue / 1000) \ 60
  seconds = (lngCurrentMSTimeValue \ 1000) Mod 60
  milliseconds = lngCurrentMSTimeValue Mod 1000

  ConvertMStoTimeCode = Format(minutes, "00") & ":" & Format(seconds, "00") & _
    ":" & Format(milliseconds, "000")

End Function

【讨论】:

  • 谁会喜欢它?乌鸦那里反应很好!喜欢学习我不知道的关于 VB6 的新知识。非常感谢那里的帮助。我也没有考虑内置的 Format 函数,因为我已经用我的 DLL 中的同名属性替换了 Format 函数。从那以后,我为这个糟糕的约定找到了一个新名字。
【解决方案2】:

目前这可行:

Public Function ConvertMStoTimeCode(ByVal lngCurrentMSTimeValue As Long)
Dim strMinute As String
Dim strSecond As String
Dim strFrames As String

strMinute = CheckForLeadingZero(Fix(lngCurrentMSTimeValue / 1000 / 60))
strSecond = CheckForLeadingZero(Int((lngCurrentMSTimeValue / 1000) Mod 60))
strFrames = CheckForLeadingZero(Int((lngCurrentMSTimeValue / 10) Mod 100))

If (strFrames > 49) Then
    strSecond = CheckForLeadingZero(Int((lngCurrentMSTimeValue / 1000) Mod 60) - 1)
End If

ConvertMStoTimeCode = strMinute & ":" & strSecond & ":" & strFrames

结束函数

【讨论】:

    【解决方案3】:

    这是一个相当容易重新利用的 Processing/Java 等价物。

    String timecodeString(int fps) {
      float ms = millis();
      return String.format("%02d:%02d:%02d+%02d", floor(ms/1000/60/60),    // H
                                                  floor(ms/1000/60),       // M
                                                  floor(ms/1000%60),       // S
                                                  floor(ms/1000*fps%fps)); // F
    }
    

    【讨论】:

    • 对于已经有公认答案的旧帖子发布相同的答案并不是一个好主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多