3

I am trying to convert Jpeg images into .mov video file

 package com.ecomm.pl4mms.test;

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;
import javax.media.format.JPEGFormat;

public class JpegImagesToMovie implements ControllerListener, DataSinkListener {

    public boolean doItPath(int width, int height, int frameRate, Vector inFiles, String outputURL) {
        // 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();
        }

        // Generate the output media locators.
        MediaLocator oml;

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

        boolean success = doIt(width, height, frameRate, inFiles, oml);

        System.gc();
        return success;
    }

    public boolean doIt(int width, int height, int frameRate, Vector inFiles, MediaLocator outML) {
        try {
            System.out.println(inFiles.size());
            ImageDataSource ids = new ImageDataSource(width, height, frameRate, inFiles);

            Processor p;

            try {
                // System.err.println("- create processor for the image
                // datasource ...");
                System.out.println("processor");
                p = Manager.createProcessor(ids);
                System.out.println("success");
            } 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.out.println("Issue configuring");
                // System.err.println("Failed to configure the processor.");
                p.close();
                p.deallocate();
                return false;
            }
            System.out.println("Configured");

            // Set the output content descriptor to QuickTime.
            p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.QUICKTIME));
System.out.println(outML);
            // Query for the processor for supported formats.
            // Then set it on the processor.
            TrackControl tcs[] = p.getTrackControls();
            Format f[] = tcs[0].getSupportedFormats();
            System.out.println(f[0].getEncoding());
            if (f == null || f.length <= 0) {
                 System.err.println("The mux does not support the input format: " + tcs[0].getFormat());
                p.close();
                p.deallocate();
                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.");
                p.close();
                p.deallocate();
                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);
                p.close();
                p.deallocate();
                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) {
                p.close();
                p.deallocate();
                dsink.close();
                // 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.");

            p.close();

            return true;
        } catch (NotConfiguredError e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return false;
    }

    /**
     * Create the DataSink.
     */
    DataSink createDataSink(Processor p, MediaLocator outML) {
System.out.println("In data sink");
        DataSource ds;

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

        DataSink dsink;

        try {
             System.out.println("- create DataSink for: " + ds.toString()+ds.getContentType());
            dsink = Manager.createDataSink(ds, outML);
            dsink.open();
            System.out.println("Done data sink");
        } catch (Exception e) {
             System.err.println("Cannot create the DataSink: " +e);
             e.printStackTrace();
            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 arg[]) {
        try {
            String args[] = { "-w 100 -h 100 -f 100 -o F:\\test.mov F:\\Text69.jpg F:\\Textnew.jpg" };
            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[i].equals("-w")) {
                    i++;
                    if (i >= args.length)
                        width = new Integer(args[i]).intValue();
                } else if (args[i].equals("-h")) {
                    i++;
                    if (i >= args.length)
                        height = new Integer(args[i]).intValue();
                } else if (args[i].equals("-f")) {
                    i++;
                    if (i >= args.length)
                        frameRate = new Integer(args[i]).intValue();
                } else if (args[i].equals("-o")) {
                    System.out.println("in ou");
                    i++;
                    System.out.println(i);
                    if (i >= args.length)
                        outputURL = args[i];
                    System.out.println(outputURL);
                } else {
                    System.out.println("adding"+args[i]);
                    inputFiles.addElement(args[i]);
                }
                i++;

            }
            inputFiles.addElement("F:\\Textnew.jpg");
            outputURL = "F:\\test.mov";
            System.out.println(inputFiles.size() + outputURL);
            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();
            }
            width = 100;
            height = 100;
            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;
            oml = createMediaLocator(outputURL);
            System.out.println("Media" + oml);
            if (oml == null) {
                System.err.println("Cannot build media locator from: " + outputURL);
                // //System.exit(0);
            }
            System.out.println("Before change");
System.out.println(inputFiles.size());
            JpegImagesToMovie imageToMovie = new JpegImagesToMovie();
            boolean status = imageToMovie.doIt(width, height, frameRate, inputFiles, oml);
            System.out.println("Status"+status);
            //System.exit(0);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    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) {
        System.out.println(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 JPEGFormat(new Dimension(width, height), Format.NOT_SPECIFIED, Format.byteArray,
                    (float) frameRate, 75, JPEGFormat.DEC_422);
        }

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

            System.err.println("  - reading image file: " + imageFile);

            // Open a random access file for the next image.
            RandomAccessFile raFile;
            raFile = new RandomAccessFile(imageFile, "r");

            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;
        }
    }
}

I am getting

    Cannot create the DataSink: javax.media.NoDataSinkException: Cannot find a DataSink for: com.sun.media.multiplexer.BasicMux$BasicMuxDataSource@d7b1517
javax.media.NoDataSinkException: Cannot find a DataSink for: com.sun.media.multiplexer.BasicMux$BasicMuxDataSource@d7b1517
    at javax.media.Manager.createDataSink(Manager.java:1894)
    at com.ecomm.pl4mms.test.JpegImagesToMovie.createDataSink(JpegImagesToMovie.java:168)
    at com.ecomm.pl4mms.test.JpegImagesToMovie.doIt(JpegImagesToMovie.java:104)
    at com.ecomm.pl4mms.test.JpegImagesToMovie.main(JpegImagesToMovie.java:330)

Please help me to resolve this and let me what can be the cause of this

I am using java 1.8 and trying to create video with jpeg images and using

javax.media to perform this action. and i followed http://www.oracle.com/technetwork/java/javase/documentation/jpegimagestomovie-176885.html to write the code

Divya
  • 87
  • 1
  • 10

2 Answers2

0

From experiment, this exception is thrown when the output file cannot be created (in your case "F:\\test.mov"). Check that the path is valid and that the application has write permission on it.

I recommend constructing a platform agnostic path somewhere under user.home e.g:

System.getProperty("user.home") + File.separator + "test.mov"
Chris
  • 1,335
  • 10
  • 19
0

In Windows you need to use the file URL starting with file://, see https://github.com/agomezmoron/screen-recorder/issues/6#issuecomment-547072889

Reed_Xia
  • 1,300
  • 3
  • 17
  • 29