Java webcam support using gstreamer
Java’s side that is not too well known would be its interface with external devices. Java can read bar codes interface with serial / parallel ports , and communicate with a web cam (JMF)
Speaking of webcams, the following snippet in the Java media framework (JMF) should list your webcam as a device
Vector info = CaptureDeviceManager.getDeviceList(null);
The problem is that this piece of code does not work all the time. Your webcam should be compatible with JMF to be listed by this call. The gstreamer API can come to your rescue should the JMF call fail. Here is how the gstreamer API describes itself
GStreamer is a library for constructing graphs of media-handling components. The applications it supports range from simple Ogg/Vorbis playback, audio/video streaming to complex audio (mixing) and video (non-linear editing) processing.
The API supports pipelines, which stream data from one node on the pipe to the next. A source node which plugs to a webcam can pass through a video-filter node and end up in a file node thereby recording the video from the webcam and saving it to a file. So where does java fit into this picture ?
The gstreamer-java project is a java interface to the gstreamer API. It allows one to define the piepelines in java and run them in the JVM. The excerpt to a simple video based pipeline is shown below
Video test with a simple pipeline: (No webcams)
public class VideoTest { public VideoTest() { } private static Pipeline pipe; public static void main(String[] args) { args = Gst.init("VideoTest", args); pipe = new Pipeline("VideoTest"); final Element videosrc = ElementFactory.make("videotestsrc", "source"); final Element videofilter = ElementFactory.make("capsfilter", "filter"); videofilter.setCaps(Caps.fromString("video/x-raw-yuv, width=720, height=576" + ", bpp=32, depth=32, framerate=25/1")); SwingUtilities.invokeLater(new Runnable() { public void run() { VideoComponent videoComponent = new VideoComponent(); Element videosink = videoComponent.getElement(); pipe.addMany(videosrc, videofilter, videosink); Element.linkMany(videosrc, videofilter, videosink); // Now create a JFrame to display the video output JFrame frame = new JFrame("Swing Video Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(videoComponent, BorderLayout.CENTER); videoComponent.setPreferredSize(new Dimension(720, 576)); frame.pack(); frame.setVisible(true); // Start the pipeline processing pipe.setState(State.PLAYING); } }); } }
To convert this program to accept the feed from a webcam, all one has to do is replace the videotestsrc with the v4l2src that accepts a stream from a webcam or a tv. Voila, you now have a stream from a webcam to your java app. If you want to save the stream as an image to a file, you can always construct another pipeline to accept the jpegdec and filesink pipeline elements.
As for platform neutrality, the gstreamer API is itself supported in the distributions as noted on this page
Note: There is a working example of content streaming through a webcam on this forum post. Unfortunately the source code in question (displayed below) did not work for the author of that post. It certainly worked when I tried it. Have fun trying it on your webcam
Webcam and gstreamer:
package gstreamervideo; import java.awt.BorderLayout; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.SwingUtilities; import org.gstreamer.Caps; import org.gstreamer.Element; import org.gstreamer.ElementFactory; import org.gstreamer.Gst; import org.gstreamer.Pipeline; import org.gstreamer.State; import org.gstreamer.swing.VideoComponent; public class Main { private static Pipeline pipe; public static void main(String[] args) { args = Gst.init("SwingVideoTest", args); pipe = new Pipeline("pipeline"); // This is from VideoTest example and gives test image // final Element videosrc = ElementFactory.make("videotestsrc", "source"); // This gives black window with VideoComponent final Element videosrc = ElementFactory.make("v4l2src", "source"); final Element videofilter = ElementFactory.make("capsfilter", "flt"); videofilter.setCaps(Caps.fromString("video/x-raw-yuv, width=640, height=480")); SwingUtilities.invokeLater(new Runnable() { public void run() { VideoComponent videoComponent = new VideoComponent(); // This gives only black window Element videosink = videoComponent.getElement(); // This gives 2nd window with stream from webcam // Element videosink = ElementFactory.make("xvimagesink", "sink"); pipe.addMany(videosrc, videofilter, videosink); Element.linkMany(videosrc, videofilter, videosink); JFrame frame = new JFrame("Swing Video Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(videoComponent, BorderLayout.CENTER); videoComponent.setPreferredSize(new Dimension(640, 480)); frame.pack(); frame.setVisible(true); // Start the pipeline processing pipe.setState(State.PLAYING); } }); }
For java and gstreamer pushed to the limit, have a look at my project WebcamStudio (http://ws4gl.org). I rely a lot on this technic and improved it to be dynamic with a video mixer entirely built in java.
My 2 cents!
you fucking rooooooock!!!!
I literaly love you man
thanks!!!!!
Gan….
aku coba script agan diatas dan import library gstreamer…
keluar exception berikut , mohon bantuannya:
Exception in thread “main” java.lang.UnsatisfiedLinkError: Could not load library gstreamer-0.10
at org.gstreamer.lowlevel.GNative.loadWin32Library(GNative.java:83)
at org.gstreamer.lowlevel.GNative.loadLibrary(GNative.java:43)
at org.gstreamer.lowlevel.GstNative.load(GstNative.java:42)
at org.gstreamer.lowlevel.GstNative.load(GstNative.java:39)
at org.gstreamer.Gst.(Gst.java:59)
at org.pidel.vmm.app.Main.main(Main.java:17)
A very good tutorial, thanks!!!
I’ve try the examples and they works fine.
I’ve also tried to add the audio to the pipeline but I haven’t find the solution. There’s someone that know the right way for to do this?