10

I am creating an application in which I have to mix the songs. I have accomplished this but the problem is when I am using the following function.

- (BOOL)insertTimeRange:(CMTimeRange)timeRange ofTrack:(AVAssetTrack *)track atTime:(CMTime)startTime error:(NSError **)error;

I have to pass CMTime type value in the atTime parameter but it doesn't takes Float value and I have to add the another song at some floating point value. Is it possible any how?

Naresh
  • 16,698
  • 6
  • 112
  • 113
Developer
  • 6,375
  • 12
  • 58
  • 92

4 Answers4

19

You can use one of the CMTimeMake...() functions. You have to supply a time point and a timescale value. The former is a 64-bit integer; you can just truncate or round your float to convert it to an integer, or use a necessarily high timescale:

CMTime tm = CMTimeMake(53425, 10000); // @ 5.3425 sec
  • I don't need Integer value. Here is an example, Suppose there is a song with duration 10 secs and I have to mix one more song at 5.3425 secs. But since "atTime" parameter takes only CMTime Value and it is Integer and when I am using the CMTimeMake(5.3425, 1.0); it is returning me 5.00000 and the song gets added at 5.00000 not at 5.3425. – Developer Dec 27 '12 at 13:42
  • @Harsh Why can't you just set the timescale to something reasonable then? For example, 5.3425 can be represented as `CMTimeMake(53425, 10000)`... –  Dec 27 '12 at 13:50
  • 1
    It worked! :-) Accepted you answer! Thanks but why it was not working with CMTimeMake(5.3425, 1.0);? – Developer Dec 27 '12 at 14:06
  • @Harsh Only if you read the documentation... the first argument of the function is the numerator and the second is the denominator of a fraction. And it accepts integers, so no matter you have a float, C's type system will truncate it. –  Dec 27 '12 at 14:18
  • @Harsh `CMTimeMake(5.3425, 1.0)` fails because the `timescale` value means `CMTimeMake` will not return anything smaller than 1 second. `The precision of the CMTime object as a whole is limited by this quantity. For example, if timescale is 1, no timestamp smaller than 1 second can be represented by the object, and timestamps go in increments of one second. Similarly, if timescale is 1000, each second is subdivided into 1000 pieces, and the value member represents the number of milliseconds we want to signify.` Details here: https://warrenmoore.net/understanding-cmtime – Crashalot Jun 13 '16 at 18:16
2

In Swift 4.2 and Xcode 10.1

CMTimeMake(value: 53425, timescale: 10000)// @ 5.3425 sec
Naresh
  • 16,698
  • 6
  • 112
  • 113
0

Swift version

CMTime(seconds: 5.3425, preferredTimescale: CMTimeScale(1000))

Set preferredTimescale larger to get more precision.


Availability

iOS 7.0+ macOS 10.9+ Mac Catalyst 13.0+ tvOS 9.0+ watchOS 6.0+ Xcode 7.1+

Also check Apple Documentation.

Yang_____
  • 117
  • 8
0

sadly every answer uses hard coded CMTimeScale(1000), the right way is

let t = CMTimeMake(value: 53425, timescale: CMTimeScale(NSEC_PER_SEC))
Peter Lapisu
  • 19,915
  • 16
  • 123
  • 179