Java tutorial
/* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940 */ import javax.media.*; import javax.media.format.*; import javax.media.protocol.*; import java.util.*; /******************************************************************************* * A simple application to allow users to capture audio or video through devices * connected to the PC. Via command-line arguments the user specifies whether * audio (-a) or video (-v) capture, the duration of the capture (-d) in * seconds, and the file to write the media to (-f). * * The application would be far more useful and versatile if it provided control * over the formats of the audio and video captured as well as the content type * of the output. * * The class searches for capture devices that support the particular default * track formats: linear for audio and Cinepak for video. As a fall-back two * device names are hard-coded into the application as an example of how to * obtain DeviceInfo when a device's name is known. The user may force the * application to use these names by using the -k (known devices) flag. * * The class is static but employs the earlier Location2Location example to * perform all the Processor and DataSink related work. Thus the application * chiefly involves CaptureDevice related operations. * * @author Michael (Spike) Barlow ******************************************************************************/ public class SimpleRecorder { ///////////////////////////////////////////////////////////// // Names for the audio and video capture devices on the // author's system. These will vary system to system but are // only used as a fallback. ///////////////////////////////////////////////////////////// private static final String AUDIO_DEVICE_NAME = "DirectSoundCapture"; private static final String VIDEO_DEVICE_NAME = "vfw:Microsoft WDM Image Capture:0"; /////////////////////////////////////////////////////////// // Default names for the files to write the output to for // the case where they are not supplie by the user. ////////////////////////////////////////////////////////// private static final String DEFAULT_AUDIO_NAME = "file://./captured.wav"; private static final String DEFAULT_VIDEO_NAME = "file://./captured.avi"; /////////////////////////////////////////// // Type of capture requested by the user. ////////////////////////////////////////// private static final String AUDIO = "audio"; private static final String VIDEO = "video"; private static final String BOTH = "audio and video"; //////////////////////////////////////////////////////////////////// // The only audio and video formats that the particular application // supports. A better program would allow user selection of formats // but would grow past the small example size. //////////////////////////////////////////////////////////////////// private static final Format AUDIO_FORMAT = new AudioFormat(AudioFormat.LINEAR); private static final Format VIDEO_FORMAT = new VideoFormat(VideoFormat.CINEPAK); public static void main(String[] args) { ////////////////////////////////////////////////////// // Object to handle the processing and sinking of the // data captured from the device. ////////////////////////////////////////////////////// Location2Location capture; ///////////////////////////////////// // Audio and video capture devices. //////////////////////////////////// CaptureDeviceInfo audioDevice = null; CaptureDeviceInfo videoDevice = null; ///////////////////////////////////////////////////////////// // Capture device's "location" plus the name and location of // the destination. ///////////////////////////////////////////////////////////// MediaLocator captureLocation = null; MediaLocator destinationLocation; String destinationName = null; //////////////////////////////////////////////////////////// // Formats the Processor (in Location2Location) must match. //////////////////////////////////////////////////////////// Format[] formats = new Format[1]; /////////////////////////////////////////////// // Content type for an audio or video capture. ////////////////////////////////////////////// ContentDescriptor audioContainer = new ContentDescriptor(FileTypeDescriptor.WAVE); ContentDescriptor videoContainer = new ContentDescriptor(FileTypeDescriptor.MSVIDEO); ContentDescriptor container = null; //////////////////////////////////////////////////////////////////// // Duration of recording (in seconds) and period to wait afterwards /////////////////////////////////////////////////////////////////// double duration = 10; int waitFor = 0; ////////////////////////// // Audio or video capture? ////////////////////////// String selected = AUDIO; //////////////////////////////////////////////////////// // All devices that support the format in question. // A means of "ensuring" the program works on different // machines with different capture devices. //////////////////////////////////////////////////////// Vector devices; ////////////////////////////////////////////////////////// // Whether to search for capture devices that support the // format or use the devices whos names are already // known to the application. ////////////////////////////////////////////////////////// boolean useKnownDevices = false; ///////////////////////////////////////////////////////// // Process the command-line options as to audio or video, // duration, and file to save to. ///////////////////////////////////////////////////////// for (int i = 0; i < args.length; i++) { if (args[i].equals("-d")) { try { duration = (new Double(args[++i])).doubleValue(); } catch (NumberFormatException e) { } } else if (args[i].equals("-w")) { try { waitFor = Integer.parseInt(args[++i]); } catch (NumberFormatException e) { } } else if (args[i].equals("-a")) { selected = AUDIO; } else if (args[i].equals("-v")) { selected = VIDEO; } else if (args[i].equals("-b")) { selected = BOTH; } else if (args[i].equals("-f")) { destinationName = args[++i]; } else if (args[i].equals("-k")) { useKnownDevices = true; } else if (args[i].equals("-h")) { System.out.println( "Call as java SimpleRecorder [-a | -v | -b] [-d duration] [-f file] [-k] [-w wait]"); System.out.println("\t-a\tAudio\n\t-v\tVideo\n\t-b\tBoth audio and video (system dependent)"); System.out.println("\t-d\trecording Duration (seconds)"); System.out .println("\t-f\tFile to save to\n\t-k\tuse Known device names (don't search for devices)"); System.out.println("\t-w\tWait the specified time (seconds) before abandoning capture"); System.out.println( "Defaults: 10 seconds, audio, and captured.wav or captured.avi, 4x recording duration wait"); System.exit(0); } } ///////////////////////////////////////////////////////////////// // Perform setup for audio capture. Includes finding a suitable // device, obatining its MediaLocator and setting the content // type. //////////////////////////////////////////////////////////////// if (selected.equals(AUDIO)) { devices = CaptureDeviceManager.getDeviceList(AUDIO_FORMAT); if (devices.size() > 0 && !useKnownDevices) { audioDevice = (CaptureDeviceInfo) devices.elementAt(0); } else audioDevice = CaptureDeviceManager.getDevice(AUDIO_DEVICE_NAME); if (audioDevice == null) { System.out.println("Can't find suitable audio device. Exiting"); System.exit(1); } captureLocation = audioDevice.getLocator(); formats[0] = AUDIO_FORMAT; if (destinationName == null) destinationName = DEFAULT_AUDIO_NAME; container = audioContainer; } ///////////////////////////////////////////////////////////////// // Perform setup for video capture. Includes finding a suitable // device, obatining its MediaLocator and setting the content // type. //////////////////////////////////////////////////////////////// else if (selected.equals(VIDEO)) { devices = CaptureDeviceManager.getDeviceList(VIDEO_FORMAT); if (devices.size() > 0 && !useKnownDevices) videoDevice = (CaptureDeviceInfo) devices.elementAt(0); else videoDevice = CaptureDeviceManager.getDevice(VIDEO_DEVICE_NAME); if (videoDevice == null) { System.out.println("Can't find suitable video device. Exiting"); System.exit(1); } captureLocation = videoDevice.getLocator(); formats[0] = VIDEO_FORMAT; if (destinationName == null) destinationName = DEFAULT_VIDEO_NAME; container = videoContainer; } else if (selected.equals(BOTH)) { captureLocation = null; formats = new Format[2]; formats[0] = AUDIO_FORMAT; formats[1] = VIDEO_FORMAT; container = videoContainer; if (destinationName == null) destinationName = DEFAULT_VIDEO_NAME; } //////////////////////////////////////////////////////////////////// // Perform all the necessary Processor and DataSink preparation via // the Location2Location class. //////////////////////////////////////////////////////////////////// destinationLocation = new MediaLocator(destinationName); System.out.println("Configuring for capture. Please wait."); capture = new Location2Location(captureLocation, destinationLocation, formats, container, 1.0); ///////////////////////////////////////////////////////////////////////////// // Start the recording and tell the user. Specify the length of the // recording. Then wait around for up to 4-times the duration of // recording // (can take longer to sink/write the data so should wait a bit incase). ///////////////////////////////////////////////////////////////////////////// System.out.println("Started recording " + duration + " seconds of " + selected + " ..."); capture.setStopTime(new Time(duration)); if (waitFor == 0) waitFor = (int) (4000 * duration); else waitFor *= 1000; int waited = capture.transfer(waitFor); ///////////////////////////////////////////////////////// // Report on the success (or otherwise) of the recording. ///////////////////////////////////////////////////////// int state = capture.getState(); if (state == Location2Location.FINISHED) System.out.println(selected + " capture successful in approximately " + ((int) ((waited + 500) / 1000)) + " seconds. Data written to " + destinationName); else if (state == Location2Location.FAILED) System.out.println(selected + " capture failed after approximately " + ((int) ((waited + 500) / 1000)) + " seconds"); else { System.out.println(selected + " capture still ongoing after approximately " + ((int) ((waited + 500) / 1000)) + " seconds"); System.out.println("Process likely to have failed"); } System.exit(0); } }