Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android and MJPEG

I need to get the mjpeg stream from an IP camera, anyone know the right way do it? I googled a bit and I find this example

http://www.anddev.org/mjpeg_on_android_anyone-t1871.html

but I've been stucked when I tried to get the stream from another activity called by the main activity. Here the code:

Main acitivity

package com.test;   public class IntentTest extends Activity {     /** Called when the activity is first created. */     ListView myListView = null;     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.main);          myListView = (ListView)findViewById(R.id.listView);         final ArrayList<String> items = new ArrayList<String>();         items.add("00408C944B9A");         final ArrayAdapter<String> aa;         aa = new ArrayAdapter<String>(this,                 android.R.layout.simple_list_item_1,                 items);          myListView.setAdapter(aa);         myListView.setOnItemClickListener(listClicked);      }       private OnItemClickListener listClicked = new OnItemClickListener() {         public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {             // TODO Auto-generated method stub             Intent i = new Intent(IntentTest.this, OtherActivity.class);             i.putExtra("MAC", myListView.getItemAtPosition(position).toString());             startActivity(i);                  }     }; } 

Second activity

package com.test;  import com.test.mjpeg.mjpegsample.MjpegView.*; import com.test.parser.JSONParse;   public class OtherActivity extends Activity {     /** Called when the activity is first created. */     private MjpegView mv;     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);          Bundle extras = getIntent().getExtras();         if (extras != null){             String mac = (String)extras.get("MAC");             Log.i("Other", "---->" + mac);             TextView tv = (TextView)findViewById(R.id.textView);             tv.setText(mac);               String URL = "myurl";              requestWindowFeature(Window.FEATURE_NO_TITLE);             getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                      WindowManager.LayoutParams.FLAG_FULLSCREEN);              mv = new MjpegView(this);             setContentView(mv);                      mv.setSource(MjpegInputStream.read(URL));             mv.setDisplayMode(MjpegView.SIZE_BEST_FIT);             mv.showFps(true);                }     }      public void onPause() {         super.onPause();         mv.stopPlayback();     }   } 
like image 475
bl4d3 Avatar asked Jul 08 '10 15:07

bl4d3


1 Answers

I found this code over the internet some time ago, maybe it will be of some help to you.

MjpegSample Class

package de.mjpegsample;  import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.Window; import android.view.WindowManager; import de.mjpegsample.MjpegView.MjpegInputStream; import de.mjpegsample.MjpegView.MjpegView;  public class MjpegSample extends Activity {      private MjpegView mv;     private static final int MENU_QUIT = 1;      /* Creates the menu items */     public boolean onCreateOptionsMenu(Menu menu) {         menu.add(0, MENU_QUIT, 0, "Quit");     return true;     }      /* Handles item selections */     public boolean onOptionsItemSelected(MenuItem item) {             switch (item.getItemId()) {             case MENU_QUIT:                 finish();                 return true;                 }             return false;     }      public void onCreate(Bundle icicle) {         super.onCreate(icicle);         //sample public cam         String URL = "http://gamic.dnsalias.net:7001/img/video.mjpeg";          requestWindowFeature(Window.FEATURE_NO_TITLE);         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);         mv = new MjpegView(this);         setContentView(mv);                 mv.setSource(MjpegInputStream.read(URL));         mv.setDisplayMode(MjpegView.SIZE_BEST_FIT);         mv.showFps(false);     }      public void onPause() {         super.onPause();         mv.stopPlayback();     } } 

MjpegView Class

package de.mjpegsample.MjpegView;  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.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.Typeface; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView;  public class MjpegView extends SurfaceView implements SurfaceHolder.Callback {     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 MjpegInputStream 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) { 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 / 2) - (bmh / 2);                 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.DST_OVER);             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) {}                         }                     } finally { if (c != null) mSurfaceHolder.unlockCanvasAndPost(c); }                 }             }         }     }      private void init(Context context) {         SurfaceHolder holder = getHolder();         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) {}         }     }      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(MjpegInputStream 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;          } } 

MjpegInputStream Class

package de.mjpegsample.MjpegView;  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));     } } 

If you need any more info, let me know, I'll help in any way I can.

FYI: I did not write SimpleMjpegView, you can find more up to date code here

like image 86
Carlos Portes Avatar answered Sep 17 '22 23:09

Carlos Portes