我正在使用JavaCV使用FrameRecorder从我的网络摄像头捕获视频。
我正在创建一个库实用程序类,它将webCam视频作为'avi'视频InputStream提供,在这里我无法这样做,因为FrameRecorder没有提供任何这样的工具,所需要的只是一个文件名并将视频保留在文件系统上。 如何从FrameRecorder生成java InputStream?
以下是供参考的示例代码:
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();
我也对任何其他选择开放......
提前致谢
与Ashish
答案 0 :(得分:1)
根据http://code.google.com/p/javacv/source/browse/src/main/java/com/googlecode/javacv/cpp/avformat.java
似乎写入帧数据的方法如下:
/**
* 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);
作为其原生方法,您的赌注是重定向除文件之外的本机lib输出, 或使用返回的图像数据“构建”您的AVI。
您可以使用内存映射文件,但在这种情况下,您希望连续捕获视频,我认为这不是一个好主意。
答案 1 :(得分:1)
如果您的目标不是创建视频文件,为什么要使用FrameRecorder
?
我能想到的最实用的解决方案是使用InputStream
作为后端简单地扩展FrameGrabber
。由于JavaCV似乎没有开箱即用,所以我担心你必须自己做。
正如documentation for InputStream
所述,InputStream
的子类只能实现public abstract int read()
,但请记住,也很可能也需要覆盖其他方法。
一个好的选择是实施public int read(byte[] b)
。
作为参考,下面是一个非常简单的低效和不安全的实现。
警告未经过测试!
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;
}