Movie cocoaqt
From The Foundry MODO SDK wiki
Revision as of 23:05, 6 September 2013 by Adissid (Talk | contribs) (Created page with "Movie_CocoaQT is a basic example plugin. This wiki page is intended as a walkthrough of the code in order to help you better understand the SDK. _TOC_ ==Functionality== Mov...")
Movie_CocoaQT is a basic example plugin. This wiki page is intended as a walkthrough of the code in order to help you better understand the SDK.
_TOC_
Contents
Functionality
Movie_CocoaQT is a Plug-in Cocoa QuickTime saver for movies.
Code Walkthrough
Class Declaration
class CCocoaQuickTimeMovie : public CLxImpl_Movie { public: LxResult mov_BeginMovie (const char*,int, int, int); LxResult mov_SetFramerate (int); LxResult mov_AddImage (ILxUnknownID); LxResult mov_EndMovie (void); LxResult mov_AddAudio (ILxUnknownID); static LXtTagInfoDesc descInfo[]; int frameRate; NSString *nsStringPath; QTMovie *mMovie; NSDictionary *myDict; NSString *audioFileName; };
We want to have our class create a movie object, so we have our class inherit from CLxImpl_Movie.
Server Tags
LXtTagInfoDesc CCocoaQuickTimeMovie::descInfo[] = { { LXsLOD_CLASSLIST, LXa_MOVIE }, { LXsLOD_DOSPATTERN, "*.mov" }, { LXsSAV_DOSTYPE, "mov" }, { LXsSRV_USERNAME, "Express Quicktime" }, { 0 } };
The tags here indicate that the main class will be a server of the movie type that will have the extension .mov named Express Quicktime
Initialization
void initialize () { LXx_ADD_SERVER (Movie, CCocoaQuickTimeMovie, "quicktime"); }
We export a server of the movie type dependent on the CCocoaQuickTimeMovie class with the "quicktime" name.
Helper Functions
static NSImage * cgImageToNSImage ( CGImageRef image) { NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0); CGContextRef imageContext = nil; NSImage *newImage = nil; // Get the image dimensions. imageRect.size.height = CGImageGetHeight(image); imageRect.size.width = CGImageGetWidth(image); // Create a new image to receive the Quartz image data. newImage = [[NSImage alloc] initWithSize:imageRect.size]; [newImage lockFocus]; // Get the Quartz context and draw. imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image); [newImage unlockFocus]; return newImage; }
This function takes a cg image and transforms it into a ns image, the apple format.
static LxResult CreateAudioTempFile ( NSString *filePath, CLxUser_Audio *audio) { LXtAudioMetrics m; LxResult res; OSStatus err; NSURL *toURL; AudioBufferList audioBufferList; UInt32 bufferSize; char *buffer; ExtAudioFileRef outfile; int eos; unsigned int readFrames; toURL = [NSURL fileURLWithPath: filePath]; audio->Metrics (&m); AudioStreamBasicDescription outFormat = {0}; AudioFileTypeID audioFileType; outFormat.mBitsPerChannel = m.type; outFormat.mSampleRate = (Float64) m.frequency; outFormat.mFormatID = kAudioFormatLinearPCM; outFormat.mChannelsPerFrame = m.channels; outFormat.mFramesPerPacket = 1; outFormat.mBytesPerFrame = outFormat.mBitsPerChannel / 8 * outFormat.mChannelsPerFrame; outFormat.mBytesPerPacket = outFormat.mBytesPerFrame * outFormat.mFramesPerPacket; audioFileType = kAudioFileWAVEType; outFormat.mFormatFlags = kAudioFormatFlagIsPacked; if (m.type == 16) outFormat.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; else if (m.type == 32) outFormat.mFormatFlags |= kLinearPCMFormatFlagIsFloat; // Create a temp audio file. err = ExtAudioFileCreateWithURL ((CFURLRef) toURL, audioFileType, &outFormat, NULL, kAudioFileFlags_EraseFile, &outfile); if (err != noErr) { NSLog (@"[ExtAudioFileCreateWithURL] err %ld\n", err); NSLog (@"[toURL] %@\n", toURL); NSLog (@"mSampleRate %f\n", outFormat.mSampleRate); NSLog (@"mFormatID %s\n", &outFormat.mFormatID); NSLog (@"mFormatFlags %x\n", outFormat.mFormatFlags); NSLog (@"mBytesPerPacket %u\n", outFormat.mBytesPerPacket); NSLog (@"mFramesPerPacket %u\n", outFormat.mFramesPerPacket); NSLog (@"mBytesPerFrame %u\n", outFormat.mBytesPerFrame); NSLog (@"mChannelsPerFrame %u\n", outFormat.mChannelsPerFrame); NSLog (@"mBitsPerChannel %u\n", outFormat.mBitsPerChannel); return LXe_FAILED; } readFrames = 1024; bufferSize = sizeof (char) * readFrames * outFormat.mBytesPerPacket; buffer = (char *) malloc (bufferSize); audioBufferList.mNumberBuffers = 1; audioBufferList.mBuffers[0].mNumberChannels = outFormat.mChannelsPerFrame; audioBufferList.mBuffers[0].mDataByteSize = bufferSize; audioBufferList.mBuffers[0].mData = buffer; // Read audio data from audio object and write it into the temp file. audio->Seek (0); while (1) { readFrames = 1024; res = audio->Read (&readFrames, buffer, &eos); if (LXx_FAIL (res)) return LXe_FAILED; if (readFrames == 0) break; err = ExtAudioFileWrite (outfile, (UInt32) readFrames, &audioBufferList); if (err != noErr) return LXe_FAILED; } free (buffer); ExtAudioFileDispose (outfile); return LXe_OK; }
This function creates a temporary audio file with the audio object.