Posted By:
Anonymous
Posted On:
Saturday, September 4, 2010 11:32 AM
Problem: I have a program, written in Java, which produces a never-ending animation Image by Image (Actually it is BufferedImage by BufferedImage, if thats important to anyone). I also have an external device with the ability to play streamed media. My aim was to create a separate class to handle both the image grabbing, the video conversion and the output. Heres a simplified version where images are pushed rather than pulled but I think youll get the idea. package pharos.media; import java.awt.image.BufferedImage; import java.io.OutputStream; public class ImagesToVideoConverter implements Runnable { private boolean recording; private OutputStream outstream; /
More>>
Problem:
I have a program, written in Java, which produces a never-ending animation Image by Image (Actually it is BufferedImage by BufferedImage, if thats important to anyone). I also have an
external device
with the ability to play streamed media. My aim was to create a separate class to handle both the image grabbing, the video conversion and the output. Heres a simplified version where images are pushed rather than pulled but I think youll get the idea.
package pharos.media;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
public class ImagesToVideoConverter implements Runnable {
private boolean recording;
private OutputStream outstream;
/** Creates a new video with the given dimensions.
* @param width - the number of pixels in each line
* @param heigh - the number of lines in each frame */
public ImagesToVideoConverter(int width,int heigh) { /* Initiate */ }
/** Sets the output stream and initiates a new video to it.
* What it really does is creating a new thread to handle the new OutputStream. All
* heavy work is done by that thread. */
public void setOutput(OutputStream outstream) {
this.outstream = outstream;
new Thread(this);
}
/** Closes the output stream and releases any other buffers held by the video. */
public void close() { recording = false; }
/** Appends the next image to the animation if and only if
animation
is on.
* Actually all it does is append the image to a FIFO list. The actual appending is
* controlled by
run()
. If the size of the FIFO-list exceeds some defined limit,
* the method either blocks until the list has been chewed down a bit or it might
* throw an exception of some sort.
* @param img - An image with this converters dimensions and containing RGB or ARGB data.
* @param duration - The time (in seconds) this image is supposed to be visible in the
* video. */
public void addImage(BufferedImage img,float duration) {}
@Override
public void run() {
recording = true;
// Setup a new video resource
// Convert outstream to a video output stream if necessary
// Loop as long as recording is on
while (recording) {
// If (there are any unhandled Images) do
// convert image to video frame
// append the image to the video output
// else wait a millisec or so
}
// turn off the video properly
// close the output stream
// dispose thread
}
}
Work:
Ive spent around 200 hours trying to get it to work. Most time was spent with JMF as I thought the javax.media.Processor interface would do the work for me. However, its only an interface and trying to implement it all got me back to where I begun.
I have read, downloaded and tested lots of example programs too. But most of them are designed to read video from either a file or an external device and none showed how to send an ongoing stream to a network.
So, I turned to QTJava. Ive read through
QuickTime For Java A Developers Notebook
twice. Its a good source for information but it has no topic at all concerning streams.
Example 8-2. Building a video track from image samples
looked promising at first. It only has two great disadvantages I dont seem to overcome. 1 It seems that you need to construct the whole video before you can start saving it to a file. 2 When saving the video to a file it uses a class called QTFile from which I find very hard to get a stream object from.
During those hours I often felt like I finally got it. I found a code snippet on the net that shows how to do it. I only have to change a few calls and try to find out what this and that means. Soon Im stuck on loads of nondocumented parameters you know, when you try to find out how to use the flags parameter, all you get from docs is specifies the flags. For QTJava it involves searching QT h- and c-files. Or rather their documentation.
I dont have much time left. The project should be finished next week and Ill have to concentrate on other routines. For now, Ill take the save-movie-to-file implementation but in the end I must get it to work.
Any suggestions?
<<Less