Month: May 2011

Using webcam with a Java application

Introduction

Before getting struck in a restless time period I determine to put my second post about Java Media Framework. In my previous post I’ve showed how to play audio and video files using this framework.

In this post I’m going to show you how to capture an image and how to record a video using webcam.

Capturing an image

First you need to get a list of devices with the help of CaptureDeviceManager and filter out the first element of that list. Then you can get the visual component of it and use it as the video screen.

Then you have to place all those player control panel and video screen on a frame. After that you allow the program to capture image after a certain time.

After that as in many cases Java has to treat the buffered image. You can save the image in any format you wish, with the help of ImageIO.

Here’s an example code on how to do that.

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.media.*;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.RGBFormat;
import javax.media.format.VideoFormat;
import javax.media.util.BufferToImage;

/**
 *
 * @author BUDDHIMA
 */
public class WebCam {

    CaptureDeviceInfo device;
    MediaLocator ml;
    Player player;
    Component videoScreen;

    public static void main(String args[]) {
        new WebCam();// create a new instance of WebCam in main function
    }

    WebCam() {
        try {
//gets a list of devices how support the given videoformat
            Vector deviceList = CaptureDeviceManager.getDeviceList(new RGBFormat());
            System.out.println(deviceList.toString());

//gets the first device in deviceList
            device = (CaptureDeviceInfo) deviceList.firstElement();

            ml = device.getLocator();

            player = Manager.createRealizedPlayer(ml);

            player.start();

            videoScreen = player.getVisualComponent();
            Frame frm = new Frame();
            frm.setBounds(10, 10, 900, 700);//sets the size of the screen

// setting close operation to the frame
            frm.addWindowListener(new WindowAdapter() {

                public void windowClosing(WindowEvent we) {
                    System.exit(0);
                }
            });

//place player and video screen on the frame
            frm.add(videoScreen, BorderLayout.CENTER);
            frm.add(player.getControlPanelComponent(), BorderLayout.SOUTH);
            frm.setVisible(true);

//capture image
            Thread.sleep(10000);//wait 10 seconds before capturing photo

            FrameGrabbingControl fgc = (FrameGrabbingControl) player.getControl("javax.media.control.FrameGrabbingControl");

            Buffer buf = fgc.grabFrame();//grab the current frame on video screen

            BufferToImage btoi = new BufferToImage((VideoFormat) buf.getFormat());

            Image img = btoi.createImage(buf);

            saveImagetoFile(img, "MyPhoto.jpg");//save the captured image as MyPhoto.jpg

        } catch (Exception e) {
            System.out.println(e);
        }
    }

    private void saveImagetoFile(Image img, String string) {
        try {
            int w = img.getWidth(null);
            int h = img.getHeight(null);
            BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = bi.createGraphics();

            g2.drawImage(img, 0, 0, null);

            g2.dispose();

            String fileType = string.substring(string.indexOf('.') + 1);

            ImageIO.write(bi, fileType, new File(string));

        } catch (Exception e) {
        }
    }
}

How it works

Record a video

Although this code is not functioning too well, you can capture some small video clips using this. I’ve to mention that captureing a video is not that much easy as capturing an image. You have to study about Processors and ProcessorModels in JMF to get the clear idea about that.

import java.util.Vector;
import javax.media.*;
import javax.media.format.AudioFormat;
import javax.media.format.VideoFormat;
import javax.media.protocol.DataSource;
import javax.media.CaptureDeviceInfo;
import javax.media.format.YUVFormat;
import javax.media.protocol.FileTypeDescriptor;
/**
 *
 * @author BUDDHIMA
 */
public class CamRecorder {

    static VideoFormat videoFormat;
    static AudioFormat audioFormat;
    static CaptureDeviceInfo videoDevice;
    static CaptureDeviceInfo audioDevice;

    public static void main(String[] args) {
        try {
            Vector deviceList = CaptureDeviceManager.getDeviceList(new YUVFormat()); //get all media devices
            CaptureDeviceInfo device = (CaptureDeviceInfo) deviceList.firstElement(); //in this computer the only capture device is in=built webcam stays at 0th position
            Format[] formats = device.getFormats(); //get all formats

            for (int x = 0; x < formats.length; x++) {
                if (formats[x] != null && formats[x] instanceof VideoFormat) {
                    videoFormat = (VideoFormat) formats[x]; //take the video format
                    videoDevice = device;
                }
                if (formats[x] != null && formats[x] instanceof AudioFormat) {
                    audioFormat = (AudioFormat) formats[x]; //take the audio format
                    //audioDevice = device;
                }
            }
            //create data sources
            DataSource videoDataSource = Manager.createDataSource(device.getLocator());

            deviceList = CaptureDeviceManager.getDeviceList(new AudioFormat(null)); //get all media devices
            device = (CaptureDeviceInfo) deviceList.firstElement();

            DataSource audioDataSource=Manager.createDataSource(device.getLocator());

            DataSource[] dArray=new DataSource[2];
            dArray[0]=videoDataSource;
            dArray[1]=audioDataSource;

                DataSource mixedDataSource = Manager.createMergingDataSource(dArray);

            //format for output

                Format[] outputFormats=new Format[2];
                outputFormats[0]=new VideoFormat(VideoFormat.YUV);
                outputFormats[1]=new AudioFormat(AudioFormat.LINEAR);
            //output type
                FileTypeDescriptor outputType=new FileTypeDescriptor(FileTypeDescriptor.MSVIDEO);

            //settingup Processor
                ProcessorModel processorModel=new ProcessorModel(mixedDataSource, outputFormats, outputType);
                Processor processor=Manager.createRealizedProcessor(processorModel);

            //settingup sink
                DataSource outputDataSource=processor.getDataOutput();
                MediaLocator destination=new MediaLocator("file:.\\testcam.avi");
                DataSink dataSink=Manager.createDataSink(outputDataSource, destination);
                dataSink.open();

                //start sink + processor
                Thread.sleep(4000);
                dataSink.start();
                processor.start();

                Thread.sleep(4000);

                dataSink.close();
                processor.stop();
                processor.close();

        } catch (Exception ex) {

        }

    }
}

