首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >网络摄像头api :最大化720p捕获

网络摄像头api :最大化720p捕获
EN

Stack Overflow用户
提问于 2018-02-11 09:04:15
回答 1查看 433关注 0票数 4

我正在尝试通过外部摄像头Logitec C922捕获视频记录。使用java,我可以通过网络摄像头api来实现这一点。

代码语言:javascript
复制
    <dependency>
        <groupId>com.github.sarxos</groupId>
        <artifactId>webcam-capture</artifactId>
        <version>0.3.10</version>
    </dependency>
    <dependency>
        <groupId>xuggle</groupId>
        <artifactId>xuggle-xuggler</artifactId>
        <version>5.4</version>
    </dependency>

然而,对于我的生活,我不能让它记录在60FPS。视频在存储时会随机卡顿,而且一点也不流畅。

我可以使用以下详细信息连接到摄像头。

代码语言:javascript
复制
final List<Webcam> webcams = Webcam.getWebcams();

for (final Webcam cam : webcams) {
    if (cam.getName().contains("C922")) {
        System.out.println("### Logitec C922 cam found");
        webcam = cam;
        break;
    }
}

我将凸轮的大小设置为以下值:

代码语言:javascript
复制
final Dimension[] nonStandardResolutions = new Dimension[] { WebcamResolution.HD720.getSize(), };
webcam.setCustomViewSizes(nonStandardResolutions);
webcam.setViewSize(WebcamResolution.HD720.getSize());
webcam.open(true);

然后我捕捉这些图像:

代码语言:javascript
复制
while (continueRecording) {
    // capture the webcam image
    final BufferedImage webcamImage = ConverterFactory.convertToType(webcam.getImage(),
                    BufferedImage.TYPE_3BYTE_BGR);
    final Date timeOfCapture = new Date();

    // convert the image and store
    final IConverter converter = ConverterFactory.createConverter(webcamImage, IPixelFormat.Type.YUV420P);
    final IVideoPicture frame = converter.toPicture(webcamImage,
                    (System.currentTimeMillis() - start) * 1000);

    frame.setKeyFrame(false);
    frame.setQuality(0);
    writer.encodeVideo(0, frame);

}

我的作者定义如下:

代码语言:javascript
复制
final Dimension size = WebcamResolution.HD720.getSize();
final IMediaWriter writer = ToolFactory.makeWriter(videoFile.getName());
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, size.width, size.height);

老实说,我不确定我的代码中是什么导致了这种情况。考虑到我降低了分辨率,我没有得到任何问题。( 480p )会不会是我使用的代码有问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-20 02:38:12

正如一些评论所提到的,引入队列确实解决了问题。以下是执行所需步骤的一般逻辑。注意,我已经将我的代码设置为较低的分辨率,因为它允许我每秒捕获100FPS。根据需要进行调整。

用于链接图像/视频捕获的类和用于编辑图像/视频捕获的类:

代码语言:javascript
复制
public class WebcamRecorder {

    final Dimension size = WebcamResolution.QVGA.getSize();
    final Stopper stopper = new Stopper();

    public void startRecording() throws Exception {

        final Webcam webcam = Webcam.getDefault();
        webcam.setViewSize(size);
        webcam.open(true);

        final BlockingQueue<CapturedFrame> queue = new LinkedBlockingQueue<CapturedFrame>();
        final Thread recordingThread = new Thread(new RecordingThread(queue, webcam, stopper));
        final Thread imageProcessingThread = new Thread(new ImageProcessingThread(queue, size));

        recordingThread.start();
        imageProcessingThread.start();
    }

    public void stopRecording() {
        stopper.setStop(true);
    }

}

RecordingThread:

代码语言:javascript
复制
public void run() {
    try {
        System.out.println("## capturing images began");
        while (true) {
            final BufferedImage webcamImage = ConverterFactory.convertToType(webcam.getImage(),
                    BufferedImage.TYPE_3BYTE_BGR);
            final Date timeOfCapture = new Date();
            queue.put(new CapturedFrame(webcamImage, timeOfCapture, false));
            if (stopper.isStop()) {
                System.out.println("### signal to stop capturing images received");
                queue.put(new CapturedFrame(null, null, true));
                break;
            }
        }
    } catch (InterruptedException e) {
        System.out.println("### threading issues during recording:: " + e.getMessage());
    } finally {
        System.out.println("## capturing images end");
        if (webcam.isOpen()) {
            webcam.close();
        }
    }
}

ImageProcessingThread:

代码语言:javascript
复制
public void run() {
    writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, size.width, size.height);
    try {
        int frameIdx = 0;
        final long start = System.currentTimeMillis();
        while (true) {
            final CapturedFrame capturedFrame = queue.take();
            if (capturedFrame.isEnd()) {
                break;
            }
            final BufferedImage webcamImage = capturedFrame.getImage();
            size.height);

            // convert the image and store
            final IConverter converter = ConverterFactory.createConverter(webcamImage, IPixelFormat.Type.YUV420P);
            final long end = System.currentTimeMillis();
            final IVideoPicture frame = converter.toPicture(webcamImage, (end - start) * 1000);

            frame.setKeyFrame((frameIdx++ == 0));
            frame.setQuality(0);
            writer.encodeVideo(0, frame);
        }
    } catch (final InterruptedException e) {
        System.out.println("### threading issues during image processing:: " + e.getMessage());
    } finally {
        if (writer != null) {
            writer.close();
        }
    }

它的工作方式非常简单。WebcamRecord类创建在视频捕获和图像处理之间共享的队列的实例。RecordingThread将bufferedImages发送到队列(在我的示例中,它是一个名为CapturedFrame的pojo (其中有一个BufferedImage ) )。ImageProcessingThread将侦听并从队列中提取数据。如果它没有接收到写入应该结束的信号,则循环永远不会终止。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48727205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档