我在堆栈上关注此代码 Android ICS and MJPEG using AsyncTask
用于流式传输mjpeg for java(以下代码)。似乎正在发生的事情是mjpegview类正在创建mjpeg对象并强制主活动将其设置为其内容视图。有没有办法可以将mjpegviewer类中的surfaceholder抛出到我的xml中定义的表面视图中,以便我可以做其他事情?我试图创建一个表面视图并在mjpeg查看器类中替换它但它崩溃了..有没有人知道如何将它放入我自己的表面视图中?
主要行为 包com.example.mjpeg; import java.io.IOException;
import java.net.URI;
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 com.example.mjpeg.mjpegstream;
import com.example.mjpeg.mjpegview;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private mjpegview mv;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//sample public cam
String URL = "http://tfdsfdfdsfd.cgi";
// mv = new mjpegview(this);
setContentView(R.layout.activity_main);
setContentView(mv); //set preview as activity content
// setContentView(mv);
new DoRead().execute(URL);
}
public void onPause()
{
super.onPause();
mv.stopPlayback();
}
public class DoRead extends AsyncTask<String, Void, mjpegstream> {
protected mjpegstream doInBackground(String... url) {
//TODO: if camera has authentication deal with it and don't just not work
HttpResponse res = null;
DefaultHttpClient httpclient = new DefaultHttpClient();
Log.d(TAG, "1. Sending http request");
try {
res = httpclient.execute(new HttpGet(URI.create(url[0])));
Log.d(TAG, "2. Request finished, status = " + res.getStatusLine().getStatusCode());
if(res.getStatusLine().getStatusCode()==401){
//You must turn off camera User Access Control before this will work
return null;
}
return new mjpegstream(res.getEntity().getContent());
} catch (ClientProtocolException e) {
e.printStackTrace();
Log.d(TAG, "Request failed-ClientProtocolException", e);
//Error connecting to camera
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "Request failed-IOException", e);
//Error connecting to camera
}
return null;
}
protected void onPostExecute(mjpegstream result) {
mv.setSource(result);
mv.setDisplayMode(mjpegview.SIZE_BEST_FIT);
mv.showFps(true);
}
}
}
mjpegviewer类
package com.example.mjpeg;
import java.io.IOException;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class mjpegview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "mjpegview";
public final static int POSITION_UPPER_LEFT = 9;
public final static int POSITION_UPPER_RIGHT = 3;
public final static int POSITION_LOWER_LEFT = 12;
public final static int POSITION_LOWER_RIGHT = 6;
public final static int SIZE_STANDARD = 1;
public final static int SIZE_BEST_FIT = 4;
public final static int SIZE_FULLSCREEN = 8;
private MjpegViewThread thread;
private mjpegstream mIn = null;
private boolean showFps = false;
private boolean mRun = false;
private boolean surfaceDone = false;
private Paint overlayPaint;
private int overlayTextColor;
private int overlayBackgroundColor;
private int ovlPos;
private int dispWidth;
private int dispHeight;
private int displayMode;
public class MjpegViewThread extends Thread {
private SurfaceHolder mSurfaceHolder;
private int frameCounter = 0;
private long start;
private Bitmap ovl;
public MjpegViewThread(SurfaceHolder surfaceHolder, Context context) {
SurfaceView camSurface = (SurfaceView) findViewById(R.id.camSurface);
SurfaceHolder mSurfaceholder = camSurface.getHolder();
mSurfaceHolder = surfaceHolder;
}
private Rect destRect(int bmw, int bmh) {
int tempx;
int tempy;
if (displayMode == mjpegview.SIZE_STANDARD) {
tempx = (dispWidth / 2) - (bmw / 2);
tempy = (dispHeight / 2) - (bmh / 2);
return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
}
if (displayMode == mjpegview.SIZE_BEST_FIT) {
float bmasp = (float) bmw / (float) bmh;
bmw = dispWidth;
bmh = (int) (dispWidth / bmasp);
if (bmh > dispHeight) {
bmh = dispHeight;
bmw = (int) (dispHeight * bmasp);
}
tempx = (dispWidth / 2) - (bmw / 2);
// tempy = (dispHeight / 4) - (bmh / 2);
tempy = 0;
return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
}
if (displayMode == mjpegview.SIZE_FULLSCREEN){
return new Rect(0, 0, dispWidth, dispHeight);
}
return null;
}
public void setSurfaceSize(int width, int height) {
synchronized(mSurfaceHolder) {
dispWidth = width;
dispHeight = height;
}
}
private Bitmap makeFpsOverlay(Paint p, String text) {
Rect b = new Rect();
p.getTextBounds(text, 0, text.length(), b);
int bwidth = b.width()+2;
int bheight = b.height()+2;
Bitmap bm = Bitmap.createBitmap(bwidth, bheight, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
// p.setColor(overlayBackgroundColor);
c.drawRect(0, 0, bwidth, bheight, p);
// p.setColor(overlayTextColor);
// c.drawText(text, -b.left+1, (bheight/2)-((p.ascent()+p.descent())/2)+1, p);
return bm;
}
public void run() {
start = System.currentTimeMillis();
PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT);
Bitmap bm;
int width;
int height;
Rect destRect;
Canvas c = null;
Paint p = new Paint();
String fps;
while (mRun) {
if(surfaceDone) {
try {
c = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
try {
bm = mIn.readMjpegFrame();
destRect = destRect(bm.getWidth(),bm.getHeight());
// c.drawColor(Color.BLACK);
c.drawBitmap(bm, null, destRect, p);
if(showFps) {
p.setXfermode(mode);
if(ovl != null) {
height = ((ovlPos & 1) == 1) ? destRect.top : destRect.bottom-ovl.getHeight();
width = ((ovlPos & 8) == 8) ? destRect.left : destRect.right -ovl.getWidth();
c.drawBitmap(ovl, width, height, null);
}
p.setXfermode(null);
frameCounter++;
if((System.currentTimeMillis() - start) >= 1000) {
fps = String.valueOf(frameCounter)+" fps";
frameCounter = 0;
start = System.currentTimeMillis();
ovl = makeFpsOverlay(overlayPaint, fps);
}
}
} catch (IOException e) {
e.getStackTrace();
Log.d(TAG, "catch IOException hit in run", e);
}
}
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
private void init(Context context) {
SurfaceHolder holder = getHolder();
getHolder().setFormat(PixelFormat.TRANSLUCENT);
holder.addCallback(this);
thread = new MjpegViewThread(holder, context);
// setFocusable(true);
overlayPaint = new Paint();
overlayPaint.setTextAlign(Paint.Align.LEFT);
overlayPaint.setTextSize(12);
overlayPaint.setTypeface(Typeface.DEFAULT);
overlayTextColor = Color.WHITE;
// overlayBackgroundColor = Color.BLACK;
ovlPos = mjpegview.POSITION_LOWER_RIGHT;
displayMode = mjpegview.SIZE_STANDARD;
dispWidth = getWidth();
dispHeight = getHeight();
}
public void startPlayback() {
if(mIn != null) {
mRun = true;
thread.start();
}
}
public void stopPlayback() {
mRun = false;
boolean retry = true;
while(retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
e.getStackTrace();
Log.d(TAG, "catch IOException hit in stopPlayback", e);
}
}
}
public mjpegview(Context context, AttributeSet attrs) {
super(context, attrs); init(context);
}
public void surfaceChanged(SurfaceHolder holder, int f, int w, int h) {
thread.setSurfaceSize(w, h);
}
public void surfaceDestroyed(SurfaceHolder holder) {
surfaceDone = false;
stopPlayback();
}
public mjpegview(Context context) {
super(context);
init(context);
}
public void surfaceCreated(SurfaceHolder holder) {
surfaceDone = true;
}
public void showFps(boolean b) {
showFps = b;
}
public void setSource(mjpegstream source) {
mIn = source;
startPlayback();
}
public void setOverlayPaint(Paint p) {
overlayPaint = p;
}
public void setOverlayTextColor(int c) {
overlayTextColor = c;
}
public void setOverlayBackgroundColor(int c) {
overlayBackgroundColor = c;
}
public void setOverlayPosition(int p) {
ovlPos = p;
}
public void setDisplayMode(int s) {
displayMode = s;
}
}
mjpeg stream class
package com.example.mjpeg;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
public class mjpegstream extends DataInputStream {
private static final String TAG = "mjpegstream";
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 mjpegstream(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) {
nfe.getStackTrace();
Log.d(TAG, "catch NumberFormatException hit", nfe);
mContentLength = getEndOfSeqeunce(this, EOF_MARKER);
}
reset();
byte[] frameData = new byte[mContentLength];
skipBytes(headerLen);
readFully(frameData);
return BitmapFactory.decodeStream(new ByteArrayInputStream(frameData));
}
}
任何帮助将不胜感激,谢谢
mv = new mjpegview(this);
// setContentView(R.layout.activity_main); 的setContentView(MV); //将预览设置为活动内容
View stolenView = mv;
// set your own view
setContentView(R.layout.activity_main);
View view =(findViewById(R.id.vids));
((ViewGroup) view).addView(stolenView);
答案 0 :(得分:1)
你可以尝试一些令人讨厌的伎俩。我没有亲自尝试,但我给你的想法。
从mjpegview
窃取视图。首先让他设置内容视图,然后像这样:
// obtain mjpegview reference
View stolenView = getWindow().getDecorView().findViewById(android.R.id.content);
// set your own view
setContentView(R.layout.activity_main);
现在只需将其添加到您的视图中。
(ParentView)(findViewById(R.id.mjpegviewContainer)).addView(stolenView);