【问题标题】:How to save Pictures from MJPEG Stream with Java?如何使用 Java 从 MJPEG 流中保存图片?
【发布时间】:2011-08-05 07:52:52
【问题描述】:

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

【问题讨论】:

  • 好吧,您需要编写一些 Java 代码来接收 MJPEG 帧并将它们写入文件。也许您应该更具体地说明您在尝试时遇到的问题。
  • 嘿,谢谢,我不知道如何接收帧并将它们保存到磁盘。你能给我一个方法吗?
  • Favi,你知道如何从 Stream 接收数据吗?我会从那里开始。

标签: java http video stream mjpeg


【解决方案1】:

VLCj 应该能够播放该流。如果你只想经常保存截图,你应该可以使用DirectMediaPlayer(它会给你一个 BufferedImage)然后使用 ImageIO 来保存它。

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

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      我的流服务器在linux上运行,我使用wget命令来记录

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

      然后使用

      将 outputfile.mjpg 转换为 outputfile.mp4
      ffmpeg -r 1/5 -i  outputfile.mjpg  outputfile.mp4.
      

      【讨论】:

        【解决方案4】:

        参见几年前发布的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);
                }
            }
        
        }
        

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-08-22
            • 1970-01-01
            • 2014-08-27
            • 1970-01-01
            • 1970-01-01
            • 2012-02-21
            • 1970-01-01
            相关资源
            最近更新 更多