MJPEG on Android anyone?

All your problems with Audio, Video and Images.

Re: MJPEG on Android anyone?

Postby Nettosama » Thu Jan 27, 2011 7:47 pm

I can't seem to get the last .java's posted here to see a mjpeg stream from a IP camera. The app forcefully closes when i run it, on a 2.1 android target (AVD). Apparently im not writing correctly the main .java file to use the Viewer classes written here, can anyone share that file?
Nettosama
Once Poster
Once Poster
 
Posts: 1
Joined: Thu Jan 27, 2011 7:44 pm

Top

Re: MJPEG on Android anyone?

Postby FilipeFreitas » Thu Feb 10, 2011 5:25 pm

XML:

<SurfaceView android:id="@+id/surface_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
>
</SurfaceView>

Java:

mv = new MjpegView(this, mSurfaceView);
mv.setDisplayMode(MjpegView.SIZE_FULLSCREEN);
mv.surfaceCreated(null);
mv.setSource(mjpeginputstream);
FilipeFreitas
Junior Developer
Junior Developer
 
Posts: 14
Joined: Fri Aug 06, 2010 5:50 pm

Re: MJPEG on Android anyone?

Postby toni.meireles » Tue Mar 01, 2011 9:32 pm

Does anyone have an Eclipse project they could share with this example working? It's driving me insane! I can't get the original project or the orignal plus latest changes on the thread working at all...

Any help would be *greatly* appreciated!
toni.meireles
Once Poster
Once Poster
 
Posts: 1
Joined: Tue Mar 01, 2011 5:52 pm

Re: MJPEG on Android anyone?

Postby kevinybh » Sun Mar 06, 2011 9:22 am

ive tried on the code and it didnt work at first. Line 248 of MjpegView gave me an compilation error
width = ((ovlPos & <img src="http://www.anddev.org/images/smilies/cool.png" alt="8)" title="Cool" /> == <img src="http://www.anddev.org/images/smilies/cool.png" alt="8)" title="Cool" /> ? destRect.left : destRect.right -ovl.getWidth()
so i changed it to the same value as the height and then it worked.
Launched the program in the emulator and tested in the device itself and it is able to display the mjpg image. and the display is flickering and i don't see any FPS indicator or anything? Am i supposed to see all that? and the image is a still image, it doesnt move unless i tilt my device and it has to reload again then the image changes.
im using a D-Link DCS-920 and the image file is "192.168.1.10/IMAGE.JPG"
is the code supposed to refresh at certain time?
need some help here, any help would be good :)
thanks!
kevinybh
Once Poster
Once Poster
 
Posts: 1
Joined: Sun Mar 06, 2011 9:12 am

Re: MJPEG on Android anyone?

Postby michele.diflorio » Thu Apr 07, 2011 3:26 pm

Hello, I donwloaded the 2 versione upladed on the email thread but both did not work. I have not compilation error, but when running, only a black screen I can see, without image. I am using an axis M1011 network camera and I am using the following url http://<my server>/axis-cgi/mjpg/video.cgi.
Any idea?
michele.diflorio
Once Poster
Once Poster
 
Posts: 1
Joined: Wed Apr 06, 2011 3:33 pm

Re: MJPEG on Android anyone?

Postby fredfr » Thu Apr 14, 2011 5:56 pm

Hello,
I use axis camera to make mjpeg streaming in html page with a iphone. :oops:
I am looking for making the same with android since lot of times. :cry:
I am very exiting about this code, :D but its for use with application.
It is posible to integrate this code in a html page?
Thank you
fredfr
Once Poster
Once Poster
 
Posts: 1
Joined: Thu Apr 14, 2011 5:33 pm

Top

Re: MJPEG on Android anyone?

Postby naab » Tue May 03, 2011 5:25 pm

Hi

first i would like to say thanks for the help I've been getting here with the explanations,
but there is a problem that I keep getting that I don't know how to fix

in this code :
" public static MjpegInputStream read(String url, String domain,int port, String username, String password) throws HandledException "

it says that the HandledException cannot be resovled to a type, anyone know how I can fix this?

thanks in advance
naab
Once Poster
Once Poster
 
Posts: 1
Joined: Tue May 03, 2011 5:20 pm

Re: MJPEG on Android anyone?

Postby mavispisces » Sat May 14, 2011 9:11 am

I tried this code and it work really fine but I have some problem to add 4 buttons on it.
I want to use this 4 buttons to remote my ip cam.
I add the following code in MjpegSample.java but it not work.
Button btn1 = new Button(this);
btn1.setText("up");
mv.addView(btn1, 50, 50);

I also make a SurfaceView and 4 buttons in my xml but i have no idea how to integrate it with my xml.

Hope someone can tell me how to fix this problem, thanks.
mavispisces
Once Poster
Once Poster
 
Posts: 1
Joined: Sat May 14, 2011 9:07 am

Re:

Postby secin07 » Thu Jun 16, 2011 11:18 am

padde wrote:Have you added the internet permission to your manifest?

--- Edit ---
Added the hole eclipse project.. new cam url.. more to see 24/7 :)

