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

发布于 2024-11-28 04:46:23 字数 68 浏览 1 评论 0原文

如何在 Java 中保存 MJPEG 流中的图片? 我想调用 HTTP MJPEG 地址并将每一帧保存到单独的图片文件中。

How is it possible to save the pictures from a MJPEG Stream in Java?
I want to call a HTTP MJPEG address and save every single frame to a seperate picture file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ぃ弥猫深巷。 2024-12-05 04:46:23

VLCj 应该能够播放该流。如果您只想经常保存屏幕截图,则应该可以使用 DirectMediaPlayer (这将为您提供一个 BufferedImage),然后使用 ImageIO 保存它。

请注意,尽管它不是世界上最容易使用的 API,并且需要本机代码;如果您是初学者(从问题来看您可能是初学者?)那么这不是最简单的任务!

VLCj should be able to play that stream. 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.

Note though that it's not the easiest API in the world to use and requires native code; if you're a beginner (which from the question it seems you might be?) then this isn't the simplest of tasks!

知你几分 2024-12-05 04:46:23

我的流服务器在Linux上运行,我使用wget命令来rec

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

然后使用将outputfile.mjpg转换为outputfile.mp4

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

My stream server running on linux ,I used wget command to rec

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

then converted outputfile.mjpg to outputfile.mp4 using

ffmpeg -r 1/5 -i  outputfile.mjpg  outputfile.mp4.
疏忽 2024-12-05 04:46:23

请参阅 http://wiki.bitplan.com/index.php/MJpegStreamer 这是几年前出版的。

该项目中有多个实现。这是一个例子:

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);
        }
    }

}

See http://wiki.bitplan.com/index.php/MJpegStreamer which was published by a few years ago.

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);
        }
    }

}
哽咽笑 2024-12-05 04:46:23

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

You can just parse out the Jpeg bytes and save them into files.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文