简体   繁体   English

如何使用 Java 从 MJPEG 流中保存图片?

[英]How to save Pictures from MJPEG Stream with Java?

How is it possible to save the pictures from a MJPEG Stream in Java?如何在 Java 中保存来自 MJPEG 流的图片? I want to call a HTTP MJPEG address and save every single frame to a seperate picture file.我想调用一个 HTTP MJPEG 地址并将每一帧保存到一个单独的图片文件中。

VLCj should be able to play that stream. VLCj 应该能够播放该流。 If you want to just save screenshots every so often, you should be able to use DirectMediaPlayer (which will give you a BufferedImage) then use ImageIO to save it.如果您只想经常保存屏幕截图,您应该能够使用DirectMediaPlayer (它会给您一个 BufferedImage)然后使用 ImageIO 来保存它。

Note though that it's not the easiest API in the world to use and requires native code;请注意,它不是世界上最容易使用的 API,并且需要本机代码; if you're a beginner (which from the question it seems you might be?) then this isn't the simplest of tasks!如果您是初学者(从问题看来您可能是?)那么这不是最简单的任务!

My stream server running on linux ,I used wget command to rec我的流服务器在 linux 上运行,我使用 wget 命令来记录

sudo wget -O ./outputfile.mjpg  XXX.XXX.XXX.XXX:port

then converted outputfile.mjpg to outputfile.mp4 using然后使用将 outputfile.mjpg 转换为 outputfile.mp4

ffmpeg -r 1/5 -i  outputfile.mjpg  outputfile.mp4.

See http://wiki.bitplan.com/index.php/MJpegStreamer which was published by a few years ago.请参阅几年前发布的http://wiki.bitplan.com/index.php/MJpegStreamer

There are multiple implementations in that project.该项目中有多个实现。 Here is one example:这是一个例子:

package com.bitplan.mjpegstreamer;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.logging.Level;

import com.bitplan.mjpegstreamer.ViewerSetting.DebugMode;

/**
 * Alternative MJpegRunner implementation
 * http://code.google.com/p/ipcapture/source/browse/IPCapture.java?r=0d
 * f4452208266f77fdc09b427682eaee09054fcb for an alternative implementation
 * Copyright (c) 2014 Wolfgang Fahl
 * 
 */
public class MJpegReaderRunner2 extends MJpegRunnerBase {

    private ByteArrayOutputStream jpgOut;

    public final static String VERSION = "0.1.1";

    /**
     * no args default constructor
     */
    public MJpegReaderRunner2() {

    }

    @Override
    public void init(InputStream inputStream) throws IOException {
        this.curFrame = new byte[0];
        this.frameAvailable = false;
        if (inputStream != null)
            this.inputStream = new BufferedInputStream(inputStream);
        // if (debug)
        // debugTrace("init called");
    }

    /**
     * stop reading
     */
    public synchronized void stop(String msg) {
        try {
            if (jpgOut != null)
                jpgOut.close();
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (IOException e) {
            handle("Error closing streams: ", e);
        }
        DebugMode debugMode = DebugMode.None;
        if (viewer != null)
            debugMode = viewer.getViewerSetting().debugMode;
        if ((debugMode == DebugMode.Verbose) && (conn!=null))
            LOGGER
                    .log(Level.INFO, "stopping connection " + conn.getClass().getName());
        if (conn instanceof HttpURLConnection) {
            HttpURLConnection httpcon = (HttpURLConnection) conn;
            if (debugMode == DebugMode.Verbose)
                LOGGER.log(Level.INFO, "disconnecting " + this.getUrlString());
            httpcon.disconnect();
        }
        if (debugMode == DebugMode.Verbose)
            debugTrace("stop with msg: " + msg, this);
        super.stop(msg);
    }

    /**
     * run me
     */
    public void run() {
        connect();
        if (!connected)
            throw new IllegalStateException(
                    "connection lost immediately after connect");
        int prev = 0;
        int cur = 0;

        try {
            // EOF is -1
            readloop: while (connected && (inputStream != null)
                    && ((cur = inputStream.read()) >= 0)) {
                if (prev == 0xFF && cur == 0xD8) {
                    jpgOut = new ByteArrayOutputStream(INPUT_BUFFER_SIZE);
                    jpgOut.write((byte) prev);
                }
                if (jpgOut != null) {
                    jpgOut.write((byte) cur);
                    if (prev == 0xFF && cur == 0xD9) {
                        synchronized (curFrame) {
                            curFrame = jpgOut.toByteArray();
                        }
                        frameAvailable = true;
                        jpgOut.close();
                        // the image is now available - read it and check if we reached the
                        // limit
                        // e.g. maxFrameCount
                        connected = read();
                        // LOGGER.log(Level.INFO,this.getTimeMsg());
                        if (!connected) {
                            break readloop;
                        }
                    }
                }
                prev = cur;
            }
            // end of input stream reached
            String msg = "end of inputstream " + this.getTimeMsg();
            if (viewer!=null)
                msg+=" read time out is set at "+viewer.getViewerSetting().readTimeOut+" msecs";
            stop(msg);
        } catch (IOException e) {
            handle("I/O Error " + this.getTimeMsg() + ":", e);
        }
    }

}

您可以解析出 Jpeg 字节并将它们保存到文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM