如何在 CMTimeMake 的时间刻度 Int32 中传递浮点数
Posted
技术标签:
【中文标题】如何在 CMTimeMake 的时间刻度 Int32 中传递浮点数【英文标题】:How to pass Float in CMTimeMake's timescale Int32 【发布时间】:2018-08-03 12:41:09 【问题描述】:我正在开发 CMTimeMake,以便为视频添加慢动作和快动作效果。我们必须除以视频比例以获得快速效果,并乘以视频比例以获得慢速效果。
这里是:
let videoScaleFactor = Int64(2)
// Get the scaled video duration
let scaledVideoDuration = (mode == .Faster) ? CMTimeMake(videoAsset.duration.value / videoScaleFactor, videoAsset.duration.timescale) : CMTimeMake(videoAsset.duration.value * videoScaleFactor, videoAsset.duration.timescale)
现在根据我的要求,有一个滑块(介于 0.1 到 2.0 之间),用户将在其中选择特定的视频比例值以获得慢速和快速效果。此值以浮点数形式出现。
我的问题是当我在上面的代码中传递像 0.8 这样的浮点值时,然后:
让 videoScaleFactor = Int64(0.8) // 这返回 0
如何将精确值 0.8 返回到此?请给我建议。
【问题讨论】:
不要将 Int64 用于videoScaleFactor
,使用 Float
。
我可以使用,但是当我使用 Float 时,它给我的错误应该是 Int64。
因为 CMTimeMake(_:_:)
等待 Int64 然后是 Int32。您需要做什么CMTimeMake(Int64(videoAsset.duration.value / videoScaleFactor), ...)
等,其中videoScaleFactor
是Float
。换句话说,使用 Float/Double 或其他方法进行计算,然后转换为 Int64。
当我尝试这样做时:让 videoScaleFactor = Float(0.12) 让 scaledVideoDuration = (mode == .Faster) ? CMTimeMake(Int64(videoAsset.duration.value / videoScaleFactor), videoAsset.duration.timescale) : CMTimeMake(Int64(videoAsset.duration.value * videoScaleFactor), videoAsset.duration.timescale) 然后出现错误:二进制运算符'/'不能应用于“CMTimeValue”(又名“Int64”)和“Float”类型的操作数
可以直接传递我的Float值吗?
【参考方案1】:
你写道:
let videoScaleFactor = Int64(0.8) // this returns me 0
这很正常,因为根据定义不能有十进制值。所以 0.8 => 0.
根据您需要的精度,改为使用Float
(或Double
)。
那么让我们试试吧:
let videoScaleFactor = Float(0.8)
// Get the scaled video duration
let scaledVideoDuration = (mode == .Faster) ? CMTimeMake(videoAsset.duration.value / videoScaleFactor, videoAsset.duration.timescale) : CMTimeMake(videoAsset.duration.value * videoScaleFactor, videoAsset.duration.timescale)
这引发了另一个问题:
二元运算符“/”不能应用于“CMTimeValue”(又名“Int64”)和“Float”类型的操作数
确实,在 Swift 中你不能像那样操作各种类型的 Int/Float 等。
所以要修复它:
let videoScaleFactor = Float(0.8)
// Get the scaled video duration
let scaledVideoDuration = (mode == .Faster) ? CMTimeMake(Float(videoAsset.duration.value) / videoScaleFactor, videoAsset.duration.timescale) : CMTimeMake(Float(videoAsset.duration.value) * videoScaleFactor, videoAsset.duration.timescale)
现在您将Float
与其他Float
相乘/除以
但是
func CMTimeMake(_ value: Int64, _ timescale: Int32) -> CMTime
所以CMTimeMake(_:_:)
等待Int64
值,因此您会收到错误,因为Float(videoAsset.duration.value) / videoScaleFactor
(对于第一个)正在返回Float
,而该方法需要一个Int64。
就这样吧
let videoScaleFactor = Float(0.8)
// Get the scaled video duration
let scaledVideoDuration = (mode == .Faster) ? CMTimeMake(Int64(Float(videoAsset.duration.value) / videoScaleFactor), videoAsset.duration.timescale) : CMTimeMake(Int64(Float(videoAsset.duration.value) * videoScaleFactor), videoAsset.duration.timescale)
现在应该可以了。
但我不能带着那个代码离开。您的行很长,很难阅读。其实你只要修改CMTimeMake(_:_:)
的value
参数就好了。
让我们分解:
let videoScaleFactor = Float(0.8)
// Get the scaled video duration
let scaledVideoDuration = CMTimeMake((mode == .Faster) ? Int64(Float(videoAsset.duration.value) / videoScaleFactor) : Int64(Float(videoAsset.duration.value) * videoScaleFactor), videoAsset.duration.timescale)
现在,这是个人的,我更喜欢(明确的额外行没有错):
let videoScaleFactor = Float(0.8)
let value = (mode == .Faster) ? Float(videoAsset.duration.value) / videoScaleFactor : Float(videoAsset.duration.value) * videoScaleFactor
let scaledVideoDuration = CMTimeMake(Int64(value), videoAsset.duration.timescale)
【讨论】:
以上是关于如何在 CMTimeMake 的时间刻度 Int32 中传递浮点数的主要内容,如果未能解决你的问题,请参考以下文章