Hello, I used your code . But on getEndOfSeqeunce(DataInputStream in, byte[] sequence) throw a java.io.EOFException.

what does this mean?

Thank you very much!
secin07
Freshman
Freshman
 
Posts: 2
Joined: Fri Feb 26, 2010 9:48 am

Re: MJPEG on Android anyone?

Postby secin07 » Fri Jun 17, 2011 2:50 am

naab wrote:Hi

first i would like to say thanks for the help I've been getting here with the explanations,
but there is a problem that I keep getting that I don't know how to fix

in this code :
" public static MjpegInputStream read(String url, String domain,int port, String username, String password) throws HandledException "

it says that the HandledException cannot be resovled to a type, anyone know how I can fix this?

thanks in advance



I still got the problem always show black screen.
I found the exception is:

06-17 09:46:08.377: WARN/System.err(14896): java.io.EOFException
06-17 09:46:08.377: WARN/System.err(14896): at java.io.DataInputStream.readUnsignedByte(DataInputStream.java:396)
06-17 09:46:08.377: WARN/System.err(14896): at de.mjpegsample.MjpegView.MjpegInputStream.getEndOfSeqeunce(MjpegInputStream.java:44)
06-17 09:46:08.377: WARN/System.err(14896): at de.mjpegsample.MjpegView.MjpegInputStream.getStartOfSequence(MjpegInputStream.java:54)
06-17 09:46:08.377: WARN/System.err(14896): at de.mjpegsample.MjpegView.MjpegInputStream.readMjpegFrame(MjpegInputStream.java:67)
06-17 09:46:08.377: WARN/System.err(14896): at de.mjpegsample.MjpegView.MjpegView$MjpegViewThread.run(MjpegView.java:110)
secin07
Freshman
Freshman
 
Posts: 2
Joined: Fri Feb 26, 2010 9:48 am

Re: MJPEG on Android anyone?

Postby pengume » Tue Jul 05, 2011 9:19 pm

Hey everyone,

It looks and works fine for one video. However when I try to stream multiple MJpeg videos at the same time and display on the screen the performance slows down significantly. Would Anyone recommend a better way of going about this for multiple streams or any improvements they can see to implement to improve the performance. As of now it is pretty slow and not acceptable.
pengume
Once Poster
Once Poster
 
Posts: 1
Joined: Tue Jul 05, 2011 9:15 pm

Re: MJPEG on Android anyone?

Postby loraempson » Thu Jul 14, 2011 3:15 pm

MJEG problem is wisely addressed by you guys, I have different eloquent solution to share.
Last edited by loraempson on Mon Jul 25, 2011 12:06 pm, edited 1 time in total.
loraempson
Junior Developer
Junior Developer
 
Posts: 18
Joined: Fri Jul 01, 2011 2:02 pm

Re: MJPEG on Android anyone?

Postby cubrovic » Fri Jul 22, 2011 4:47 pm

