How to save Pictures from MJPEG Stream with Java?
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.
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!
Here is a code that could help you:
http://www.walking-productions.com/notslop/2010/04/20/motion-jpeg-in-flash-and-java/
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.
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);
}
}
}
You can just parse out the Jpeg bytes and save them into files.
精彩评论