Reputation: 1144
I am using JavaCV to capture the video from my web camera using FrameRecorder.
I am working to create a library utility class that would provide the webCam video as an 'avi' video InputStream, here I am unable to do so as the FrameRecorder does not provide any such facility, all it takes is a file name and persists the video on the filesystem. What should I do to generate a java InputStream from FrameRecorder?
Following is the sample code for reference :
FrameGrabber frameGrabber = FrameGrabber.createDefault(1);
frameGrabber.start();
IplImage grabbedImage = frameGrabber.grab();
int width = grabbedImage.width();
int height = grabbedImage.height();
FrameRecorder frameRecorder = new FFmpegFrameRecorder("c:\\output.avi", width, height);
frameRecorder.setAudioChannels(frameGrabber.getAudioChannels());
frameRecorder.start();
int i = 0;
while ((grabbedImage = frameGrabber.grab()) != null && i <= 500) {
frameRecorder.record(grabbedImage);
i++;
}
frameRecorder.stop();
frameGrabber.stop();
I am open to any other alternatives too ...
thanks in advance
Ashish
Upvotes: 0
Views: 1504
Reputation: 2349
Why do you want to use a FrameRecorder
if your goal is not to create a video file?
The most practical solution I can think of, would be to simply extend InputStream
using a FrameGrabber
as backend. Since JavaCV doesn't seem to provide that out of the box, then I'm afraid you'd have to do it yourself.
As described on the documentation for InputStream
, subclasses of InputStream
must only implement public abstract int read()
, however keep in mind it will also most probably be necessary to overwrite other methods too.
A good bet would be to implement public int read(byte[] b)
.
For reference, a very simple inefficient and unsafe implementation follows.
Warning not tested!
public int read(byte[] data) throws IOException, BufferUnderflowException, Exception {
IplImage grabbedImage = frameGrabber.grab();
if(grabbedImage == null)
throw <some IOException here>
grabbedImage.getByteBuffer().get(data);
return data.length;
}
Upvotes: 1
Reputation: 2801
According to http://code.google.com/p/javacv/source/browse/src/main/java/com/googlecode/javacv/cpp/avformat.java
Seems that the method that is called for writing the frame data is the following:
/**
* Write a packet to an output media file.
*
* The packet shall contain one audio or video frame.
* The packet must be correctly interleaved according to the container
* specification, if not then av_interleaved_write_frame must be used.
*
* @param s media file handle
* @param pkt The packet, which contains the stream_index, buf/buf_size,
* dts/pts, ...
* This can be NULL (at any time, not just at the end), in
* order to immediately flush data buffered within the muxer,
* for muxers that buffer up data internally before writing it
* to the output.
* @return < 0 on error, = 0 if OK, 1 if flushed and there is no more data to flush
*/
public static native int av_write_frame(AVFormatContext s, AVPacket pkt);
As its native method, your bet will be to redirect the native lib output other than a file, or using the image data returned to "build" your AVI.
You can use a memory mapped file, but in that case you want continuous capture of video, I don't think it would be a good idea.
Upvotes: 1