Great code. Works well displaying mu mjpeg stream.
I only have problem that when I add mjpegView to linearlayout I can see some other content on that layout (two buttons bellow mjpegview) Tried nesting mjpegview in other linear layout. still no buttons bellow.
Any ideas on proper use of mjpegview with other components?
cubrovic
Freshman
Freshman
 
Posts: 8
Joined: Mon Jan 25, 2010 10:16 pm

Re:

Postby muebau » Thu Aug 04, 2011 8:32 am

Hi,
do you released this it under GPL2/3 license?

I would like to use it in a GPL2/3 App. I would be part of my SVN-Repo (google code).

Bye muebau

padde wrote:This could help i think.. i know this post is old but i read that forum quite a while now
and always want to give a little contribution in return for the help and informationen i got.
And because i came across the same problem lately and solved it my chance for contribution
arrived :D

This is a little app to simply show an MJPEG stream.. okay a few gadgets like resize and fps overlay
too but nothing too fancy.

First the Test Activity to show how to use the MjpegView
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package de.mjpegsample;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.view.Window;
  6. import android.view.WindowManager;
  7. import de.mjpegsample.MjpegView.MjpegInputStream;
  8. import de.mjpegsample.MjpegView.MjpegView;
  9.  
  10. public class MjpegSample extends Activity {
  11.         private MjpegView mv;
  12.        
  13.         public void onCreate(Bundle icicle) {
  14.         super.onCreate(icicle);
  15.        
  16.         //sample public cam
  17.         String URL = "http://www.gfp.cz:88/axis-cgi/mjpg/video.cgi?resolution=320x240";
  18.        
  19.         requestWindowFeature(Window.FEATURE_NO_TITLE);
  20.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  21.                              WindowManager.LayoutParams.FLAG_FULLSCREEN);
  22.        
  23.         mv = new MjpegView(this);
  24.         setContentView(mv);        
  25.        
  26.         mv.setSource(MjpegInputStream.read(URL));
  27.         mv.setDisplayMode(MjpegView.SIZE_BEST_FIT);
  28.         mv.showFps(true);
  29.         }
  30.        
  31.         public void onPause() {
  32.                 super.onPause();
  33.                 mv.stopPlayback();
  34.         }
  35. }
  36.  
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


