This discussion is archived
5 Replies Latest reply: Dec 21, 2011 3:38 AM by 896918 RSS

Creating Video from set of images using JPEGIMAGESTOMOVIE.JAVA

896918 Newbie
Currently Being Moderated
Hi guys,
I am using JMF to create movie file from a set of images. The code I am using is jpegimagestovideo.java as provided by SUN, and the code compiled successfully but with an warning message. But when I run the program, it shows the error:
throwing exception NullPointException: in Handle() class.
I also mention here that the handle class bundled in JMF jar only consist of a blank constructor.
I am not able to solve this issue.
Also I am sure that the files I am inputting are jpegs and output format is .mov
Please help me to solve it.
Thanking you in advance.


Regards,
Lovelesh Saxena.
  • 1. Re: Creating Video from set of images using JPEGIMAGESTOMOVIE.JAVA
    896918 Newbie
    Currently Being Moderated
    Hi guys,
    Where are you ?
    Please help me to slove this issue out.
    Thanking you all in advance.


    Regards,
    Lovelesh Saxena
  • 2. Re: Creating Video from set of images using JPEGIMAGESTOMOVIE.JAVA
    896918 Newbie
    Currently Being Moderated
    Hi guys,
    please help me, I am getting no help from any where.
    Please try to solve this issue.


    Regards,
    Lovelesh Saxena
  • 3. Re: Creating Video from set of images using JPEGIMAGESTOMOVIE.JAVA
    906485 Newbie
    Currently Being Moderated
    Try posting a few lines of code.

    I'm starting from the dumb: the last time I got a NullPointer exception anywhere in a JMF-powered code, was caused by a bad path provided in the MediaLocator constructor.
    Yea, I know that this reply won't be very useful to you. Sorry. :/
  • 4. Re: Creating Video from set of images using JPEGIMAGESTOMOVIE.JAVA
    896918 Newbie
    Currently Being Moderated
    HI,
    Thanks for atleast replying few words.
    Here I am posting the whole code:


    /*
    * @(#)JpegImagesToMovie.java     1.3 01/03/13
    *
    * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved.
    *
    * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
    * modify and redistribute this software in source and binary code form,
    * provided that i) this copyright notice and license appear on all copies of
    * the software; and ii) Licensee does not utilize the software in a manner
    * which is disparaging to Sun.
    *
    * This software is provided "AS IS," without a warranty of any kind. ALL
    * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
    * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
    * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
    * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
    * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
    * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
    * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
    * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
    * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
    * POSSIBILITY OF SUCH DAMAGES.
    *
    * This software is not designed or intended for use in on-line control of
    * aircraft, air traffic, aircraft navigation or aircraft communications; or in
    * the design, construction, operation or maintenance of any nuclear
    * facility. Licensee represents and warrants that it will not use or
    * redistribute the Software for such purposes.
    */

    import java.io.*;
    import java.util.*;
    import java.awt.Dimension;

    import javax.media.*;
    import javax.media.control.*;
    import javax.media.protocol.*;
    import javax.media.protocol.DataSource;
    import javax.media.datasink.*;
    import javax.media.format.VideoFormat;


    /**
    * This program takes a list of JPEG image files and convert them into
    * a QuickTime movie.
    */
    public class JpegImagesToMovie implements ControllerListener, DataSinkListener {

    public boolean doIt(int width, int height, int frameRate, Vector inFiles, MediaLocator outML) {
         ImageDataSource ids = new ImageDataSource(width, height, frameRate, inFiles);

         Processor p;

         try {
         System.err.println("- create processor for the image datasource ...");
         p = Manager.createProcessor(ids);
         } catch (Exception e) {
         System.err.println("Yikes! Cannot create a processor from the data source.");
         return false;
         }

         p.addControllerListener(this);

         // Put the Processor into configured state so we can set
         // some processing options on the processor.
         p.configure();
         if (!waitForState(p, p.Configured)) {
         System.err.println("Failed to configure the processor.");
         return false;
         }

         // Set the output content descriptor to QuickTime.
         p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.QUICKTIME));

         // Query for the processor for supported formats.
         // Then set it on the processor.
         TrackControl tcs[] = p.getTrackControls();
         Format f[] = tcs[0].getSupportedFormats();
         if (f == null || f.length <= 0) {
         System.err.println("The mux does not support the input format: " + tcs[0].getFormat());
         return false;
         }

         tcs[0].setFormat(f[0]);

         System.err.println("Setting the track format to: " + f[0]);

         // We are done with programming the processor. Let's just
         // realize it.
         p.realize();
         if (!waitForState(p, p.Realized)) {
         System.err.println("Failed to realize the processor.");
         return false;
         }

         // Now, we'll need to create a DataSink.
         DataSink dsink;
         if ((dsink = createDataSink(p, outML)) == null) {
         System.err.println("Failed to create a DataSink for the given output MediaLocator: " + outML);
         return false;
         }

         dsink.addDataSinkListener(this);
         fileDone = false;

         System.err.println("start processing...");

         // OK, we can now start the actual transcoding.
         try {
         p.start();
         dsink.start();
         } catch (IOException e) {
         System.err.println("IO error during processing");
         return false;
         }

         // Wait for EndOfStream event.
         waitForFileDone();

         // Cleanup.
         try {
         dsink.close();
         } catch (Exception e) {}
         p.removeControllerListener(this);

         System.err.println("...done processing.");

         return true;
    }


    /**
    * Create the DataSink.
    */
    DataSink createDataSink(Processor p, MediaLocator outML) {

         DataSource ds;

         if ((ds = p.getDataOutput()) == null) {
         System.err.println("Something is really wrong: the processor does not have an output DataSource");
         return null;
         }

         DataSink dsink;

         try {
         System.err.println("- create DataSink for: " + outML);
         dsink = Manager.createDataSink(ds, outML);
         dsink.open();
         } catch (Exception e) {
         System.err.println("Cannot create the DataSink: " + e);
         return null;
         }

         return dsink;
    }


    Object waitSync = new Object();
    boolean stateTransitionOK = true;

    /**
    * Block until the processor has transitioned to the given state.
    * Return false if the transition failed.
    */
    boolean waitForState(Processor p, int state) {
         synchronized (waitSync) {
         try {
              while (p.getState() < state && stateTransitionOK)
              waitSync.wait();
         } catch (Exception e) {}
         }
         return stateTransitionOK;
    }


    /**
    * Controller Listener.
    */
    public void controllerUpdate(ControllerEvent evt) {

         if (evt instanceof ConfigureCompleteEvent ||
         evt instanceof RealizeCompleteEvent ||
         evt instanceof PrefetchCompleteEvent) {
         synchronized (waitSync) {
              stateTransitionOK = true;
              waitSync.notifyAll();
         }
         } else if (evt instanceof ResourceUnavailableEvent) {
         synchronized (waitSync) {
              stateTransitionOK = false;
              waitSync.notifyAll();
         }
         } else if (evt instanceof EndOfMediaEvent) {
         evt.getSourceController().stop();
         evt.getSourceController().close();
         }
    }


    Object waitFileSync = new Object();
    boolean fileDone = false;
    boolean fileSuccess = true;

    /**
    * Block until file writing is done.
    */
    boolean waitForFileDone() {
         synchronized (waitFileSync) {
         try {
              while (!fileDone)
              waitFileSync.wait();
         } catch (Exception e) {}
         }
         return fileSuccess;
    }


    /**
    * Event handler for the file writer.
    */
    public void dataSinkUpdate(DataSinkEvent evt) {

         if (evt instanceof EndOfStreamEvent) {
         synchronized (waitFileSync) {
              fileDone = true;
              waitFileSync.notifyAll();
         }
         } else if (evt instanceof DataSinkErrorEvent) {
         synchronized (waitFileSync) {
              fileDone = true;
              fileSuccess = false;
              waitFileSync.notifyAll();
         }
         }
    }


    public static void main(String args[]) {

         if (args.length == 0)
         prUsage();

         // Parse the arguments.
         int i = 0;
         int width = -1, height = -1, frameRate = 1;
         Vector inputFiles = new Vector();
         String outputURL = null;

         while (i < args.length) {

         if (args.equals("-w")) {
              i++;
              if (i >= args.length)
              prUsage();
         //     width = new Integer(args[i]).intValue();
    width=1366;
         } else if (args[i].equals("-h")) {
              i++;
              if (i >= args.length)
              prUsage();
              //height = new Integer(args[i]).intValue();
    height=768;
         } else if (args[i].equals("-f")) {
              i++;
              if (i >= args.length)
              prUsage();
              //frameRate = new Integer(args[i]).intValue();
    frameRate =2;
         } else if (args[i].equals("-o")) {
              i++;
              if (i >= args.length)
              prUsage();
              //outputURL = args[i];
    outputURL="a.mov";
         } else {
              inputFiles.addElement(args[i]);
         }
         i++;
         }

         if (outputURL == null || inputFiles.size() == 0)
         prUsage();

         // Check for output file extension.
         if (!outputURL.endsWith(".mov") && !outputURL.endsWith(".MOV")) {
         System.err.println("The output file extension should end with a .mov extension");
         prUsage();
         }

         if (width < 0 || height < 0) {
         System.err.println("Please specify the correct image size.");
         prUsage();
         }

         // Check the frame rate.
         if (frameRate < 1)
         frameRate = 1;

         // Generate the output media locators.
         MediaLocator oml;

         if ((oml = createMediaLocator(outputURL)) == null) {
         System.err.println("Cannot build media locator from: " + outputURL);
         System.exit(0);
         }

         JpegImagesToMovie imageToMovie = new JpegImagesToMovie();
         imageToMovie.doIt(width, height, frameRate, inputFiles, oml);

         System.exit(0);
    }

    static void prUsage() {
         System.err.println("Usage: java JpegImagesToMovie -w <width> -h <height> -f <frame rate> -o <output URL> <input JPEG file 1> <input JPEG file 2> ...");
         System.exit(-1);
    }

    /**
    * Create a media locator from the given string.
    */
    static MediaLocator createMediaLocator(String url) {

         MediaLocator ml;

         if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null)
         return ml;

         if (url.startsWith(File.separator)) {
         if ((ml = new MediaLocator("file:" + url)) != null)
              return ml;
         } else {
         String file = "file:" + System.getProperty("user.dir") + File.separator + url;
         if ((ml = new MediaLocator(file)) != null)
              return ml;
         }

         return null;
    }


    ///////////////////////////////////////////////
    //
    // Inner classes.
    ///////////////////////////////////////////////


    /**
    * A DataSource to read from a list of JPEG image files and
    * turn that into a stream of JMF buffers.
    * The DataSource is not seekable or positionable.
    */
    class ImageDataSource extends PullBufferDataSource {

         ImageSourceStream streams[];

         ImageDataSource(int width, int height, int frameRate, Vector images) {
         streams = new ImageSourceStream[1];
         streams[0] = new ImageSourceStream(width, height, frameRate, images);
         }

         public void setLocator(MediaLocator source) {
         }

         public MediaLocator getLocator() {
         return null;
         }

         /**
         * Content type is of RAW since we are sending buffers of video
         * frames without a container format.
         */
         public String getContentType() {
         return ContentDescriptor.RAW;
         }

         public void connect() {
         }

         public void disconnect() {
         }

         public void start() {
         }

         public void stop() {
         }

         /**
         * Return the ImageSourceStreams.
         */
         public PullBufferStream[] getStreams() {
         return streams;
         }

         /**
         * We could have derived the duration from the number of
         * frames and frame rate. But for the purpose of this program,
         * it's not necessary.
         */
         public Time getDuration() {
         return DURATION_UNKNOWN;
         }

         public Object[] getControls() {
         return new Object[0];
         }

         public Object getControl(String type) {
         return null;
         }
    }


    /**
    * The source stream to go along with ImageDataSource.
    */
    class ImageSourceStream implements PullBufferStream {

         Vector images;
         int width, height;
         VideoFormat format;

         int nextImage = 0;     // index of the next image to be read.
         boolean ended = false;

         public ImageSourceStream(int width, int height, int frameRate, Vector images) {
         this.width = width;
         this.height = height;
         this.images = images;

         format = new VideoFormat(VideoFormat.JPEG,
                        new Dimension(width, height),
                        Format.NOT_SPECIFIED,
                        Format.byteArray,
                        (float)frameRate);
         }

         /**
         * We should never need to block assuming data are read from files.
         */
         public boolean willReadBlock() {
         return false;
         }

         /**
         * This is called from the Processor to read a frame worth
         * of video data.
         */
         public void read(Buffer buf) throws IOException {

         // Check if we've finished all the frames.
         if (nextImage >= images.size()) {
              // We are done. Set EndOfMedia.
              System.err.println("Done reading all images.");
              buf.setEOM(true);
              buf.setOffset(0);
              buf.setLength(0);
              ended = true;

              return;
         }

         String imageFile = (String)images.elementAt(nextImage);
    System.out.println("#####"+imageFile);
         nextImage++;

         System.err.println(" - reading image file: " + imageFile);
         // Open a random access file for the next image.
         RandomAccessFile raFile;
         raFile = new RandomAccessFile(imageFile, "r");
    System.out.println("---------------------------------------");

         byte data[] = null;



         // Check the input buffer type & size.

         if (buf.getData() instanceof byte[]){
              data = (byte[])buf.getData();

    }

         // Check to see the given buffer is big enough for the frame.
         if (data == null || data.length < raFile.length()) {
              data = new byte[(int)raFile.length()];
              buf.setData(data);
         }

         // Read the entire JPEG image from the file.
         raFile.readFully(data, 0, (int)raFile.length());

         System.err.println(" read " + raFile.length() + " bytes.");

         buf.setOffset(0);
         buf.setLength((int)raFile.length());
         buf.setFormat(format);
         buf.setFlags(buf.getFlags() | buf.FLAG_KEY_FRAME);

         // Close the random access file.
         raFile.close();
         }

         /**
         * Return the format of each video frame. That will be JPEG.
         */
         public Format getFormat() {
         return format;
         }

         public ContentDescriptor getContentDescriptor() {
         return new ContentDescriptor(ContentDescriptor.RAW);
         }

         public long getContentLength() {
         return 0;
         }

         public boolean endOfStream() {
         return ended;
         }

         public Object[] getControls() {
         return new Object[0];
         }

         public Object getControl(String type) {
         return null;
         }
    }
    }


    Thanks and Regards
    Lovelesh Saxena
  • 5. Re: Creating Video from set of images using JPEGIMAGESTOMOVIE.JAVA
    896918 Newbie
    Currently Being Moderated
    Hi guys,
    I have done it.
    My problem is solved now.
    I take another code example MovieEncoder.java.
    That is a great example code with everything explained clearly.
    Thanks God!!!
    Thanking you all too.


    Regards,
    Lovelesh Saxena.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points