Reputation: 5413
1) CMTimeMake(1,10)
means duration of 1 second and timescale of 10, or 10 frames per second. This means 1s duration of video with 10 frames?
2)
CMTime lastTime=CMTimeMake(1,10);
CMTime frameTime=CMTimeMake(1, 10);
CMTime currentTime=CMTimeAdd(lastTime, frameTime)
= (2, 10) ?
2 seconds of video and with 10 frames per second of the currentTime?
Upvotes: 169
Views: 85838
Reputation: 34175
Swift CMTime CoreMediaTime
When you operate time it is important to save accuracy. CMTime
propose you to use two integers(value and timescale) to present a float number. Additional functions simplify CMTime mathematics in contrast to float operations
Important CMTime
properties are:
The formula is
Int64 value(numerator) / Int32 timescale(denominator) = Float64 seconds
//for example
//value 1 / timescale 10 = 1/10(0.1) seconds
Next example shows next items:
import CoreMedia
func testTime() {
let value: Int64 = 1
let timescale: Int32 = 10
let secondsResult: Double = 0.1 // 1/10 sec
let time1: CMTime = CMTime(value: value, timescale: timescale)
let time2: CMTime = CMTime(seconds: secondsResult, preferredTimescale: timescale)
let time3: CMTime = CMTimeMake(value: value, timescale: timescale)
let time4: CMTime = CMTimeMakeWithSeconds(secondsResult, preferredTimescale: timescale)
let seconds1: Double = time1.seconds
let seconds2: Float64 = CMTimeGetSeconds(time1)
assert(seconds1 == seconds2)
assert(seconds1 == secondsResult)
assert(time1 == time2)
assert(time1 == time3)
assert(time1 == time4)
assert(CMTimeCompare(time1, time2) == 0)
}
Create CMTime using seconds
You are able to create CMTime
using value and timescale where seconds will be calculated(value / timescale). This approach is clear but also you are able to create CMTime
using seconds and preferredTimescale. In this case your value and seconds can be different and be recalculated to satisfy formula(value must be Int64) that is why it can be rounded, as a result seconds also is recalculated
//preset - seconds: 0.1, preferredTimescale: 10, expect value == 1
//result - seconds: 0.1, value: 1
let time5: CMTime = CMTime(seconds: 0.1, preferredTimescale: 10)
assert(time5.value == 1)
assert(time5.seconds == 0.1)
//preset - seconds: 0.1, preferredTimescale: 1, expect value == 0.1
//result - seconds: 0, value: 0
let time6: CMTime = CMTime(seconds: 0.1, preferredTimescale: 1)
assert(time6.value == 0)
assert(time6.seconds == 0)
//preset - seconds: 1.31, preferredTimescale: 10, expect value == 13.1
//result - seconds: 1.3, value: 13
let time7: CMTime = CMTime(seconds: 1.31, preferredTimescale: 10)
assert(time7.value == 13)
assert(time7.seconds == 1.3)
Upvotes: 0
Reputation: 8463
If you only want to know how to make an interval for 1 second (like me), this is your answer:
int seconds = 1;
CMTime interval = CMTimeMakeWithSeconds(seconds, NSEC_PER_SEC);
Upvotes: 12
Reputation: 1585
A CMTime struct represents a length of time that is stored as rational number.
CMTime has a value and a timescale field, and represents the time value/timescale seconds .
See See this SO Answer which is clear
Upvotes: 3
Reputation: 12819
With CMTimeMake(A, B)
you store a rational number, an exact fraction A / B
seconds
CMTimeMake(1, 4)
-> the time interval 0.25 secondsWith CMTimeMakeWithSeconds(A, B)
you store A
seconds to a resolution of B
steps
CMTimeMakeWithSeconds(0.25, ...)
-> the time interval 0.25 secondsYou commonly see CMTimeMakeWithSeconds(time, NSEC_PER_SEC)
. The NSEC_PER_SEC
effectively means "max resolution".
Upvotes: 43
Reputation: 3414
Peter is right. The following code makes the concept more clear:
1)
Float64 seconds = 5;
int32_t preferredTimeScale = 600;
CMTime inTime = CMTimeMakeWithSeconds(seconds, preferredTimeScale);
CMTimeShow(inTime);
The above code gives: {3000/600 = 5.000}
Which means a total duration of 5 seconds, with 3000 frames with a timescale of 600 frames per second.
2)
int64_t value = 10000;
int32_t preferredTimeScale = 600;
CMTime inTime = CMTimeMake(value, preferredTimeScale);
CMTimeShow(inTime);
This one gives {10000/600 = 16.667}
Which means a total duration of 16.667 seconds, with 10000 frames with a timescale of 600 frames per second.
Notice the difference between CMTimeMake(int64_t value, int32_t timescale) and CMTimeMakeWithSeconds(Float64 seconds, int32_t preferredTimeScale)
Hope this explanation helps. For further clarifications, please don't hesitate to post further questions on this post.
Upvotes: 154
Reputation: 18333
1) CMTimeMake(1,10)
actually means a value of 1 and a timescale of 10. They are a numerator and denominator, so it is 1/10 of a second, not 1 second.
2) The result will be like CMTimeMake(2, 10)
, which is 2/10ths of a second.
Upvotes: 191