Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
ImportExportMovie.c
/* |
File: ImportExportMovie.c |
Written by: Peter Hoddie |
Copyright: © 1992 by Apple Computer, Inc., all rights reserved. |
*/ |
#include <SysEqu.h> |
#include <Memory.h> |
#include <Resources.h> |
#include <QuickDraw.h> |
#include <Fonts.h> |
#include <StandardFile.h> |
#include <ToolUtils.h> |
#include <Desk.h> |
#include <GestaltEqu.h> |
#include <Movies.h> |
#include <QuickTimeComponents.h> |
#define kExportMenu 155 |
#define kMyCustomSaveDialog 128 |
#define kMyMBar 128 |
#define kAboutBox 129 |
enum { |
menuApple = 128, |
menuFile |
}; |
enum { |
fileImport = 1, |
fileExport, |
fileUnused1, |
fileQuit |
}; |
pascal Boolean myImportFileFilter(ParmBlkPtr PB); |
void importMovie(void); |
pascal Boolean myExportFileFilter(ParmBlkPtr PB); |
pascal short myDlgHook(short item, DialogPtr theDialog, short *whichConverter); |
void exportMovie(void); |
Boolean doMenuItem(long menuChoice); |
// |
// IMPORT MOVIE |
// |
/* |
The import file filter checks the given file to see if there is a |
Movie Import Component available which could translate it into a |
movie. If one is available, the file is allowed to be shown. |
*/ |
pascal Boolean myImportFileFilter(ParmBlkPtr PB) |
{ |
ComponentDescription cd; |
Boolean result = true; // true means we don't want it |
cd.componentType = MovieImportType; |
cd.componentSubType = PB->fileParam.ioFlFndrInfo.fdType; |
cd.componentManufacturer = 0; |
cd.componentFlags = canMovieImportFiles; |
cd.componentFlagsMask = canMovieImportFiles; |
if (FindNextComponent(0, &cd)) // search for component to do the work |
result = false; |
return result; |
} |
void importMovie(void) |
{ |
OSErr err; |
StandardFileReply reply; |
SFReply putFile; |
FSSpec newFile; |
Str255 newName; |
Point where = {100,100}; |
Component c; |
ComponentDescription cd; |
StandardGetFilePreview(myImportFileFilter, 0, nil, &reply); |
if (!reply.sfGood) return; |
BlockMove(reply.sfFile.name, newName, sizeof(reply.sfFile.name)); |
newName[++newName[0]] = '!'; |
SFPutFile(where, "\pName imported movie:", newName, nil, &putFile); |
if (!putFile.good) return; |
FSMakeFSSpec(putFile.vRefNum, 0, putFile.fName, &newFile); |
cd.componentType = MovieImportType; |
cd.componentSubType = reply.sfType; |
cd.componentManufacturer = 0; |
cd.componentFlags = canMovieImportFiles; |
cd.componentFlagsMask = canMovieImportFiles; |
c = FindNextComponent(nil, &cd); |
if (!c) return; // too weird. no import component exists |
GetComponentInfo(c, &cd, nil, nil, nil); |
if (cd.componentFlags & hasMovieImportUserInterface) { |
MovieImportComponent importer; |
Boolean canceled = false; |
importer = OpenComponent(c); |
err = MovieImportDoUserDialog(importer, &reply.sfFile, nil, &canceled); |
if (err || canceled) { |
CloseComponent(importer); |
return; |
} |
err = ConvertFileToMovieFile(&reply.sfFile, &newFile, 'TVOD', reply.sfScript, nil, |
createMovieFileDeleteCurFile, importer, (MovieProgressProcPtr)-1, 0); |
CloseComponent(importer); |
} |
else { |
// no import user interface option, so let the toolbox open the component |
err = ConvertFileToMovieFile(&reply.sfFile, &newFile, 'TVOD', reply.sfScript, nil, |
createMovieFileDeleteCurFile, nil, (MovieProgressProcPtr)-1, 0); |
} |
if (err) { |
SysBeep(1); |
DeleteMovieFile(&newFile); |
} |
} |
// |
// EXPORT MOVIE |
// |
/* |
This file filter is particularly slimey. Standard File Preview automatically tries |
to show all non-movie files that it could convert to movies. In a dialog to select |
a movie to export, we only want to see movies. So what we do here is refetch the |
file type for the selected file via the File System to see if Standard File |
Preview is lying to us about the file type. If the file is indeed a movie, we |
let it be shown. |
*/ |
pascal Boolean myExportFileFilter(ParmBlkPtr PB) |
{ |
FSSpec fss; |
FInfo info; |
FSMakeFSSpec(-*(short *)SFSaveDisk, *(long *)CurDirStore, PB->fileParam.ioNamePtr, &fss); |
FSpGetFInfo(&fss, &info); |
if (info.fdType == MovieFileType) |
return false; |
else |
return true; |
} |
/* |
This skanky hook just constantly (and stupidly) watches the value of the export |
types menu and jams it back into our local variable below. |
*/ |
pascal short myDlgHook(short item, DialogPtr theDialog, short *whichConverter) |
{ |
short kind; |
Handle h; |
Rect r; |
if (GetWRefCon(theDialog) != sfMainDialogRefCon) |
return item; |
GetDItem(theDialog, sfItemNewFolderUser+1, &kind, &h, &r); // first custom item |
*whichConverter = GetCtlValue((ControlHandle)h); |
return item; |
} |
void exportMovie(void) |
{ |
OSErr err; |
StandardFileReply reply, putFile; |
OSType movieType = MovieFileType; |
MenuHandle mh = GetMenu(kExportMenu); |
ComponentDescription cd; |
Component c = 0; |
Point where = {0,0}; |
Str255 newName; |
short convertItem = 1; |
Component **exportComponents; |
Movie theMovie = nil; |
short resRef; |
OSType creator; |
StandardGetFilePreview(myExportFileFilter, 1, &movieType, &reply); |
if (!reply.sfGood) return; |
// get the movie. |
OpenMovieFile(&reply.sfFile, &resRef, fsRdPerm); |
NewMovieFromFile(&theMovie, resRef, nil, nil, |
0, nil); |
CloseMovieFile(resRef); |
if (!theMovie) return; |
SetMovieProgressProc(theMovie, (MovieProgressProcPtr)-1, 0); |
// build a list of all export components which are applicable to this movie |
exportComponents = (Component **)NewHandle(0); |
cd.componentType = MovieExportType; |
cd.componentSubType = 0; |
cd.componentManufacturer = 0; |
cd.componentFlags = canMovieExportFiles; |
cd.componentFlagsMask = canMovieExportFiles; |
while (c = FindNextComponent(c, &cd)) { |
Handle h = NewHandle(4); |
ComponentDescription exportCD; |
if (GetComponentInfo(c, &exportCD, h, nil, nil) == noErr) { |
Str255 s; |
Handle h2 = NewHandle(4); |
ComponentDescription mhcd; |
Component mediaHandler; |
mhcd.componentType = MediaHandlerType; |
mhcd.componentSubType = exportCD.componentManufacturer; |
mhcd.componentManufacturer = 0; |
mhcd.componentFlags = 0; |
mhcd.componentFlagsMask = 0; |
if (mediaHandler = FindNextComponent(0, &mhcd)) { |
long trackCount = GetMovieTrackCount(theMovie); |
long i; |
Boolean foundMedia = true; |
// make sure the media type the component can export is in the movie |
if (exportCD.componentManufacturer) { |
foundMedia = false; |
for (i=1; i<=trackCount; i++) { |
Track t = GetMovieIndTrack(theMovie, i); |
OSType mediaType; |
GetMediaHandlerDescription(GetTrackMedia(t), &mediaType, nil, nil); |
foundMedia = (mediaType == exportCD.componentManufacturer); |
if (foundMedia) break; |
} |
} |
if (foundMedia && (GetComponentInfo(mediaHandler, nil, h2, nil, nil) == noErr)) { |
Str255 s; |
// build menu name in un-international friendly way |
if (exportCD.componentManufacturer) { |
BlockMove(*h2, s, sizeof(s)); |
s[++s[0]] = ' '; |
s[++s[0]] = 't'; |
s[++s[0]] = 'o'; |
s[++s[0]] = ' '; |
} |
else |
s[0] = 0; |
BlockMove(*h + 1, &s[s[0] + 1], **h); |
s[0] += **h; |
AppendMenu(mh, s); |
PtrAndHand((Ptr)&c, (Handle)exportComponents, sizeof(c)); |
DisposHandle(h); |
} |
} |
} |
DisposHandle(h); |
} |
InsertMenu(mh, -1); |
if (GetHandleSize((Handle)exportComponents) == 0) { |
// no export components for this movie are available |
SysBeep(1); |
goto bail; |
} |
BlockMove(reply.sfFile.name, newName, 255); |
newName[++newName[0]] = '!'; |
CustomPutFile("\pExport a file", newName, &putFile, |
kMyCustomSaveDialog, where, (DlgHookYDProcPtr)myDlgHook, |
nil, nil, nil, (void *)&convertItem); |
if (!putFile.sfGood) goto bail; |
GetComponentInfo((*exportComponents)[convertItem - 1], &cd, nil, nil, nil); |
// cheap map in the application to allow us to chose the file creator |
{ |
Handle h = GetResource('fMap', 128); |
short count = GetHandleSize(h) / (sizeof(OSType) * 2); |
OSType *creators = *(OSType **)h; |
creator = '????'; |
while (count-- > 0) { |
if (*creators++ == cd.componentSubType) { |
creator = *creators; |
break; |
} |
creators++; |
} |
} |
if (cd.componentFlags & hasMovieExportUserInterface) { |
MovieExportComponent exporter; |
Boolean canceled = false; |
exporter = OpenComponent((*exportComponents)[convertItem - 1]); |
err = MovieExportDoUserDialog(exporter, &reply.sfFile, nil, &canceled); |
if (err || canceled) { |
CloseComponent(exporter); |
return; |
} |
err = ConvertMovieToFile(theMovie, nil, &putFile.sfFile, |
cd.componentSubType, creator, putFile.sfScript, nil, createMovieFileDeleteCurFile, |
exporter); |
CloseComponent(exporter); |
} |
else { |
// no user interface available. let the movie toolbox do the hard part |
err = ConvertMovieToFile(theMovie, nil, &putFile.sfFile, |
cd.componentSubType, creator, putFile.sfScript, nil, createMovieFileDeleteCurFile, |
(ComponentInstance)(*exportComponents)[convertItem - 1]); |
} |
if (err) |
SysBeep(1); |
bail: |
DeleteMenu(kExportMenu); |
DisposeMenu(mh); |
DisposeMovie(theMovie); |
DisposHandle((Handle)exportComponents); |
} |
Boolean doMenuItem(long menuChoice) |
{ |
Boolean done = false; |
short whichMenu = HiWord(menuChoice); |
short whichItem = LoWord(menuChoice); |
switch (whichMenu) { |
case menuApple: |
if (whichItem > 2) { |
Str255 daName; |
GetItem(GetMHandle(menuApple), whichItem, daName); |
OpenDeskAcc(daName); |
} |
else |
Alert(kAboutBox, nil); |
break; |
case menuFile: |
switch (whichItem) { |
case fileImport: |
importMovie(); |
break; |
case fileExport: |
exportMovie(); |
break; |
case fileQuit: |
done = true; |
break; |
} |
break; |
} |
HiliteMenu(0); |
return done; |
} |
void main(void) |
{ |
OSErr err; |
Boolean done = false; |
long response; |
// initialize the world |
InitGraf(&qd.thePort); |
InitFonts(); |
InitWindows(); |
InitMenus(); |
TEInit(); |
InitDialogs(0L); |
InitCursor(); |
MaxApplZone(); |
// need system 7. slimey check |
// we use pop-up cdef and custom putfile |
if (*(short *)SysVersion < 0x0700) return; |
// must have QuickTime around |
if (Gestalt(gestaltQuickTime, &response)) return; |
err = EnterMovies(); |
if (err) return; |
SetMenuBar(GetNewMBar(kMyMBar)); |
DrawMenuBar(); |
AddResMenu(GetMHandle(menuApple), 'DRVR'); |
while (!done) { |
EventRecord theEvent; |
SystemTask(); |
GetNextEvent(everyEvent, &theEvent); |
switch (theEvent.what) { |
case mouseDown: { |
short part; |
WindowPtr whichWindow; |
part = FindWindow(theEvent.where, &whichWindow); |
switch (part) { |
case inMenuBar: |
done = doMenuItem(MenuSelect(theEvent.where)); |
break; |
case inSysWindow: |
SystemClick(&theEvent, whichWindow); |
break; |
} |
} |
break; |
case keyDown: { |
char c; |
c = theEvent.message & charCodeMask; |
if (theEvent.modifiers & cmdKey) |
done = doMenuItem(MenuKey(c)); |
} |
break; |
} |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14