In the MjpegInputStream Class the "real magic" happens
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package de.mjpegsample.MjpegView;
  2.  
  3. import java.io.BufferedInputStream;
  4. import java.io.ByteArrayInputStream;
  5. import java.io.DataInputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.net.URI;
  9. import java.util.Properties;
  10.  
  11. import org.apache.http.HttpResponse;
  12. import org.apache.http.client.ClientProtocolException;
  13. import org.apache.http.client.methods.HttpGet;
  14. import org.apache.http.impl.client.DefaultHttpClient;
  15.  
  16. import android.graphics.Bitmap;
  17. import android.graphics.BitmapFactory;
  18.  
  19. public class MjpegInputStream extends DataInputStream {
  20.     private final byte[] SOI_MARKER = { (byte) 0xFF, (byte) 0xD8 };
  21.     private final byte[] EOF_MARKER = { (byte) 0xFF, (byte) 0xD9 };
  22.     private final String CONTENT_LENGTH = "Content-Length";
  23.     private final static int HEADER_MAX_LENGTH = 100;
  24.     private final static int FRAME_MAX_LENGTH = 40000 + HEADER_MAX_LENGTH;
  25.     private int mContentLength = -1;
  26.        
  27.     public static MjpegInputStream read(String url) {
  28.         HttpResponse res;
  29.         DefaultHttpClient httpclient = new DefaultHttpClient();        
  30.         try {
  31.             res = httpclient.execute(new HttpGet(URI.create(url)));
  32.             return new MjpegInputStream(res.getEntity().getContent());                         
  33.         } catch (ClientProtocolException e) {
  34.         } catch (IOException e) {}
  35.         return null;
  36.     }
  37.        
  38.     public MjpegInputStream(InputStream in) {
  39.         super(new BufferedInputStream(in, FRAME_MAX_LENGTH));
  40.     }
  41.        
  42.     private int getEndOfSeqeunce(DataInputStream in, byte[] sequence)
  43.         throws IOException
  44.     {
  45.         int seqIndex = 0;
  46.         byte c;
  47.         for(int i=0; i < FRAME_MAX_LENGTH; i++) {
  48.             c = (byte) in.readUnsignedByte();
  49.             if(c == sequence[seqIndex]) {
  50.                 seqIndex++;
  51.                 if(seqIndex == sequence.length) return i + 1;
  52.             } else seqIndex = 0;
  53.         }
  54.         return -1;
  55.     }
  56.        
  57.     private int getStartOfSequence(DataInputStream in, byte[] sequence)
  58.         throws IOException
  59.     {
  60.         int end = getEndOfSeqeunce(in, sequence);
  61.         return (end < 0) ? (-1) : (end - sequence.length);
  62.     }
  63.  
  64.     private int parseContentLength(byte[] headerBytes)
  65.         throws IOException, NumberFormatException
  66.     {
  67.         ByteArrayInputStream headerIn = new ByteArrayInputStream(headerBytes);
  68.         Properties props = new Properties();
  69.         props.load(headerIn);
  70.         return Integer.parseInt(props.getProperty(CONTENT_LENGTH));
  71.     }  
  72.  
  73.     public Bitmap readMjpegFrame() throws IOException {
  74.         mark(FRAME_MAX_LENGTH);
  75.         int headerLen = getStartOfSequence(this, SOI_MARKER);
  76.         reset();
  77.         byte[] header = new byte[headerLen];
  78.         readFully(header);
  79.         try {
  80.             mContentLength = parseContentLength(header);
  81.         } catch (NumberFormatException nfe) {
  82.             mContentLength = getEndOfSeqeunce(this, EOF_MARKER);
  83.         }
  84.         reset();
  85.         byte[] frameData = new byte[mContentLength];
  86.         skipBytes(headerLen);
  87.         readFully(frameData);
  88.         return BitmapFactory.decodeStream(new ByteArrayInputStream(frameData));
  89.     }
  90. }
  91.  
Parsed in 0.044 seconds, using GeSHi 1.0.8.4



