Playing a Video

An OSP video is any class that implements the media.Video interface. Since Video extends display.Interactive, videos are drawable objects that can respond to mouse input. There are many additional methods in the Video interface that enable videos to be played and manipulated. These methods will be presented a few at a time.

Figure 3. Playing a Video

Playing a video

Loading and Displaying a Video

Listing 3 shows an example (screenshot above) that uses QTVideo, the QuickTime implementation of Video, to load and play a video file. By default, the video.play() method plays the video to its end and then stops; here we have turned on looping so the video loops when played (i.e., replays continuously).

Listing 3. VideoDrawingApp

import java.io.IOException;
import javax.swing.JFrame;
import org.opensourcephysics.display.*;
import org.opensourcephysics.media.*;
import org.opensourcephysics.media.quicktime.*;

public class VideoDrawingApp {

public static void main(String[] args) {

// create the video
Video video = null;
try {
video = new QTVideo("videos/Pendulum.mov");
} catch(IOException ex) {}

// play the video looping
video.setLooping(true);
video.play();

// display the video in a drawing panel
DrawingPanel panel = new DrawingPanel();
panel.addDrawable(video);
panel.repaint(); // be sure the video displays
DrawingFrame frame = new DrawingFrame(panel);
frame.setVisible(true);

// set up the Java and QuickTime exit mechanisms
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
QT.exitOnClose(frame);
}
}

Note that the QTVideo object is instantiated before creating the drawing panel and frame. This prevents deadlocks that can occur when the panel attempts to draw itself on screen while the QTVideo is loading a file. (Another option is to initially display only a panel and control, then create the video in response to a user action such as a button press.) Also note that after the video is added to the drawing panel, the panel is repainted to ensure that the video is drawn. While this is not always necessary, it is a good practice.

QTVideo is a versatile class that can load and display any file format supported by QuickTime. In addition to the QTVideo(String movieName) constructor used above, which loads the named video from a file or URL, there is a no-argument constructor which displays a standard open file dialog box.

Other implementations of Video include GifVideo, which wraps animated gif files, and ImageVideo, which opens jpeg images. JMFVideo (not yet complete) will open video files using the Java Media Foundation classes.

Providing a Video Player

In most applications, videos should be accompanied by a video player that allows the user to easily move to and replay sections of interest using the mouse or keyboard. A VideoPanel is an InteractiveDrawingPanel that integrates such a player.

Some useful VideoPanel methods are shown in Listing 4. The setVideo(Video) method replaces the panel's existing video (if any) with a new one. The video may be set to null. A video panel can display at most one video at a time. The player is visible by default.

Listing 4. VideoPanel Methods

public VideoPanel(); // constructs a panel with player but no video
public VideoPanel(Video video); // constructs a panel with player and video
public void setVideo(Video newVideo);
public VideoPlayer getPlayer();
public void setPlayerVisible(boolean visible);

Figure 4. Video Panel with Default Player

Video panel with player

A code fragment from an application that uses a video panel to display a video (screenshot above) is shown in Listing 5. Note that the video is automatically added to the panel and repainted when specified in the constructor. When additional Drawable objects are added to the panel, they are always drawn on top of the video (i.e. as overlays).

Listing 5. VideoPanelApp fragment

// display the video in a video panel
VideoPanel vidPanel = new VideoPanel(video);
DrawingFrame frame = new DrawingFrame(vidPanel);
frame.setVisible(true);

Defining a Video Clip

The VideoPlayer does not play the video directly. Instead, it plays a VideoClip ("clip") that defines a set of equally spaced steps in the video. The player always has a clip to play even if the video is null. The clip is accessed with the VideoPlayer.getVideoClip() method.

A VideoClip defines its steps using three parameters: a start frame, a step size and a step count. The start frame is the frame number of the first step, the step size is the frame increment between successive steps, and the step count is the number of steps in the clip. For example, a clip with start frame 3, step size 2 and step count 5 would have step numbers 0, 1, 2, 3 and 4 that map to video frame numbers 3, 5, 7, 9 and 11, respectively.

A clip need not reference an actual video, though it normally does. It is simply a mapping of step to frame number. Clips with no videos are essentially animations with a player.

A list of VideoClip methods is shown in Listing 6. The stepToFrame() and frameToStep() methods convert between step and frame number, and the containsFrame() method returns true if the specified frame is a step frame. The getClipInspector() method is discussed below.

Listing 6. VideoClip methods

public void setStartFrameNumber(int start);
public void setStepSize(int size);
public void setStepCount(int count);
public int stepToFrame(int stepNumber);
public int frameToStep(int n);
public boolean includesFrame(int n);
public ClipInspector getClipInspector();

A code fragment from an application that sets some video clip properties is shown in Listing 7. Note that the clip is accessible only after the video panel is created, and the clip only specifies steps in the panel's current video. If the video is replaced, a new clip will be created with default start frame 0, step size 1 and frame count equal to the frame count of the new video.

Listing 7. VideoClipApp fragment

// set some clip properties
VideoClip clip = vidPanel.getPlayer().getVideoClip();
clip.setStartFrameNumber(3);
clip.setStepSize(4);

The Clip Inspector

The VideoClip.getClipInspector() method returns a ClipInspector dialog with text fields that allow a user to set the clip's properties. If the clip references a video, the dialog also displays thumbnail images of the video start frame and end frame. The text fields can be individually disabled to prevent a user from changing a parameter.

Figure 5. Clip Inspector

Clip inspector

The video player has a (normally hidden) clip inspector button that can be shown with the VideoPlayer.setInspectorButtonVisible(boolean) method. Clicking the button displays the clip inspector.

Figure 6. Player with Clip Inspector Button (in Floating Toolbar)

Player with clip inspector button

Video Frame

The VideoFrame class, which like DrawingFrame extends OSPFrame, provides menus that enable a user to open video files, record videos with overlays, and save and load xml files of video and coordinate system data.

Listing 8. VideoPanelApp fragment with VideoFrame

// display the video in a video panel
VideoPanel vidPanel = new VideoPanel(video);
DrawingFrame frame = new VideoFrame(vidPanel); // note VideoFrame here
frame.setVisible(true);

Listing 8 shows how to change the VideoPanelApp code fragment from Listing 5 to display the video panel in a video frame. The screenshot below shows the resulting application and the video frame menus.

Figure 7. Video Frame File Menu

Video frame and menus