Question

I'm currently attempting to add some video clip settings to a NSMutableDictionary, including two CMTime objects.

I am trying to store the video stream in use (indicated with an integer), the clip duration (CMTime) and the clip start time (CMTime), which are defined elsewhere in the code.

I'm probably being daft but I can't figure out how to add the CMTimes to the dictionary, I get a "Sending 'CMTime' to parameter of incompatible type 'id'" error.

I tried both setObject and setValue with no success and can't find an answer anywhere.

NSMutableDictionary *clipDetails = [NSMutableDictionary dictionary];
[clipDetails setObject:[NSNumber numberWithInteger:currentStream] forKey:@"stream"];
[clipDetails setObject:startTime forKey:@"clipStart"];
[clipDetails setObject:duration forKey:@"duration"];
Was it helpful?

Solution

Since CMTime is a struct, you need to wrap it in an Objective C type, usually with NSValue:

CMTime startTime = (...);
NSValue *startValue = [NSValue valueWithBytes:&startTime objCType:@encode(CMTime)];
[clipDetails setObject:startValue forKey:@"startTime"];

You can get it out again like so:

CMTime startTime;
NSValue *startValue = [clipDetails objectForKey:@"startTime"];
[startValue getValue:&startTime];

Sidenote, it's much easier to use the new dictionary syntax:

clipDetails[@"startTime"] = ...;
NSValue *value = clipDetails[@"startTime"];

Those steps will work for any struct; as it turns out, the AVFoundation framework provides convenience methods for CMTime structs:

clipDetails[@"startTime"] = [NSValue valueWithCMTime:startTime];
CMTime startTime = [clipDetails[@"startTime"] CMTimeValue];

OTHER TIPS

The most simple and elegant way is probably:

NSValue *value = [NSValue valueWithCMTime:cmTime];

Then add value to dictionary:

NSMutableDictionary *clipDetails = [NSMutableDictionary dictionary];
[clipDetails setObject: value forKey:@"cmtime"];

Use CMTimeCopyAsDictionary to convert your CMTime struct to CFDictionaryRef and CMTimeMakeFromDictionary to get back your CMTime.

// Without ARC
 CFDictionaryRef timeAsDictionary = CMTimeCopyAsDictionary(startTime, kCFAllocatorDefault);
[clipDetails setObject:(NSDictionary*)timeAsDictionary forKey:@"clipStart"];
CFRelease(timeAsDictionary);

The problem is that setObject: takes an objectiveC object as an argument (e.g. an object that derives from NSObject)

CMTime, on the other hand, is a struct and you can't use it to add it to the dictionary. You would need to convert it to some other valid object... maybe an NSDate??

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top