Converting Cmtime to String Is Wrong Value Return

Converting CMTime To String is wrong value return

You need to round your seconds before calculating your time components.

extension CMTime {
var roundedSeconds: TimeInterval {
return seconds.rounded()
}
var hours: Int { return Int(roundedSeconds / 3600) }
var minute: Int { return Int(roundedSeconds.truncatingRemainder(dividingBy: 3600) / 60) }
var second: Int { return Int(roundedSeconds.truncatingRemainder(dividingBy: 60)) }
var positionalTime: String {
return hours > 0 ?
String(format: "%d:%02d:%02d",
hours, minute, second) :
String(format: "%02d:%02d",
minute, second)
}
}

Testing all the possible edge rounding cases:

CMTime(value: 0, timescale: 600).positionalTime              // "00:00"
CMTime(value: 300, timescale: 600).positionalTime // "00:01"
CMTime(value: 600, timescale: 600).positionalTime // "00:01"

CMTime(value: 18000 - 600, timescale: 600).positionalTime // "00:29"
CMTime(value: 17945, timescale: 600).positionalTime // "00:30"
CMTime(value: 18000, timescale: 600).positionalTime // "00:30"
CMTime(value: 18055, timescale: 600).positionalTime // "00:30"
CMTime(value: 18000 + 600, timescale: 600).positionalTime // "00:31"

CMTime(value: 2160000 - 600, timescale: 600).positionalTime // "59:59"
CMTime(value: 2160000 - 300, timescale: 600).positionalTime // "1:00:00"
CMTime(value: 2160000, timescale: 600).positionalTime // "1:00:00"

Converting CMTime values to swift

You can not simply perform mathematically operation with different type of operands in swift like other languages. You need to type-cast manually.

Here you should cast videoAsset.naturalTimeScale( which is CMTimeScale and CMTimeScale is of type Int32) to Float to get it work.

Float(videoAsset.naturalTimeScale)

But CMTimeMake's value key will accept value CMTimeValue type value. So use it like:

trimmingTime = CMTimeMake(value: CMTimeValue(Float(videoAsset.naturalTimeScale) / videoAsset.nominalFrameRate), timescale: videoAsset.naturalTimeScale)

Again to make you code more Swifty use CMTime rather CMTimeMake as:

trimmingTime = CMTime(value: CMTimeValue(Float(videoAsset.naturalTimeScale) / videoAsset.nominalFrameRate), timescale: videoAsset.naturalTimeScale)

Receiving Fatal error: Double value cannot be converted to Int because it is either infinite or NaN

From the CMTimeGetSeconds documentation:

If the CMTime is invalid or indefinite, NaN is returned. If the CMTime
is infinite, +/- infinity is returned.

When CMTimeGetSeconds returns NaN or infinity, casting the return value to an Int will throw the Fatal Error you are seeing.

You can first check the value then return some sort of default in case it's not a valid number.

func toDisplayString() -> String {
let rawSeconds = CMTimeGetSeconds(self)
guard !(rawSeconds.isNaN || rawSeconds.isInfinite) else {
return "--" // or some other default string
}
let totalSeconds = Int(rawSeconds)
let seconds = totalSeconds % 60
let minutes = totalSeconds / 60
let timeFormatString = String(format: "%02d:%02d", minutes, seconds)
return timeFormatString
}

CMTimeClampToRange() doesn't seem to return a CMTime that's inside the given range

I've worked out the following hack:

clipTime = CMTimeMaximum(clipRange.start, CMTimeSubtract(clipTime, CMTimeMake(1, clipTime.timescale)));

Basically, it subtracts the smallest non-empty timespan within the same timescale from the clamped time and makes sure we don't yield a negative value.

Xcode 6- SWIFT- Cast CMTime as Float

CMTime is a structure, containing a value, timescale and other fields,
so you cannot just "cast" it to a floating point value.

Fortunately, there is a conversion function CMTimeGetSeconds():

let cmTime = player.currentTime()
let floatTime = Float(CMTimeGetSeconds(player.currentTime()))

Update: As of Swift 3, player.currentTime returns a
TimeInterval which is a type alias for Double.
Therefore the conversion to Float simplifies to

let floatTime = Float(player.currentTime)

How do I convert a CMTime to an NSValue in Swift?

The Swift constructor corresponding to valueWithCMTime: is NSValue(time:):

import CoreMedia
import AVFoundation

let cmTime = CMTimeMake(value: 10, timescale: 20) // Updated for Swift 3+
let cmValue = NSValue(time: cmTime)
// Or simply:
let cmValue = cmTime as NSValue

CMTime doesn't seek AVPlayer to correct time

Your entire use of CMTime(seconds:preferredTimescale:) is wrong. The first argument should be a number of seconds (hence the name, seconds:), not a number of milliseconds; and the second argument should be a reasonable timescale, such as 600.



Related Topics



Leave a reply



Submit