Mega Code Archive

 
Categories / Java / 2D Graphics GUI
 

Capture audio or video through devices connected to the PC

/* 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);   } }