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.
AddFrameToMovie.c
/* |
File: AddFrameToMovie.c |
Contains: Adding a Frame to the End of an Existing Movie. |
How To Test: |
Run the application, open a movie file, the application will now add an additional |
frame at the end of this existing movie. |
Written by: John Wang |
Copyright: Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/28/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
12/4/94 khs changed the format of the file to the new look and feel |
94 JW Fixed error where ind was assumed to be 0 based |
rather than 1 based. And, added code to update |
movie rather than require a flatten movie for |
saving the new edited movie. |
*/ |
// INCLUDES |
#include <GestaltEqu.h> |
#include <Segload.h> |
#include <ToolUtils.h> |
#include <Devices.h> |
#include <Errors.h> |
#include <Movies.h> |
// DEFINES |
#define Gestalttest 0xA1AD |
#define NoTrap 0xA89F |
#define appleID 128 |
#define appleMenu 0 |
#define aboutMeCommand 1 |
#define fileID 129 |
#define openCommand 1 |
#define flattenCommand 2 |
#define closeCommand 3 |
#define quitCommand 5 |
#define aboutMeDLOG 128 |
#define okButton 1 |
#define MAXWINDOWS 5 |
// FUNCTION PROTOTYPES |
Movie GetMovieFromFile(void); |
OSErr PlayMovie(int index); |
short Flatten(int index); |
void showAboutMeDialog(void); |
void Init(void); |
void Finish(void); |
void DoOpenCommand(void); |
void DoFlattenCommand(void); |
void DoCloseCommand(void); |
void PlayMovies(void); |
void DoCommand(long mResult); |
// GLOBALS |
Boolean DoneFlag = false; |
MenuHandle mymenu0, mymenu1; |
Boolean playingMovie[MAXWINDOWS]; |
Movie myMovie[MAXWINDOWS]; |
WindowPtr myWindow[MAXWINDOWS]; |
int startlocation; |
// FUNCTIONS |
/*------------------------------------------------------*/ |
/* GetMovieFromFile(). */ |
/*------------------------------------------------------*/ |
Movie GetMovieFromFile(void) |
{ |
OSErr err; |
StandardFileReply reply; |
Point where = |
{ |
200, 50 |
}; |
SFTypeList types; |
short movieResRefNum; |
short actualResId; |
Movie theMovie; |
long i, |
maxCompressionSize; |
Track myVideoTrack; |
Media myVideoMedia; |
OSType myMediaType; |
Boolean done = false; |
GWorldPtr myGWorld; |
Rect movieBounds; |
GDHandle oldGDevice; |
CGrafPtr oldPort; |
Handle compressedData; |
ImageDescriptionHandle imageDescH; |
TimeValue sampleDuration; |
int x,y; |
types[0] = 'MooV'; |
StandardGetFilePreview(nil, 1, types, &reply); |
if (!reply.sfGood) |
return ((Movie)0); |
err = OpenMovieFile(&reply.sfFile, &movieResRefNum, fsWrPerm); |
if (GetMoviesError()) |
return ((Movie)0); |
if (err) |
return ((Movie)0); |
actualResId = 0; |
err = NewMovieFromFile(&theMovie, movieResRefNum, &actualResId, |
(StringPtr)0, newMovieActive, (Boolean *)0); |
if (GetMoviesError()) |
return ((Movie)0); |
if (err) |
return ((Movie)0); |
/* This is where I add a frame to the end of the movie's video track. */ |
for (i = 1; ((i <= GetMovieTrackCount(theMovie)) && (!done)); i++) |
{ |
myVideoTrack = GetMovieIndTrack(theMovie, i); |
myVideoMedia = GetTrackMedia(myVideoTrack); |
GetMediaHandlerDescription(myVideoMedia, &myMediaType, nil, nil); |
if (myMediaType == VideoMediaType) |
done = true; |
} |
if (done == false) |
DebugStr("\pMovie contains no video tracks."); |
else |
{ |
if (BeginMediaEdits(myVideoMedia)) |
DebugStr("\pBeginMediaEdits failed."); |
GetMovieBox(theMovie, &movieBounds); |
if (NewGWorld(&myGWorld, 1, &movieBounds, nil, nil, 0)) |
DebugStr("\pNewGWorld failed."); |
GetGWorld(&oldPort, &oldGDevice); |
SetGWorld(myGWorld, nil); |
LockPixels(GetGWorldPixMap(myGWorld)); |
EraseRect(&movieBounds); |
x=movieBounds.right/2; |
y=movieBounds.bottom/2; |
MoveTo(x, y); |
DrawString("\pHi there"); |
imageDescH = (ImageDescriptionHandle)NewHandle(4); |
if (GetMaxCompressionSize(GetGWorldPixMap(myGWorld), &movieBounds, 1, |
codecNormalQuality, 'raw ', anyCodec, &maxCompressionSize)) |
DebugStr("\pCompressImage."); |
compressedData = NewHandle(maxCompressionSize); |
if (compressedData == nil) |
DebugStr("\pCould not allocate compressedData block"); |
MoveHHi(compressedData); |
HLock(compressedData); |
if (CompressImage(GetGWorldPixMap(myGWorld), &movieBounds, codecNormalQuality, |
'raw ', imageDescH, StripAddress(*compressedData))) |
DebugStr("\pCompressImage."); |
if (AddMediaSample(myVideoMedia, compressedData, 0, (**imageDescH).dataSize, |
GetMediaTimeScale(myVideoMedia), (SampleDescriptionHandle)imageDescH, |
1, 0, &sampleDuration)) |
DebugStr("\pInsertMediaIntoTracks."); |
if (InsertMediaIntoTrack(myVideoTrack, GetTrackDuration(myVideoTrack), sampleDuration, |
GetMediaTimeScale(myVideoMedia), 0x00010000)) |
DebugStr("\pInsertMediaIntoTracks."); |
if (EndMediaEdits(myVideoMedia)) |
DebugStr("\pEndMediaEdits failed."); |
SetGWorld(oldPort, oldGDevice); |
HUnlock(compressedData); |
DisposeGWorld(myGWorld); |
DisposeHandle(compressedData); |
DisposeHandle((Handle)imageDescH); |
} |
err = UpdateMovieResource(theMovie, movieResRefNum, actualResId, nil); |
if (err != noErr) |
DebugStr("\pUpdateResource failed."); |
/* This is the end of the code for adding the one frame to the movie. */ |
err = CloseMovieFile(movieResRefNum); |
if (GetMoviesError()) |
return ((Movie)0); |
if (err) |
return ((Movie)0); |
return (theMovie); |
} |
/*------------------------------------------------------*/ |
/* PlayMovie(). */ |
/*------------------------------------------------------*/ |
OSErr PlayMovie(int index) |
{ |
Rect movieBounds; |
GetMovieBox(myMovie[index], &movieBounds); |
OffsetRect(&movieBounds, -movieBounds.left, -movieBounds.top); |
if (movieBounds.right < 40) |
movieBounds.right = 40; |
if (movieBounds.bottom < 20) |
movieBounds.bottom = 20; |
SetMovieBox(myMovie[index], &movieBounds); |
OffsetRect(&movieBounds, startlocation, startlocation); |
myWindow[index] = NewCWindow(0L, &movieBounds, "\pMovie!", 1, 0, |
(WindowPtr) - 1, true, 0L); |
startlocation += 50; |
if (startlocation > 300) |
startlocation = 50; |
SetMovieGWorld(myMovie[index], (CGrafPtr)myWindow[index], 0); |
if (GetMoviesError()) |
DebugStr("\pSetMovieGWorld error."); |
/* Uncomment these lines if you want to pre load the movie into ram. |
GotoBeginningOfMovie(myMovie[index]); |
if (LoadMovieIntoRam(myMovie[index], GetMovieTime(myMovie[index], 0L), |
GetMovieDuration(myMovie[index]), |
0) != noErr) |
DebugStr("\pNot enough memory to load movie into ram."); |
*/ |
SetMovieRate(myMovie[index], 0x00010000); |
return noErr; |
} |
/*------------------------------------------------------*/ |
/* Flatten(). */ |
/*------------------------------------------------------*/ |
short Flatten(int index) |
{ |
StandardFileReply reply; |
OSErr theErr = noErr; |
StandardPutFile("\pName of Flattened movie.", "\pUntitled", &reply); |
if (!reply.sfGood) |
return fnOpnErr; |
theErr = GetMoviesError(); |
if (theErr != noErr) |
DebugStr("\pCall Before FlattenMovies failed."); |
FlattenMovie(myMovie[index], flattenAddMovieToDataFork, &reply.sfFile, |
'TWOD', 0, createMovieFileDeleteCurFile, nil, nil); |
theErr = GetMoviesError(); |
if (theErr != noErr) |
DebugStr("\pFlattenMovies failed."); |
return (theErr); |
} |
/*------------------------------------------------------*/ |
/* showAboutMeDialog() */ |
/*------------------------------------------------------*/ |
void showAboutMeDialog(void) |
{ |
GrafPtr savePort; |
DialogPtr theDialog; |
short itemHit; |
GetPort(&savePort); |
theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) - 1); |
SetPort(theDialog); |
do |
{ |
ModalDialog(nil, &itemHit); |
} while (itemHit != okButton); |
CloseDialog(theDialog); |
SetPort(savePort); |
return; |
} |
/*------------------------------------------------------*/ |
/* Init(). */ |
/*------------------------------------------------------*/ |
void Init(void) |
{ |
OSErr err; |
int i; |
long QDfeature, |
OSfeature; |
/* Initialize Managaer. */ |
InitGraf(&qd.thePort); |
FlushEvents(everyEvent, 0); |
InitWindows(); |
InitDialogs(nil); |
InitCursor(); |
/* Set up menus. */ |
mymenu0 = GetMenu(appleID); |
AppendResMenu(mymenu0, 'DRVR'); |
InsertMenu(mymenu0, 0); |
mymenu1 = GetMenu(fileID); |
InsertMenu(mymenu1, 0); |
DrawMenuBar(); |
/* Set up variables. */ |
startlocation = 50; |
for (i = 0; i < MAXWINDOWS; i++) |
{ |
playingMovie[i] = false; |
myWindow[i] = nil; |
} |
/* Use Gestalt to find if QuickDraw and QuickTime is available. */ |
if ((NGetTrapAddress(Gestalttest,OSTrap) != NGetTrapAddress(NoTrap,OSTrap))) |
{ |
err = Gestalt(gestaltQuickdrawVersion, &QDfeature); |
if (err) |
ExitToShell(); |
err = Gestalt(gestaltSystemVersion, &OSfeature); |
if (err) |
ExitToShell(); |
if (!DoneFlag && (QDfeature & 0x0f00) != 0x0200 && OSfeature < 0x0607) |
ExitToShell(); |
err = Gestalt(gestaltQuickTime, &QDfeature); |
if (err) |
ExitToShell(); |
} |
else |
ExitToShell(); |
/* Open QuickTime last. */ |
err = EnterMovies(); |
if (err) |
ExitToShell(); |
} |
/*------------------------------------------------------*/ |
/* Finish(). */ |
/*------------------------------------------------------*/ |
void Finish(void) |
{ |
ExitMovies(); |
ExitToShell(); |
} |
/*------------------------------------------------------*/ |
/* DoOpenCommand(). */ |
/*------------------------------------------------------*/ |
void DoOpenCommand(void) |
{ |
int i, |
useThisIndex; |
useThisIndex = -1; |
/* Search for the first window that is nil. */ |
for (i = MAXWINDOWS - 1; i >= 0; i--) |
if (myWindow[i] == nil) |
useThisIndex = i; |
/* If index = -1, then it means that there are no windows avaiable. */ |
if (useThisIndex != -1) |
{ |
myMovie[useThisIndex] = GetMovieFromFile(); |
if (myMovie[useThisIndex] != 0) |
{ |
PlayMovie(useThisIndex); |
playingMovie[useThisIndex] = true; |
} |
} |
} |
/*------------------------------------------------------*/ |
/* DoFlattenCommand(). */ |
/*------------------------------------------------------*/ |
void DoFlattenCommand(void) |
{ |
int i; |
WindowPtr myTempWindow; |
/* Flatten movie that is currently selected. */ |
myTempWindow = FrontWindow(); |
if (myTempWindow == nil) |
return; |
for (i = 0; i < MAXWINDOWS; i++) |
if (myWindow[i] == myTempWindow) |
Flatten(i); |
} |
/*------------------------------------------------------*/ |
/* DoCloseCommand(). */ |
/*------------------------------------------------------*/ |
void DoCloseCommand(void) |
{ |
int i; |
WindowPtr myTempWindow; |
/* Close selected window. */ |
myTempWindow = FrontWindow(); |
if (myTempWindow == nil) |
return; |
for (i = 0; i < MAXWINDOWS; i++) |
if (myWindow[i] == myTempWindow) |
{ |
DisposeMovie(myMovie[i]); |
DisposeWindow(myTempWindow); |
playingMovie[i] = false; |
myWindow[i] = nil; |
} |
} |
/*------------------------------------------------------*/ |
/* DoCommand(). */ |
/*------------------------------------------------------*/ |
void DoCommand(long mResult) |
{ |
int theMenu, |
theItem; |
Str255 daName; |
GrafPtr savePort; |
theItem = LoWord(mResult); |
theMenu = HiWord(mResult); |
switch (theMenu) |
{ |
case appleID: |
if (theItem == aboutMeCommand) |
showAboutMeDialog(); |
else |
{ |
GetMenuItemText(mymenu0, theItem, daName); |
GetPort(&savePort); |
(void)OpenDeskAcc(daName); |
SetPort(savePort); |
} |
break; |
case fileID: |
switch (theItem) |
{ |
case openCommand: |
DoOpenCommand(); |
break; |
case flattenCommand: |
DoFlattenCommand(); |
break; |
case closeCommand: |
DoCloseCommand(); |
break; |
case quitCommand: |
DoneFlag = true; |
break; |
default: |
break; |
} |
break; |
} |
HiliteMenu(0); |
return; |
} |
/*------------------------------------------------------*/ |
/* PlayMovies(). */ |
/*------------------------------------------------------*/ |
void PlayMovies(void) |
{ |
int i; |
for (i = 0; i < MAXWINDOWS; i++) |
if (playingMovie[i] == true) |
{ |
if (IsMovieDone(myMovie[i]) == false) |
MoviesTask(myMovie[i], DoTheRightThing); |
} |
} |
/*------------------------------------------------------*/ |
/* main(). */ |
/*------------------------------------------------------*/ |
main() |
{ |
int i; |
char key; |
Boolean track; |
EventRecord myEvent; |
WindowPtr whichWindow; |
int yieldTime; |
Init(); |
yieldTime = 0; |
for (;;) |
{ |
/* We can't just do ExitToShell because we must cann ExitMovies. */ |
if (DoneFlag) |
Finish(); |
/* Play movies which are active. */ |
PlayMovies(); |
if (WaitNextEvent(everyEvent, &myEvent, yieldTime, nil)) |
{ |
switch (myEvent.what) |
{ |
case mouseDown: |
switch (FindWindow(myEvent.where, &whichWindow)) |
{ |
case inSysWindow: |
SystemClick(&myEvent, whichWindow); |
break; |
case inMenuBar: |
DoCommand(MenuSelect(myEvent.where)); |
break; |
case inContent: |
SelectWindow(whichWindow); |
break; |
case inDrag: |
DragWindow(whichWindow, myEvent.where, &qd.screenBits.bounds); |
break; |
case inGrow: |
break; |
case inGoAway: |
track = TrackGoAway(whichWindow, myEvent.where); |
if (track) |
DoCloseCommand(); |
break; |
case inZoomIn: |
break; |
case inZoomOut: |
break; |
default: |
break; |
} |
break; |
case keyDown: |
case autoKey: |
key = myEvent.message & charCodeMask; |
if (myEvent.modifiers & cmdKey) |
if (myEvent.what == keyDown) |
DoCommand(MenuKey(key)); |
break; |
case updateEvt: |
for (i = 0; i < MAXWINDOWS; i++) |
if ((WindowPtr)myEvent.message == myWindow[i]) |
{ |
BeginUpdate((WindowPtr)myWindow[i]); |
EndUpdate((WindowPtr)myWindow[i]); |
} |
break; |
case diskEvt: |
break; |
case activateEvt: |
break; |
case app4Evt: |
break; |
default: |
break; |
} |
} |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14