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.
src/FrameStepper.java
////////// |
// |
// QuickTime for Java SDK Sample Code |
// |
// Usage subject to restrictions in SDK License Agreement |
// Copyright: © 1996-1999 Apple Computer, Inc. |
// |
// Contains: Functions to step frame-by-frame through a QuickTime movie. |
// |
// |
// This file defines functions that you can use to step frame-by-frame through a QuickTime movie. |
// Indeed, it illustrates *two* different methods for doing this: (1) using Movie Toolbox functions |
// to advance (or retreat) to interesting times in the movie; and (2) using movie controller actions |
// to step forward or backward through a movie. To my knowledge, there are no particular advantages |
// to using one or the other method, except that the second method is (as you will see) quite a bit |
// simpler to code. |
// |
// METHOD ONE: Use Movie Toolbox calls to step to interesting times in the movie. An interesting time |
// is a time value in a movie, track, or media that meets certain search conditions that you specify. |
// We'll use a very simple search condition: locate the next (or previous) sample in the movie's media. |
// Once we have an interesting time, we display the sample at that time by calling SetMovieTimeValue. |
// To implement this first method, we define three functions (which all operate on an open movie): |
// |
// -> GoToNextVideoSample: display the sample that follows the current sample in a movie |
// -> GoToPrevVideoSample: display the sample that precedes the current sample in a movie |
// -> GoToFirstVideoSample: display the first video sample in a movie |
// |
// Internally, these functions depend on three functions defined at the beginning of this file. |
// The code here is extremely straightforward. The only "gotcha" concerns finding the first |
// interesting time in a movie. See the description of GetStartTimeOfFirstVideoSample for |
// details. |
// |
// METHOD TWO: Use movie controller actions to step through frames in the movie. Using this method, |
// the code is considerably simpler. To implement this second method, we define three functions |
// (which all operate on a movie controller that is associated with an open movie): |
// |
// -> MCGoToNextVideoSample: display the sample that follows the current sample in a movie |
// -> MCGoToPrevVideoSample: display the sample that precedes the current sample in a movie |
// -> MCGoToFirstVideoSample: display the first video sample in a movie |
// |
// |
////////// |
import java.awt.*; |
import java.awt.event.*; |
import java.applet.*; |
import java.io.IOException; |
import quicktime.*; |
import quicktime.std.*; |
import quicktime.std.movies.*; |
import quicktime.std.clocks.*; |
////////// |
// |
// FrameStepper class |
// |
////////// |
public class FrameStepper { |
// |
// METHOD 1: Use Movie Toolbox calls to step to interesting times in the movie. |
// |
////////// |
// |
// GetStartTimeOfFirstVideoSample |
// Return, through the TimeInfo parameter, the starting time of the first video sample of the |
// specified QuickTime movie. |
// |
// The "trick" here is to set the nextTimeEdgeOK flag, to indicate that you want to get the |
// starting time of the beginning of the movie. |
// |
////////// |
TimeInfo GetStartTimeOfFirstVideoSample (Movie theMovie) |
{ |
try |
{ |
TimeInfo interestingTime; |
int interestingTimeFlags; |
int myTypes[] = new int[] {StdQTConstants.visualMediaCharacteristic}; |
float theRate = 1.0f; |
int bogusStartTime = -1; |
// specify we want the first sample in the movie |
interestingTimeFlags = StdQTConstants.nextTimeMediaSample + StdQTConstants.nextTimeEdgeOK; |
// get the time of the first sample |
interestingTime = theMovie.getNextInterestingTime(interestingTimeFlags, |
myTypes, |
bogusStartTime, /* bogus start time */ |
theRate); |
return(interestingTime); |
} |
catch (QTException err) |
{ |
err.printStackTrace(); |
} |
return(null); |
} |
////////// |
// |
// DrawVideoSampleAtTime |
// Draw the video sample of a QuickTime movie at the specified time. |
// |
////////// |
void DrawVideoSampleAtTime (Movie theMovie, int theTime) |
{ |
try |
{ |
short myFlags; |
long timeValue; |
// make sure that the specified time lies within the movie's temporal bounds |
if ((theTime < 0) || (theTime > theMovie.getDuration())) |
return; |
// set current movie time to the desired value |
theMovie.setTimeValue(theTime); |
// the following calls to UpdateMovie and MoviesTask are not necessary |
// if you are handling movie controller events in your main event loop |
// (by passing the event to MCIsPlayerEvent); they don't hurt, however. |
// redraw the movie immediately by calling UpdateMovie and MoviesTask |
theMovie.update(); |
theMovie.task(0); |
} |
catch (QTException err) |
{ |
err.printStackTrace(); |
} |
} |
////////// |
// |
// DrawVideoSampleNextOrPrev |
// Draw the next or previous video sample of a QuickTime movie. |
// If theRate is 1, the next video sample is drawn; if theRate is -1, the previous sample is drawn. |
// |
////////// |
void DrawVideoSample(Movie theMovie, float theRate) |
{ |
try |
{ |
TimeInfo timeInfo; |
int movieCurrentTime; |
int interestingTimeFlags; |
int mediaTypes[] = new int[] {StdQTConstants.visualMediaCharacteristic}; |
// specify we want the next frame in the movie's media |
interestingTimeFlags = StdQTConstants.nextTimeStep; |
// get the current movie time |
movieCurrentTime = theMovie.getTime(); |
// get current sample at this time |
timeInfo = theMovie.getNextInterestingTime(interestingTimeFlags, |
mediaTypes, |
movieCurrentTime, |
theRate); |
// now draw the sample for the current time |
DrawVideoSampleAtTime(theMovie, timeInfo.time); |
} |
catch (QTException err) |
{ |
err.printStackTrace(); |
} |
} |
////////// |
// |
// DrawVideoSampleNext |
// Draw the next video sample of a QuickTime movie. |
// |
////////// |
void DrawVideoSampleNext (Movie theMovie) |
{ |
DrawVideoSample(theMovie, 1.0f); |
} |
////////// |
// |
// DrawVideoSamplePrev |
// Draw the previous video sample of a QuickTime movie. |
// |
////////// |
void DrawVideoSamplePrev (Movie theMovie) |
{ |
DrawVideoSample(theMovie, -1.0f); |
} |
////////// |
// |
// GoToFirstVideoSample |
// Draw the first video sample of a QuickTime movie. |
// |
////////// |
void GoToFirstVideoSample (Movie theMovie) |
{ |
TimeInfo timeInfo; |
timeInfo = GetStartTimeOfFirstVideoSample(theMovie); |
DrawVideoSampleAtTime(theMovie, timeInfo.time); |
} |
// |
// METHOD 2: Use Movie Controller calls to step to interesting times in the movie. |
// |
////////// |
// |
// MCGoToFirstVideoSample |
// Draw the first video sample of the QuickTime movie associated with the specified movie controller. |
// |
////////// |
void MCGoToFirstVideoSample (MovieController theMC) |
{ |
try { |
Movie theMovie = theMC.getMovie(); |
TimeRecord myTimeRecord = new TimeRecord(theMovie.getTimeScale(),0); |
theMC.goToTime(myTimeRecord); |
} |
catch (QTException err) |
{ |
err.printStackTrace(); |
} |
} |
////////// |
// |
// MCGoToNextVideoSample |
// Draw the next video sample of the QuickTime movie associated with the specified movie controller. |
// |
////////// |
void MCGoToNextVideoSample (MovieController theMC) |
{ |
try { |
int stepCount = 1; // advance the movie one frame |
theMC.step(stepCount); |
} |
catch (QTException err) |
{ |
err.printStackTrace(); |
} |
} |
////////// |
// |
// MCGoToPrevVideoSample |
// Draw the previous video sample of the QuickTime movie associated with the specified movie controller. |
// |
////////// |
void MCGoToPrevVideoSample (MovieController theMC) |
{ |
try { |
int stepCount = -1; // back the movie up one frame |
theMC.step(stepCount); |
} |
catch (QTException err) |
{ |
err.printStackTrace(); |
} |
} |
} /* end FrameStepper class */ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14