David Cordero
CMTime for Human Beings
Published on 07 Jul 2021
CMTime is a struct representing a time value such as a timestamp or duration. CMTime is defined by CoreMedia and it is often used by AVFoundation API interfaces.
Because the interface of CMTime is horrible, and its documentation is even worse, here you have a few use cases to make it easier to work with CMTime in a daily basis.
Create a CMTime
Apart from its initializers, a CMTime is often created with the function CMTimeMake.
CMTimeMake(value: timescale:)
This function creates a CMTime with a duration of value/timescale seconds.
Examples:
CMTimeMake(value: 1, timescale: 1) // 1 second
CMTimeMake(value: 1, timescale: 2) // 0.5 seconds
CMTimeMake(value: 2000, timescale: 1000) // 2 seconds
CMTimeMake(value: 2000, timescale: 3000) // 0.6666666 seconds
Get value from CMTime
CMTime has a value property, but because its actual value depends on the timescale of the CMTime, it is not very useful in daily basis. Instead it is usually better to use CMTimeGetSeconds.
CMTimeGetSeconds
CMTimeGetSeconds is a function that returns a float value representing a CMTime in seconds.
Example 1:
let time = CMTimeMake(value: 2000, timescale: 1000)
let seconds = CMTimeGetSeconds(time)
print(seconds) // 2.0
Example 2:
let time = CMTimeMake(value: 1, timescale: 5)
let seconds = CMTimeGetSeconds(time)
print(seconds) // 0.2
Property seconds
As a syntax sugar 🍭 you can also get the seconds from a CMTime value from the property seconds of CMTime.
let secondsWithCMTimeGetSeconds = CMTimeGetSeconds(time)
let secondsWithSyntaxSugar = time.seconds
print(secondsWithCMTimeGetSeconds == secondsWithSyntaxSugar) // true
All it says is No overview available.
, but here you have the documentation from Apple as a “reference”:
https://developer.apple.com/documentation/coremedia/cmtime/1489443-seconds
CMTime fun values
Apart from the numerical values that one could expect from CMTime. It can also take other fun values such as NaN (Not a Number) or Infinite.
The function isFinite
can be useful to deal with these cases.
You can find here below an example of this use case. Contrary to expected, the following code will print NaN, even though time has no value. This is because the fallback string is never used because of time.seconds does not return nil but NaN.
let time = CMTime()
print(time.seconds ?? "I'm sorry but I do not have any value for you")
Here you can see how we can use the function isFinite to deal with this problem:
let time = CMTime()
let seconds = time.seconds
print(seconds.isFinite ? seconds : "I'm sorry but I do not have any value for you")