【问题标题】:Unable to create java InputStream from javaCV FrameRecorder Class无法从 javaCV FrameRecorder 类创建 java InputStream
【发布时间】:2013-09-18 06:11:12
【问题描述】:

我正在使用 JavaCV 通过 FrameRecorder 从我的网络摄像头捕获视频。

我正在创建一个库实用程序类,它将网络摄像头视频作为“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();

我也愿意接受任何其他选择...

提前致谢

阿什

【问题讨论】:

  • 您说您接受替代解决方案,您能否解释一下您的目标是什么?为什么需要 AVI 流而不是原始流?
  • 该问题仅提及容器格式(avi),但未指定任何编解码器。是否应该解释为未压缩的视频流?如果您想掌握原始流数据,这些细节非常重要。
  • @DiegoCNascimento :我希望直接在网络浏览器上播放 avi 流,原始流无法实现。
  • @brunocodutra : 考虑我是视频流的新手,我只想要一个可以定向到浏览器上播放的视频流,所以请相应地回答我。

标签: java opencv ffmpeg javacv


【解决方案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。

您可以使用内存映射文件,但在这种情况下您想要连续捕获视频,我认为这不是一个好主意。

【讨论】:

    【解决方案2】:

    如果您的目标不是创建视频文件,为什么要使用FrameRecorder

    我能想到的最实用的解决方案是使用FrameGrabber 作为后端来简单地扩展InputStream。由于 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;
    }
    

    【讨论】:

    • 它想要什么,根据问题是生成的 AVI 流。为了什么?我不知道,也许是流媒体之类的。但这不是问题。
    • @DiegoCNascimento 这个问题肯定不是我读过的最清楚的问题之一,但我现在明白你的意思了。在深入研究之前,我将等待 OP 的反馈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2014-10-05
    • 2013-11-30
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多