package cn.com.basic.face.util;
|
|
import java.io.BufferedInputStream;
|
import java.io.ByteArrayInputStream;
|
import java.io.DataInputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.net.URI;
|
import java.util.Properties;
|
|
import org.apache.http.HttpResponse;
|
import org.apache.http.client.ClientProtocolException;
|
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.impl.client.DefaultHttpClient;
|
|
import android.graphics.Bitmap;
|
import android.graphics.BitmapFactory;
|
|
public class MjpegInputStream extends DataInputStream {
|
private final byte[] SOI_MARKER = { (byte) 0xFF, (byte) 0xD8 };
|
private final byte[] EOF_MARKER = { (byte) 0xFF, (byte) 0xD9 };
|
private final String CONTENT_LENGTH = "Content-Length";
|
private final static int HEADER_MAX_LENGTH = 100;
|
private final static int FRAME_MAX_LENGTH = 40000 + HEADER_MAX_LENGTH;
|
private int mContentLength = -1;
|
|
public static MjpegInputStream read(String url) {
|
HttpResponse res;
|
DefaultHttpClient httpclient = new DefaultHttpClient();
|
try {
|
res = httpclient.execute(new HttpGet(URI.create(url)));
|
return new MjpegInputStream(res.getEntity().getContent());
|
} catch (ClientProtocolException e) {
|
} catch (IOException e) {}
|
return null;
|
}
|
|
public MjpegInputStream(InputStream in) { super(new BufferedInputStream(in, FRAME_MAX_LENGTH)); }
|
|
private int getEndOfSeqeunce(DataInputStream in, byte[] sequence) throws IOException {
|
int seqIndex = 0;
|
byte c;
|
for(int i=0; i < FRAME_MAX_LENGTH; i++) {
|
c = (byte) in.readUnsignedByte();
|
if(c == sequence[seqIndex]) {
|
seqIndex++;
|
if(seqIndex == sequence.length) return i + 1;
|
} else seqIndex = 0;
|
}
|
return -1;
|
}
|
|
private int getStartOfSequence(DataInputStream in, byte[] sequence) throws IOException {
|
int end = getEndOfSeqeunce(in, sequence);
|
return (end < 0) ? (-1) : (end - sequence.length);
|
}
|
|
private int parseContentLength(byte[] headerBytes) throws IOException, NumberFormatException {
|
ByteArrayInputStream headerIn = new ByteArrayInputStream(headerBytes);
|
Properties props = new Properties();
|
props.load(headerIn);
|
return Integer.parseInt(props.getProperty(CONTENT_LENGTH));
|
}
|
|
public Bitmap readMjpegFrame() throws IOException {
|
mark(FRAME_MAX_LENGTH);
|
int headerLen = getStartOfSequence(this, SOI_MARKER);
|
reset();
|
byte[] header = new byte[headerLen];
|
readFully(header);
|
try {
|
mContentLength = parseContentLength(header);
|
} catch (NumberFormatException nfe) {
|
mContentLength = getEndOfSeqeunce(this, EOF_MARKER);
|
}
|
reset();
|
byte[] frameData = new byte[mContentLength];
|
skipBytes(headerLen);
|
readFully(frameData);
|
return BitmapFactory.decodeStream(new ByteArrayInputStream(frameData));
|
}
|
}
|