Java Media Framework vs IP Camera JPEGMJPEG

mac2022-06-30  24

http://dragosc.itmcd.ro/uncategorized/java-media-framework-vs-ip-camera-jpegmjpeg-complete-overview-sources/

————————————————————————————————————————————————————————————————————

 

NOTE: + I will try not to re-write again all the informations I already wrote in “Java Media Framwork vs IP Camera JPEG/MJPEG” a few years ago. This article is only a review of what I wrote back then, plus more info about my implementation of DataSource for JPEG/MJPEG IP Cameras. + Another note is, that this project of mine, has been attached to my own company which I founded a few years ago and I’m still trying to grow it. Project licence will be LGPL.

OK… Since Oracle bought SUN a few years ago, but their website still doesn’t reflect all info about Java Media Framework, it’s still best do Google after the info about JMF, than give you a specific link.

The article that belongs to Chris Adamson, Java Media Development with QuickTime for Java, still exists and, believe me it’s pretty useful. It explains how to create a new JMF plugin using the Java lib for Quick Time, released by Apple. Only wish I had access to them, but that’s another problem.

Even though at first I kinda disliked working with JMF due to it’s huge lack of documentation (some would say, it has such thing, I would say: NO), I discovered in time that it’s not that complicated. The principles are pretty simple, and even though the library hasn’t seen another update since 2001, its extendability is pretty high. We’ve already seen a plugin from mr. Adamson for qt-java, and from what I’ve known there are other plugins there on the web.

The main idea in Chris Adamson’s article is to create two classes, one to extend DataSource and one to extend PushBufferStream or PullBufferStream from JMF.

The DataSource class is needed by JMF Players to read the info you need to display, while the BufferStream is actually the reader of the “video” stream.

In our case, we can say the BufferStream class is a bit more complicated, but as we look closer it is not. We do have to check two cases though.

Cameras that do have a fully MJPEG stream.Cameras that only have JPEG ‘streams’. In this case, it’s not a real stream actually, and we have to simulate one by re-reading the source in a loop.

The only problem we couldn’t solve in a nice manner was creating a handler class, so we sticked to this:

 

package org.itmc.ipcamera.media.content.unknown; public  class Handler  extends com.sun.media.content.unknown.Handler {}

 

If you download the sources, you’ll discover that each class has a static function for testing, also including an example for how to use it.

You can download the latest sources from:http://svn.itmcd.ro/trunk/jmf/ipcamera user & pass: anonymous

We’re looking for help to improve our code, and make from “ipcamera” an API worth to use for all types of streaming used by ip cameras, so if you think you’re smart enough and want to help, or if you used this API in your application and want to share with us some of your code, please contact us. Leave us a comment to this post, and we will contact u ASAP. (The comment will not be published unless you request so.)

Also, if you think our code has helped you, please try and donate us a few coins. This is free LGPL work, but in order to continue our research, we do need some funds there.

 ————————————————————————————————————————————————————————————————————

以下为上面提到的老版本

 

http://dragosc.itmcd.ro/it-stuff/java-media-framework-vs-ip-camera-jpegmjpeg/

 

NOTE: + This article is pretty deprecated. I do not say that the info here is false, but I would like to write a new article about this. Please leave me comments with what you want to know, and I will try do add more info to the article. And ofcourse, more sources. + A Romanian translation for this article is found here.

I really don”t think I”m either the first or the last to try and obtain images from and ip camera and than use them with JMF. So… after a few days of reading and trying to understand how JMF works, as I already had a JPEG/MJPEG grabber, here is my solutions:

As Chris Adamson explains in his article, Java Media Development with QuickTime for Java, to create a new JMF plugin you need to create two classes, one to extend DataSource and one to extend PushBufferStream or PullBufferStream from JMF. For DataSource I used PushBufferDataSource, which implements the parent class: DataSource.

The most important element is the fact that Datasource must be placed int a package named smth like this: name1.name2.someothername.media.protocol.numeprotocol (i.e. com.sun.media.protocol.http, com.sun.media.protocol.rtp, com.ibm.media.protocol.file).

For the DataSource class I used the example given by SUN in their ScreenGrabber, and I only modified the streaming class name. I won”t reveal the image grabing class, as SUN forum is allready filled with such examples, but I will reveal the streaming class under a surogated protocol I called htmjpeg. I”m sure it won”t take long to you to understant that the protocol is just a simple name, and can be easily changed in my example:

JMF MJPEG Plugin (for Download)

[[wppald_inposts|Donation for JMF Work]]

 

