Showing posts with label Quicktime. Show all posts
Showing posts with label Quicktime. Show all posts

Tuesday, September 22, 2009

More Housecleaning

Here's another category I found while cleaning out my dev folder. It's another bit of Quicktime code for Cocoa. This is a category on QTMovie that makes it easier to deal with standard movies (i.e. ones with one video track and any number of audio tracks).

This same category exists in the MovieStepper project, but that version won't compile for 64-bit Cocoa applications because Apple has removed access to the underlying Quicktime data structures like Track and Media. This version uses only QTKit objects to accomplish the same tasks, and thus will compile for both 32-bit and 64-bit applications.

QTMovie-Frame.h
//
// QTMovie-Frame.h
// MovieStepper
//
// These are methods designed to be used on movies that contain only
// sequential frame data, e.g. straight movies. These methods make
// the assumption that the framerate is constant and that each frame
// is displayed for the same length of time. Do not use these methods
// on movies that have tracks other than a single video track and
// some number of audio tracks.
//
// This code may be used freely in any project, commercial or otherwise
// without obligation. There is no attribution required, and no need
// to publish any code. The code is provided with absolutely no
// warranties of any sort.

#import <Cocoa/Cocoa.h>
#import <QTKit/QTKit.h>

@interface QTMovie(Frames)
- (long)numberOfFrames;
- (void)gotoFrameNumber:(long)frameNum;
- (long)currentFrameNumber;
- (int)displayFPS;
- (float)desiredFPS;
- (NSImage *)frameImageForFrame:(int)frameNumber;
- (NSSize)size;
@end



QTMovie.m
//
// QTMovie-Frame.m
// MovieStepper
//
// Copyright 2009 Jeff LaMarche. All rights reserved.
//
// This code may be used freely in any project, commercial or otherwise
// without obligation. There is no attribution required, and no need
// to publish any code. The code is provided with absolutely no
// warranties of any sort.
//
// This code has been updated to work in 64-bit mode where access to
// the underlying Quicktime Carbon structures has been removed.

#import "QTMovie-Frames.h"

@implementation QTMovie(Frames)
- (long)numberOfFrames
{
NSArray *tracks = [self tracksOfMediaType:QTMediaTypeVideo];

for (QTTrack *track in tracks)
{
QTMedia *media = [track media];
NSNumber *frames = [media attributeForKey:QTMediaSampleCountAttribute];
if (frames != nil)
return [frames longValue];
}


return -1L;
}

- (void)gotoFrameNumber:(long)frameNum
{
int frames = [self numberOfFrames];
double percentDone = (double)frameNum / (double) frames;
QTTime duration = [self duration];
QTTime newTime;
newTime.timeScale = duration.timeScale;
newTime.flags = duration.flags;
newTime.timeValue = duration.timeValue * percentDone;
[self setCurrentTime:newTime];
}

- (long)currentFrameNumber
{
QTTime now = [self currentTime];
QTTime duration = [self duration];

if (now.timeValue == 0 || duration.timeValue == 0)
return 0;

double percentDone = (double)now.timeValue / (double)duration.timeValue;
int frames = [self numberOfFrames];

return (int) ((double)frames * percentDone)+1;
}

- (Fixed)rawFPS
{
NSArray *tracks = [self tracksOfMediaType:QTMediaTypeVideo];

for (QTTrack *track in tracks)
{
QTMedia *media = [track media];
QTTime duration = [[media attributeForKey:QTMediaDurationAttribute] QTTimeValue];
long numFrames = [self numberOfFrames];
double frameRate = numFrames*(double)duration.timeScale/(double)duration.timeValue;
return X2Fix(frameRate);
}

return -1;
}

- (int)displayFPS
{
return FixRound([self rawFPS]);
}

- (float)desiredFPS
{
return FixedToFloat([self rawFPS]);
}

- (NSImage *)frameImageForFrame:(int)frameNumber
{
QTTime restoreTime = [self currentTime];
[self gotoFrameNumber:frameNumber];
NSImage *ret = [self currentFrameImage];
[self setCurrentTime:restoreTime];
return ret;
}

- (NSSize)size
{
return [[self attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
}


@end

Monday, September 21, 2009

More Desktop Code

Although my focus for the last 20 months has been the iPhone, I've tried to stay at least in touch with Cocoa for the Mac. As a result, I tend to start a lot of small projects designed to help me learn, re-learn, or brush up on some specific area of functionality. A lot of these projects just end up gathering dust on my hard drive and are never used in any kind of production application, so since I'm doing a little housecleaning, I thought I'd post some of these projects that might be useful to iPhone developers wanting to get into Mac development or for newer Mac developers.

I've written several Cocoa applications over the years that work with Quicktime, including Crimson FX, a simple rotoscoping and special effects application. Back when I wrote these, most of the Quicktime functionality had to be accessed through Carbon calls. Since then, there have been several major releases of Quicktime, and Cocoa has gained some very robust Quicktime support by way of QTKit.

To familiarize myself with Cocoa's current Quicktime functionality, I wrote a small application that loads in a Quicktime movie and allows you to step through it frame-by-frame or to scrub through the frames using a slider. There's also a custom view that displays a filmstrip timeline, similar to the way iMovie displays a timeline.



This is neither a full-featured, nor a production-ready application, but if you're interested in writing a Cocoa application that needs to do more with Quicktime than simply play a movie, you may find some of the code in here useful. In addition to the filmstrip view, there's also a category that adds several methods to QTMovie for dealing with the individual frames of a movie's video track.

You can find the project here. As always, there are no restrictions on the use of this code, and I welcome any improvements or bug fixes you might come up with.

 
Design by Wordpress Theme | Bloggerized by Free Blogger Templates | coupon codes