1

我正在编写一个使用 AVFoundation 和 CMTime 的应用程序。我已经记录了CMTime使用创建的实例的值CMTimeMake()。这个值似乎被四舍五入到最接近的整数。我需要一个CMTime具有精确值的实例,而不是四舍五入。

我在CMTime参考文献中看到了舍入常量:

enum {
   kCMTimeRoundingMethod_RoundHalfAwayFromZero = 1,
   kCMTimeRoundingMethod_RoundTowardZero = 2,
   kCMTimeRoundingMethod_RoundAwayFromZero = 3,
   kCMTimeRoundingMethod_QuickTime = 4,
   kCMTimeRoundingMethod_RoundTowardPositiveInfinity = 5,
   kCMTimeRoundingMethod_RoundTowardNegativeInfinity = 6,

   kCMTimeRoundingMethod_Default = kCMTimeRoundingMethod_RoundHalfAwayFromZero
};

没有任何示例说明我如何控制将这些策略中的哪些应用于CMTime实例?或者,如果这不是正确的方法,我如何从CMTime实例中提取精确值?


编辑:

我已经找到并测试了CMTIME_HAS_BEEN_ROUNDED(). 我将我的CMTime实例传递给该函数并返回No(表明该值尚未四舍五入)。那么为什么我会失去精度呢?

4

2 回答 2

8

如果您阅读文档,CMTime您会看到它使用分子和分母将时间存储为有理数。分子是int64_t分母是int32_t

分子指定经过了多少“滴答声”,分母指定每秒有多少“滴答声”。

所以 0.5 秒可以存储为:

  • 100/200:100 个滴答声,每秒 200 个滴答声
  • 500/1000:500 刻,每秒 1000 刻
  • 8/16, 8 滴答, 16 滴答每秒

等等。你做的方式,使用

CMTimeMake([[Array objectAtIndex:i]floatValue], 1);

说“每秒有一个滴答声”,并且由于分子是整数,因此浮点值被截断,因此仅存储 1。因此,您将时间指定为:1/1,一个滴答已过去,每秒一个滴答,因此您实际上存储的正是1 秒。

要解决这个问题,这取决于你想做什么以及你是否关心时间尺度。Apple 推荐时间刻度为 600,但如果你不在乎,你可以这样做:

CMTimeMake([[Array objectAtIndex:i]floatValue]*1000, 1000);

这将时间刻度设置为 1000,因此每秒 1000 个滴答声,因此每个滴答声一毫秒。它还将以秒为单位的时间转换为毫秒。请注意,它会截断第 4 位,所以如果你有 1.2345,你只会得到 1.234 而不是 1.235。如果这对您很重要,请参阅roundf

于 2011-03-25T08:17:02.950 回答
0

CMTimeMake([[Array objectAtIndex:i]floatValue]*1000, 1000);

这帮助我获得了以毫秒为单位的准确时间。干杯。

于 2015-03-19T09:59:47.437 回答