How to pass Float in CMTimeMake's timescale Int32

╄→гoц情女王★ 提交于 2019-12-11 15:20:22

问题


I am working on CMTimeMake in order to add slow and fast motion effect to Video. Where we have to divide by Video scale for Fast effect and multiply by Video scale for Slow effect.

Here it is:

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)

Now as per my requirement, there is one Slider (between 0.1 to 2.0) where User will select the particular Video scale value for Slow and Fast effect. This Value is coming in Float.

My problem is when I am passing my Float value like 0.8 in my above code, then:

let videoScaleFactor = Int64(0.8) // this returns me 0

How can I return exact value 0.8 into this? Please advise me.


回答1:


You wrote:

let videoScaleFactor = Int64(0.8) // this returns me 0

That's normal, because by definition can't have decimal value. So 0.8 => 0.

Instead use a Float (or Double) depending on the precision you need.

So let's try it:

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)

That rises another issue:

Binary operator '/' cannot be applied to operands of type 'CMTimeValue' (aka 'Int64') and 'Float'

Indeed in Swift you can't manipulate various types of Int/Float etc like that.

So to fix it:

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)

Now you multiply/divide Float with other Float

But

func CMTimeMake(_ value: Int64, _ timescale: Int32) -> CMTime

So CMTimeMake(_:_:) awaits for a Int64 value, so you get an error because Float(videoAsset.duration.value) / videoScaleFactor (for the first one) is returning a Float while the method wants an Int64.

So just do

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)

That should work now.

But I can't leave with that code. Your line is quite long and it's hard to read. In fact, you just modify the value param of CMTimeMake(_:_:).

Let's factorize:

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)

Now, it's personal, by I'd prefer (nothing wrong with an extra line explicit):

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)


来源:https://stackoverflow.com/questions/51672908/how-to-pass-float-in-cmtimemakes-timescale-int32

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!