Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Nov 28th, 2007, 11:12 AM   #11
Harakim
Hobbyist Programmer
 
Join Date: May 2006
Location: West Jordan, Utah, United States
Posts: 176
Rep Power: 3 Harakim is on a distinguished road
Re: convert image sequence to quicktime movie

EDIT: I have read that people have trouble saving in a directory other than the one the program runs in, though I have been able to.

Here is my session:
Quote:
Z:\More of my junk\jpegs to qt>dir
Volume in drive Z is ??
Volume Serial Number is 8317-027E

Directory of Z:\More of my junk\jpegs to qt

11/28/2007 10:01 AM <DIR> .
11/28/2007 09:54 AM <DIR> ..
11/28/2007 09:38 AM 11,878 JpegImagesToMovie.java
11/28/2007 09:38 AM 46,147 Red_line5.jpeg.jpg
11/28/2007 09:56 AM 46,749 movie.mov
05/01/2003 01:54 PM 1,904,171 jmf.jar
4 File(s) 2,008,945 bytes
2 Dir(s) 11,190,403,072 bytes free

Z:\More of my junk\jpegs to qt>javac -cp .;jmf.jar JpegImagesToMovie.java
Note: JpegImagesToMovie.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Z:\More of my junk\jpegs to qt>java -cp .;jmf.jar JpegImagesToMovie -h 480 -w 640 -f 1 -o movie.mov Red_line5.jpeg.jpg

Z:\More of my junk\jpegs to qt>dir
Volume in drive Z is ??
Volume Serial Number is 8317-027E

Directory of Z:\More of my junk\jpegs to qt

11/28/2007 10:01 AM <DIR> .
11/28/2007 09:54 AM <DIR> ..
11/28/2007 10:01 AM 2,607 JpegImagesToMovie$ImageSourceStream.class
11/28/2007 09:38 AM 11,878 JpegImagesToMovie.java
11/28/2007 10:01 AM 6,047 JpegImagesToMovie.class
11/28/2007 09:38 AM 46,147 Red_line5.jpeg.jpg
11/28/2007 10:01 AM 1,488 JpegImagesToMovie$ImageDataSource.class
11/28/2007 10:01 AM 46,749 movie.mov
05/01/2003 01:54 PM 1,904,171 jmf.jar
7 File(s) 2,019,087 bytes
2 Dir(s) 11,190,403,072 bytes free
My friend RB Whitaker modified the original example. This is the code I used:
(I used JMF2.1.1e)
/*
 * @(#)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.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.awt.Dimension;

import javax.media.*;
import javax.media.control.*;
import javax.media.protocol.*;
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
		{
			p = Manager.createProcessor(ids);
		} catch (Exception e)
		{
			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, Processor.Configured))
		{
			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)
		{
			return false;
		}

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

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

		// Now, we'll need to create a DataSink.
		DataSink dsink;
		if ((dsink = createDataSink(p, outML)) == null)
		{
			return false;
		}

		dsink.addDataSinkListener(this);
		fileDone = false;

		// OK, we can now start the actual transcoding.
		try
		{
			p.start();
			dsink.start();
		}
		catch (IOException e)
		{
			return false;
		}

		// Wait for EndOfStream event.
		waitForFileDone();

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

		p.removeControllerListener(this);

		return true;
	}


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

		if ((ds = p.getDataOutput()) == null)
		{
			return null;
		}

		DataSink dsink;

		try
		{
			dsink = Manager.createDataSink(ds, outML);
			dsink.open();
		}
		catch (Exception 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)
		{
			if(evt.getSourceController() != null)
			{
				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[i].equals("-w"))
			{
				i++;
				if (i >= args.length)
					prUsage();
				width = new Integer(args[i]).intValue();
			}
			else if (args[i].equals("-h"))
			{
				i++;
				if (i >= args.length)
					prUsage();
				height = new Integer(args[i]).intValue();
			}
			else if (args[i].equals("-f"))
			{
				i++;
				if (i >= args.length)
					prUsage();
				frameRate = new Integer(args[i]).intValue();
			}
			else if (args[i].equals("-o"))
			{
				i++;
				if (i >= args.length)
					prUsage();
				outputURL = args[i];
			}
			else
			{
				inputFiles.addElement(args[i]);
			}

			i++;
		}

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


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

		// Generate the output media locators.
		MediaLocator oml;

		if ((oml = createMediaLocator(outputURL)) == null)
		{
			return;
		}

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

	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> ...");
		return;
	}

	private static MediaLocator createMediaLocator(String url)
	{
		try
		{
			return new MediaLocator(new URL("file:" + url));
		}
		catch (MalformedURLException e)
		{
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 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.
				buf.setEOM(true);
				buf.setOffset(0);
				buf.setLength(0);
				ended = true;
				return;
			}

			String imageFile = (String)images.elementAt(nextImage);
			nextImage++;

			// 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());

			buf.setOffset(0);
			buf.setLength((int)raFile.length());
			buf.setFormat(format);
			buf.setFlags(buf.getFlags() | Buffer.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;
		}
	}
}

Last edited by Harakim; Nov 28th, 2007 at 11:24 AM.
Harakim is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Image float, wrap text, oh boy! DaveQB HTML / XHTML / CSS 1 May 20th, 2006 12:34 AM
Image Viewer (Urgent Bèta testing) SoniX Visual Basic .NET 8 Sep 21st, 2005 5:25 PM
raw image conversion jasoncrab C++ 1 Aug 25th, 2005 10:11 PM
Rent a movie. Broax Coder's Corner Lounge 13 Jul 24th, 2005 1:44 PM
Checking source codes of image, audio and video files on_auc C++ 3 Feb 21st, 2005 8:36 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 2:36 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC