Setting QTMovie attributes - cocoa

I'm trying to create a QTVR movie via QTKit, and I've got all the frames in the movie. However, setting the attributes necessary doesn't seem to be having any effect. For example:
NSNumber *val = [NSNumber numberWithBool:YES];
[fMovie setAttribute:val forKey:QTMovieIsInteractiveAttribute];
val = [NSNumber numberWithBool:NO];
[fMovie setAttribute:val forKey:QTMovieIsLinearAttribute];
If I then get the value of these attributes, they come up as NO and YES, respectively. The movie is editable, so I can't understand what I'm doing wrong here. How can I ensure that the attributes will actually change?

What I do when I want to export a Quicktime movie is something like the following:
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], QTMovieExport,
[exportSettings objectForKey: #"subtype"], QTMovieExportType,
[exportSettings objectForKey: #"manufacturer"], QTMovieExportManufacturer,
[exportSettings objectForKey: #"settings"], QTMovieExportSettings,
nil];
BOOL didSucceed = [movie writeToFile: tmpFileName withAttributes:dictionary error: &error];

Those attributes are documented as things you can read but not write. However, you might be able to set them when you create the movie, with initWithAttributes:error:.

Related

Add Mutable Dictionary to a Mutable Dictionary for conversion to JSON

I am trying to build a dictionary which has as dictionary within it (eventually I hope to convert to a JSON). The problem is I am having problems building it.
So far I have this, what it should do is build a small dictionary with keys and add it to a larger dictionary, reset and then load the small dict and then add it to the large one.
NSMutableDictionary *nestedList = [[NSMutableDictionary alloc]init];
NSMutableDictionary *nestedSections = [[NSMutableDictionary alloc] init];
[nestedList addEntriesFromDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:46], #"menuHeight",
#"editText", #"menuMethod",
[NSNumber numberWithInt:1], #"menuOption",
nil]];
[nestedSections addEntriesFromDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
nestedList, "#Basic",
nil]];
[nestedList removeAllObjects];
[nestedList addEntriesFromDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:92], #"menuHeight",
#"sendText", #"menuMethod",
[NSNumber numberWithInt:1], #"menuOption",
nil]];
[nestedSections addEntriesFromDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
nestedList, "#Pro",
nil]];
I then hoped to address like so;
NSString *string = [[nestedSections objectForKey:#"Pro"] objectForKey:#"menuMethod"];
NSLog(#"Method is : %#", string);
Log would hope to read sendText
The first dictionary builds fine but as soon as I try and add it to the second t bums out with EXC_BAD_ACCESS
I think it is a memory addressing problem because they are both mutable but I am not sure, maybe nestedList should not be mutable. Any help appreciated.
Ultimately I would like to convert this to a JSON like;
{
"Basic":
{
"menuHeight":"46",
"menuMethod":"editText",
"menuOption":"1",
},
"Pro":
{
"menuHeight":"96",
"menuMethod":"sendText",
"menuOption":"1",
}
}
A. NSMutableDictionary does not copy the values (only the keys). Therefore you add the same dictionary two times and change both (= the one) when removing objects and so on. Beside this in your sample JSON the numbers looks like strings not like numbers. I think, that this is a typo.
B. Adding modern Objective-C for better readability it should look like this:
NSDictionary *basicDictionary =
#{
#"menuHeight" : #46,
#"menuMethod" : "editText",
#"menuOption : #1
}
NSDictionary *proDictionary =
#{
#"menuHeight" : #96,
#"menuMethod" : "sendText",
#"menuOption : #1
}
NSDictionary *nestedSections = #{ #"Pro" : proDictionary, #"Basic" : basicDictionary };

Scaling a QTMovie before appending

Using the QTKit framework, I'm developing a little app.
In the app, I'm trying to append a movie after a other movie, which in essence is already working (most of the time), but I'm having a little trouble with the appended movie. The movie is which I'm appending to is quite big, like 1920x1080, and the appended movie is usually much smaller, but I never know what size it exactly is. The appended movie sort of stays its own size in the previous 1920x1080 frame, as seen here:
Is there anyone familiar with this? Is there a way I can scale the movie which I need to append to, to the size of the appended movie? There is no reference of such a thing in the documentation.
This is are some relevant methods:
`QTMovie *segmentTwo = [QTMovie movieWithURL:finishedMovie error:nil];
QTTimeRange range = { .time = QTZeroTime, .duration = [segmentTwo duration] };
[segmentTwo setSelection:range];
[leader appendSelectionFromMovie:segmentTwo];
while([[leader attributeForKey:QTMovieLoadStateAttribute] longValue] != 100000L)
{
//wait until QTMovieLoadStateComplete
}
NSDictionary *exportAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], QTMovieExport,
[NSNumber numberWithLong:kQTFileTypeMovie], QTMovieExportType, nil];
NSString *outputFile = [NSString stringWithFormat:#"%#.mov", onderwerp];
NSString *filepath = [[#"~/Desktop" stringByExpandingTildeInPath] stringByAppendingFormat:#"/%#", outputFile];
BOOL succes = [leader writeToFile:filepath withAttributes:exportAttributes error:&theError];
Leader is initialized like this:
NSDictionary *movieAttributes = [NSDictionary dictionaryWithObjectsAndKeys:path, QTMovieFileNameAttribute, [NSNumber numberWithBool:YES], QTMovieEditableAttribute, nil];
leader = [QTMovie movieWithAttributes: movieAttributes error:&error];
This contained all the information I need, although without using the QTKit framework. QTKit - Merge two videos with different width and height?

avoid duplicate results on Core Data fetch

I have a subclass of the CoreDataTableViewController (subclass of UITAbleViewController dome by the people on Stanford done to link CoreData and TableViews). On this Class, I want to perform a fecth, sorting by an attribute called "definition" and the code which executes it is the following:
- (void)setupFetchedResultsController{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:self.entity];
request.propertiesToFetch=[NSArray arrayWithObject:#"definition"];
request.returnsDistinctResults=YES;
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:#"%K != nil", #"definition"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:#"%K != ''", #"definition"];
NSPredicate *predicate3= [NSPredicate predicateWithFormat:#"%K contains[cd] %#", #"definition", self.seachBar.text];
NSArray *prepredicateArray;
if ([self.seachBar.text length]) {
prepredicateArray = [NSArray arrayWithObjects:predicate1, predicate2, predicate3,nil];
}else {
prepredicateArray = [NSArray arrayWithObjects:predicate1, predicate2,nil];
}
request.predicate=[NSCompoundPredicate andPredicateWithSubpredicates:prepredicateArray];
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"definition" ascending:YES ]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
[self performFetch];
}
If I understood it correctly, setting request.returnsDistinctResults=YES; should avoid fetching duplicates. However it doesn't work and I'm seeing duplicates of this attribute's value.
Is there something I'm missing there? I'd appreciate some pointings there. Thank you in advance.
EDIT: If anyone is having the same issue here, after applying David's answer the resulting fetchedResultsController is just a NSDIctionary with object with only the requested value, which for displaying only purposes is quite fine. One thing I've done in cellForRowAtIndexPath in order to display the results on the cell label is:
Before:
HNMR *hnmr = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text=hnmr.definition;
After:
cell.textLabel.text=[[self.fetchedResultsController objectAtIndexPath:indexPath] valueForKey:#"definition"];
From the documentation of returnsDistinctResults:
This value is only used if a value has been set for propertiesToFetch.
From the documentation of propertiesToFetch:
This value is only used if resultType is set to NSDictionaryResultType.
From the documentation of resultType:
The default value is NSManagedObjectResultType.
This all tells me that the propertiesToFetch is ignored because you haven't set the resultType yourself and the default it to return managed objects instead of dictionaries. Since the propertiesToFetch is ignored the returnsDistinctResults is ignored as well and thus you are still getting duplicates.
Try setting the result type to return dictionaries instead of managed objects.
request.resultType = NSDictionaryResultType;
In addition to David Rönnqvist answer I suggest a useful link (with a sample) on selecting distinct values with Core Data:
core-data-how-to-do-a-select-distinct
Hope that helps.

Sort a NSMutuableArray

I have a NSMutableArray that is loaded with a inforamtion from a dictionary...
[self.data removeAllObjects];
NSMutableDictionary *rows = [[NSMutableDictionary alloc] initWithDictionary:[acacheDB.myDataset getRowsForTable:#"sites"]];
self.data = [[NSMutableArray alloc] initWithArray:[rows allValues]];
There are two key value pairs in the rows dictionary.
I need to sort the self.data NSMutableArray in alphabetical order.
How is this accomplished??
thanks
tony
If the values are plain strings you can use the following to create a sorted array:
NSArray *sorted = [values sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
This should do:
[self.data removeAllObjects];
NSArray *values = [[acacheDB.myDataset getRowsForTable:#"sites"] allValues];
NSSortDescriptor *alphaDescriptor = [[NSSortDescriptor alloc] initWithKey:#"DCFProgramName" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray *sortedValues = [values sortedArrayUsingDescriptors:[NSMutableArray arrayWithObjects:alphaDescriptor, nil]];
[alphaDesc release];
[self.data addObjectsFromArray:sortedValues];
There's no need to clear an NSMutableArray if you're replacing it shortly afterwards.
There's no need to create an additional NSMutableDictionary, if you're not modifying anything in it.
There's no need to create an additional NSMutableArray, if you could just as well just add the values to the existing one.
Also: There are some serious memory leaks in your code. (2x alloc + 0x release = 2x leak)
Edit: updated code snippet to reflect OP's update on data structure.

Cocoa QTKit resolution problem

Based on a lot of online references, the way to change resolution is using the following code.
NSDictionary * pixelBufferAttr = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:320], kCVPixelBufferWidthKey,
[NSNumber numberWithInt:240], kCVPixelBufferHeightKey,
[NSNumbernumberWithBool:YES],
(id)kCVPixelBufferOpenGLCompatibilityKey,
[NSNumber
numberWithUnsignedInt:kCVPixelFormatType_422YpCbCr8],
(id)kCVPixelBufferPixelFormatTypeKey,
nil];
NSArray *outputsConnected = [mCaptureSession outputs];
QTCaptureVideoPreviewOutput * previewOutput = [outputsConnected objectAtIndex:1];
[previewOutput setDelegate:self];
[previewOutput setPixelBufferAttributes:pixelBufferAttr];
But after changing the resolution, the captureView can see the different, but using code to check the resolution is incorrect.
Does anyone know how to change the device resolution?
Thanks ALL!

Resources