package com.itmc.media.protocol.htmjpeg; import com.itmc.ipcamera.mjpeg.grabber.mjpegGrabber; import java.awt.*; import java.awt.image.BufferedImage; import javax.media.*; import javax.media.format.*; import javax.media.protocol.*; import java.io.IOException; public  class mjpegStream  extends mjpegGrabber  implements PushBufferStream, Runnable {      protected ContentDescriptor cd =  new ContentDescriptor(ContentDescriptor.RAW);      protected  int maxDataLength;      protected  int [] data;      protected Dimension size;      protected RGBFormat rgbFormat;      protected  boolean started;      protected Thread thread;      protected  float frameRate = 7.0f;      protected BufferTransferHandler transferHandler;      protected Control [] controls =  new Control[0];      protected  int x, y, width, height;      protected Robot robot =  null;      protected BufferedImage im =  null;      protected  boolean mjpeg =  false;      public mjpegStream(MediaLocator locator) {          super("http:" + locator.getRemainder());         System.out.println("http://" + locator.getRemainder());          try {              super.connect();             im =  super.readJPEG();              super.disconnect();         }  catch(Exception e) {         }          if (im ==  null) {              try {                  super.connect();                 im =  super.readMJPEG();                 mjpeg =  true;                  super.disconnect();             }  catch(Exception e) {             }         }         size =  new Dimension(im.getWidth(), im.getHeight()); //         im = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); //         size = new Dimension(100, 100);         maxDataLength = size.width * size.height * 3;         rgbFormat =  new RGBFormat(             size, maxDataLength,             Format.intArray,             frameRate,             32,             0xFF0000, 0xFF00, 0xFF,             1, size.width,             VideoFormat.FALSE,             Format.NOT_SPECIFIED         );         System.out.println(rgbFormat.getFrameRate());          //  generate the data         data =  new  int[maxDataLength];         thread =  new Thread( this, "Htmjpeg Grabber");     }      /** *************************************************************************     * SourceStream     ************************************************************************** */      public ContentDescriptor getContentDescriptor() {          return cd;     }      public  long getContentLength() {          return LENGTH_UNKNOWN;     }      public  boolean endOfStream() {          return  false;     }      /** *************************************************************************     * PushBufferStream     ************************************************************************** */      int seqNo = 0;      public Format getFormat() {          return rgbFormat;     }      public  void read(Buffer buffer)  throws IOException {          synchronized ( this) {              super.connect();             Object outdata = buffer.getData();              if (outdata ==  null || !(outdata.getClass() == Format.intArray) ||                 (( int[])outdata).length < maxDataLength) {                 outdata =  new  int[maxDataLength];                 buffer.setData(outdata);             }             buffer.setFormat( rgbFormat );             buffer.setTimeStamp( ( long) (seqNo * (1000 / frameRate) * 1000000) );             BufferedImage bi = mjpeg? super.readMJPEG(): super.readJPEG();             bi.getRGB(0, 0, size.width, size.height, ( int[])outdata, 0, size.width);             buffer.setSequenceNumber( seqNo );             buffer.setLength(maxDataLength);             buffer.setFlags(Buffer.FLAG_KEY_FRAME);             buffer.setHeader(  null );             seqNo++;              if (!mjpeg)  super.disconnect();         }     }      public  void setTransferHandler(BufferTransferHandler transferHandler) {          synchronized ( this) {              this.transferHandler = transferHandler;             notifyAll();         }     }      void start( boolean started) {          synchronized (  this ) {              this.started = started;              if (started && !thread.isAlive()) {                 thread =  new Thread( this);                 thread.start();             }             notifyAll();         }     }      /** *************************************************************************     * Runnable     ************************************************************************** */      public  void run() {          while (started) {              synchronized ( this) {                  while (transferHandler ==  null && started) {                      try {                         wait(1000);                     }  catch (InterruptedException ie) {                     }                 }  //  while             }              if (started && transferHandler !=  null) {                 transferHandler.transferData( this);                  try {                     Thread.currentThread().sleep( 10 );                 }  catch (InterruptedException ise) {                 }             }         }  //  while (started)     }  //  run     //  Controls      public Object [] getControls() {          return controls;     }      public Object getControl(String controlType) {         try {           Class  cls = Class.forName(controlType);           Object cs[] = getControls();            for ( int i = 0; i < cs.length; i++) {               if (cls.isInstance(cs[i]))                  return cs[i];           }            return  null;        }  catch (Exception e) {    //  no such controlType or such control           return  null;        }     } }

转载于:https://www.cnblogs.com/cuizhf/archive/2012/01/04/2312291.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)