Resources

1. JMF Architecture  http://www.ibm.com/developerworks/java/tutorials/j-jmf/section4.html

2. http://www.javaworld.com/javaworld/jw-05-2001/jw-0504-jmf2.html?page=1

3. http://www.java-forums.org/new-java/40115-capturing-video-webcam-jmf.html

How to play audio and video files in Java applications

Introduction

In this post I’m going to show you how to play an audio and a video file using a java application. At first I have to mention that I’m using Java Media Framework (JMF) for this purpose. So you have to download and install JMF from here. According to the web page you can,

  • Playback audios and videos
  • Capture from devices
  • Transmitt over an internet connection

JMF is providing you necessary classes and you have to do less. But in here I’ve to mention that JMF is a bit old too. In many cases you won’t be able to play every media file you want. Because there are some restrictions. Through following examples I’ll show you how to get the use of JMF.

Creating an audio player

Before going to build an audio player you have to be familier with the classes and their methods that are going to use.

Player: As the name says Player is responsible for playing the given file. It has start(), stop(), close() methods. Player also have number of states too.

  • Prefetched
  • Prefetching
  • Realized
  • Realizing
  • Started
  • Unrealized

Manager: Manager is responsible for creating appropriate player object using an URL or a Media Locator.  Manager is also use to create a processor – will be explained later.

SimpleAudioPlayer.java

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.media.*;   // import JMF classes
import javax.swing.JFileChooser;

/**
*
* @author BUDDHIMA
*/

public class SimpleAudioPlayer {

private Player audioPlayer = null;

public SimpleAudioPlayer(URL url) {

try {

//MediaLocator ml=new MediaLocator(url);

audioPlayer = Manager.createPlayer(url);

} catch (Exception ex) {

System.out.println(ex);

}

}

public SimpleAudioPlayer(File file) throws MalformedURLException {

this(file.toURI().toURL());

}

public void play() {

audioPlayer.start(); // start playing

}

public void stop() {

audioPlayer.stop();  //stop playing

audioPlayer.close();

}

public static void main(String[] args) {

try {

// TODO code application logic here

JFileChooser fc = new JFileChooser();

fc.showOpenDialog(null);

File file = fc.getSelectedFile();

SimpleAduioPlayer sap = new SimpleAduioPlayer(file);

sap.play();

//sap.stop();

} catch (MalformedURLException ex) {

System.out.println(ex);

}

}

}

With this example you can play MP3, WAV, and AU files.

Creating a video player

Not like audio player, Video player deals with GUI. Therefore you should have a little knowledge about Swing components. In addition to previous things you have to get Visual component and Control Panel component from the Player instance created by you. Then you have to place those in a necessary Swing component (here JPanel is used).

MediaPlayer.java


import java.awt.BorderLayout;
import java.awt.Component;
import java.net.MalformedURLException;
import java.net.URL;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.swing.JFileChooser;
import javax.swing.JFrame;

/**
*
* @author BUDDHIMA
*/

public class MediaPlayer extends javax.swing.JPanel {

public MediaPlayer(URL mediauUrl) {

initComponents();

setLayout(new BorderLayout());

try {

Player mediaPlayer=Manager.createRealizedPlayer(new MediaLocator(mediauUrl));

Component video=mediaPlayer.getVisualComponent();

Component control=mediaPlayer.getControlPanelComponent();

if (video!=null) {

add(video, BorderLayout.CENTER);          // place the video component in the panel

}

add(control, BorderLayout.SOUTH);            // place the control in  panel

mediaPlayer.start();

} catch (Exception e) {

}

}

public static void main(String[] args) {

JFileChooser fileChooser = new JFileChooser();

fileChooser.showOpenDialog(null);

URL mediaUrl=null;

try {

mediaUrl = fileChooser.getSelectedFile().toURI().toURL();

} catch (MalformedURLException ex) {

System.out.println(ex);

}

JFrame mediaTest = new JFrame( "Movie Player" );

mediaTest.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

MediaPlayer mediaPanel = new MediaPlayer( mediaUrl );

mediaTest.add( mediaPanel );

mediaTest.setSize( 800, 700 ); // set the size of the player

mediaTest.setLocationRelativeTo(null);

mediaTest.setVisible( true );

}

}

When you run this code and select a file, you would get something like this. But you can only play limited number of video fromats only (.mpg, some .avi files). Give a try ! 😀

Willing to tell more intractive activities using JMF  ………

Resources:

  1. JMF official site : http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140239.html
  2. JMF examples : http://blogs.sun.com/geertjan/date/20070121