And last but not least the MjpegView to put MjpegInputStreams to the Display :wink:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package de.mjpegsample.MjpegView;
  2.  
  3. import java.io.IOException;
  4.  
  5. import android.content.Context;
  6. import android.graphics.Bitmap;
  7. import android.graphics.Canvas;
  8. import android.graphics.Color;
  9. import android.graphics.Paint;
  10. import android.graphics.PorterDuff;
  11. import android.graphics.PorterDuffXfermode;
  12. import android.graphics.Rect;
  13. import android.graphics.Typeface;
  14. import android.util.AttributeSet;
  15. import android.view.SurfaceHolder;
  16. import android.view.SurfaceView;
  17.  
  18. public class MjpegView extends SurfaceView implements SurfaceHolder.Callback {
  19.     public final static int POSITION_UPPER_LEFT  = 9;
  20.     public final static int POSITION_UPPER_RIGHT = 3;
  21.     public final static int POSITION_LOWER_LEFT  = 12;
  22.     public final static int POSITION_LOWER_RIGHT = 6;
  23.  
  24.     public final static int SIZE_STANDARD   = 1;
  25.     public final static int SIZE_BEST_FIT   = 4;
  26.     public final static int SIZE_FULLSCREEN = 8;
  27.    
  28.     private MjpegViewThread thread;
  29.     private MjpegInputStream mIn = null;    
  30.     private boolean showFps = false;
  31.     private boolean mRun = false;
  32.     private boolean surfaceDone = false;    
  33.     private Paint overlayPaint;
  34.     private int overlayTextColor;
  35.     private int overlayBackgroundColor;
  36.     private int ovlPos;
  37.     private int dispWidth;
  38.     private int dispHeight;
  39.     private int displayMode;
  40.  
  41.     public class MjpegViewThread extends Thread {
  42.         private SurfaceHolder mSurfaceHolder;
  43.         private int frameCounter = 0;
  44.         private long start;
  45.         private String fps = "";
  46.         private Bitmap ovl;
  47.          
  48.         public MjpegViewThread(SurfaceHolder surfaceHolder, Context context) {
  49.             mSurfaceHolder = surfaceHolder;
  50.         }
  51.  
  52.         private Rect destRect(int bmw, int bmh) {
  53.             int tempx;
  54.             int tempy;
  55.             if (displayMode == MjpegView.SIZE_STANDARD) {
  56.                 tempx = (dispWidth / 2) - (bmw / 2);
  57.                 tempy = (dispHeight / 2) - (bmh / 2);
  58.                 return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
  59.             }
  60.             if (displayMode == MjpegView.SIZE_BEST_FIT) {
  61.                 float bmasp = (float) bmw / (float) bmh;
  62.                 bmw = dispWidth;
  63.                 bmh = (int) (dispWidth / bmasp);
  64.                 if (bmh > dispHeight) {
  65.                     bmh = dispHeight;
  66.                     bmw = (int) (dispHeight * bmasp);
  67.                 }
  68.                 tempx = (dispWidth / 2) - (bmw / 2);
  69.                 tempy = (dispHeight / 2) - (bmh / 2);
  70.                 return new Rect(tempx, tempy, bmw + tempx, bmh + tempy);
  71.             }
  72.             if (displayMode == MjpegView.SIZE_FULLSCREEN)
  73.                 return new Rect(0, 0, dispWidth, dispHeight);
  74.             return null;
  75.         }
  76.          
  77.         public void setSurfaceSize(int width, int height) {
  78.             synchronized(mSurfaceHolder) {
  79.                 dispWidth = width;
  80.                 dispHeight = height;
  81.             }
  82.         }
  83.          
  84.         private Bitmap makeFpsOverlay(Paint p) {
  85.             Rect b = new Rect();
  86.             p.getTextBounds(fps, 0, fps.length(), b);
  87.  
  88. // false indentation to fix forum layout            
  89. Bitmap bm = Bitmap.createBitmap(b.width(), b.height(), Bitmap.Config.ARGB_8888);
  90.  
  91.             Canvas c = new Canvas(bm);
  92.             p.setColor(overlayBackgroundColor);
  93.             c.drawRect(0, 0, b.width(), b.height(), p);
  94.             p.setColor(overlayTextColor);
  95.             c.drawText(fps, -b.left, b.bottom-b.top-p.descent(), p);
  96.             return bm;           
  97.         }
  98.  
  99.         public void run() {
  100.             start = System.currentTimeMillis();
  101.             PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
  102.             Bitmap bm;
  103.             int width;
  104.             int height;
  105.             Rect destRect;
  106.             Canvas c = null;
  107.             Paint p = new Paint();
  108.             while (mRun) {
  109.                 if(surfaceDone) {
  110.                     try {
  111.                         c = mSurfaceHolder.lockCanvas();
  112.                         synchronized (mSurfaceHolder) {
  113.                             try {
  114.                                 bm = mIn.readMjpegFrame();
  115.                                 destRect = destRect(bm.getWidth(),bm.getHeight());
  116.                                 c.drawColor(Color.BLACK);
  117.                                 c.drawBitmap(bm, null, destRect, p);
  118.                                 if(showFps) {
  119.                                     p.setXfermode(mode);
  120.                                     if(ovl != null) {
  121.  
  122. // false indentation to fix forum layout                                                 
  123. height = ((ovlPos & 1) == 1) ? destRect.top : destRect.bottom-ovl.getHeight();
  124. width  = ((ovlPos & <img src="http://www.anddev.org/images/smilies/cool.png" alt="8)" title="Cool" /> == <img src="http://www.anddev.org/images/smilies/cool.png" alt="8)" title="Cool" /> ? destRect.left : destRect.right -ovl.getWidth();
  125.  
  126.                                         c.drawBitmap(ovl, width, height, null);
  127.                                     }
  128.                                     p.setXfermode(null);
  129.                                     frameCounter++;
  130.                                     if((System.currentTimeMillis() - start) >= 1000) {
  131.                                         fps = String.valueOf(frameCounter)+"fps";
  132.                                         frameCounter = 0;
  133.                                         start = System.currentTimeMillis();
  134.                                         ovl = makeFpsOverlay(overlayPaint);
  135.                                     }
  136.                                 }
  137.                             } catch (IOException e) {}
  138.                         }
  139.                     } finally { if (c != null) mSurfaceHolder.unlockCanvasAndPost(c); }
  140.                 }
  141.             }
  142.         }
  143.     }
  144.  
  145.     private void init(Context context) {
  146.         SurfaceHolder holder = getHolder();
  147.         holder.addCallback(this);
  148.         thread = new MjpegViewThread(holder, context);
  149.         setFocusable(true);
  150.         overlayPaint = new Paint();
  151.         overlayPaint.setTextAlign(Paint.Align.LEFT);
  152.         overlayPaint.setTextSize(12);
  153.         overlayPaint.setTypeface(Typeface.DEFAULT);
  154.         overlayTextColor = Color.WHITE;
  155.         overlayBackgroundColor = Color.BLACK;
  156.         ovlPos = MjpegView.POSITION_LOWER_RIGHT;
  157.         displayMode = MjpegView.SIZE_STANDARD;
  158.         dispWidth = getWidth();
  159.         dispHeight = getHeight();
  160.     }
  161.    
  162.     public void startPlayback() {
  163.         if(mIn != null) {
  164.             mRun = true;
  165.             thread.start();            
  166.         }
  167.     }
  168.    
  169.     public void stopPlayback() {
  170.         mRun = false;
  171.         boolean retry = true;
  172.         while(retry) {
  173.             try {
  174.                 thread.join();
  175.                 retry = false;
  176.             } catch (InterruptedException e) {}
  177.         }
  178.     }
  179.  
  180.     public MjpegView(Context context, AttributeSet attrs) {
  181.         super(context, attrs); init(context);
  182.     }
  183.  
  184.     public void surfaceChanged(SurfaceHolder holder, int f, int w, int h) {
  185.         thread.setSurfaceSize(w, h);
  186.     }
  187.  
  188.     public void surfaceDestroyed(SurfaceHolder holder) {
  189.         surfaceDone = false;
  190.         stopPlayback();
  191.     }
  192.    
  193.     public MjpegView(Context context) { super(context); init(context); }    
  194.     public void surfaceCreated(SurfaceHolder holder) { surfaceDone = true; }
  195.     public void showFps(boolean b) { showFps = b; }
  196.     public void setSource(MjpegInputStream source) { mIn = source; startPlayback();}
  197.     public void setOverlayPaint(Paint p) { overlayPaint = p; }
  198.     public void setOverlayTextColor(int c) { overlayTextColor = c; }
  199.     public void setOverlayBackgroundColor(int c) { overlayBackgroundColor = c; }
  200.     public void setOverlayPosition(int p) { ovlPos = p; }
  201.     public void setDisplayMode(int s) { displayMode = s; }
  202. }
  203.  
Parsed in 0.066 seconds, using GeSHi 1.0.8.4


Runs on newest SDK build Android SDK 1.1_r1 (at time of writing this)


Greets
Padde



--- Edited 09.04.2009 - 19:36 ---
Reason: less and more efficient Code + load speed improvements
muebau
Once Poster
Once Poster
 
Posts: 1
Joined: Wed Aug 03, 2011 3:19 pm

Application hanging when the server reboots

Postby rajjeshgnair » Tue Aug 23, 2011 7:34 am

Hi,
I have a question. This code works well in my application but when the server reboots the applications hangs at
c = (byte) in.readUnsignedByte(); in the
private int getEndOfSeqeunce(DataInputStream in, byte[] sequence) throws IOException
I'm not using any try catch in this method since i don't know much about the usage and i'm new to java.
Could any of you please tell me as to how to exit the application gracefully when the server reboots.
Thanks in advance
rajjeshgnair
Once Poster
Once Poster
 
Posts: 1
Joined: Tue Aug 23, 2011 7:13 am

Top
PreviousNext

Return to Multimedia Problems

Who is online

Users browsing this forum: Google Feedfetcher and 11 guests