android - MJPEG using AsyncTask02 in a VideoViewer/CustomViewer -
first "thanks @bbodenmiller!" (android ics , mjpeg using asynctask) code mjpeg-viewer works well. have problem. "mjpegactivity.java" works in new contentview:
private static final string tag = "mjpegactivity"; public static mjpegview mv; public static string url = "http://trackfield.webcam.oregonstate.edu/axis-cgi/mjpg/video.cgi?resolution=800x600&%3bdummy=1333689998337"; public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); button b01 = (button) findviewbyid(r.id.btn01); b01.setonclicklistener(new view.onclicklistener() { public void onclick(view view) {...}}); button cam01 = (button) findviewbyid(r.id.btncam01); cam01.setonclicklistener(new view.onclicklistener() { public void onclick(view view) { setcontentview(mv); new doread().execute(url); }}); }
that means old contentview example (setcontentview(r.layout.main);) overwritten. :( has idea how can display mjpegview in layout?or layout on mjpegview?because need buttons layout on mjpegview. many in advance!
i stripped mjpegview , display stream updating imageviews:
mainactivity
public class mainactivity extends activity { ipcamera cam1, cam2; imageview iv1, iv2; downloadimagetask task1, task2; final handler h = new handler(new callback() { @override public boolean handlemessage(message msg) { if (msg.what == 1){ bitmap bmp = (bitmap) msg.obj; iv1.setimagebitmap(bmp); }if(msg.what == 2){ bitmap bmp = (bitmap) msg.obj; iv2.setimagebitmap(bmp); } return false; } }); public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); this.setrequestedorientation(activityinfo.screen_orientation_landscape); setcontentview(r.layout.activity_main); iv1 = ((imageview) findviewbyid(r.id.imageview1)); iv2 = ((imageview) findviewbyid(r.id.imageview2)); cam1 = new ipcamera("http://10.0.0.101/video.cgi", "admin", "admin", this); cam2 = new ipcamera("http://10.0.0.102/video.cgi", "admin", "admin", this); task1 = starttask(cam1, 1, false, h); task2 = starttask(cam2, 2, false, h); } private downloadimagetask starttask(ipcamera cam, int id, boolean useparallelexecution, handler h) { downloadimagetask task = new downloadimagetask(cam, id); if (useparallelexecution) { task.executeonexecutor(asynctask.thread_pool_executor); } else { task.execute(h); } return task; } private class downloadimagetask extends asynctask<handler, void, void> { ipcamera cam; int id; downloadimagetask(ipcamera cam, int id){ this.cam = cam; this.id = id; } protected void doinbackground(handler... h) { cam.startstream(h[0], id); cam.getframe(); return null; } } }
ipcamera class
public class ipcamera{ private static final string tag = "mjpegactivity"; string url; string usr; string pwd; mjpeginputstream is; boolean running = false; handler h; context ctx; int id; ipcamera(string url, string usr, string pwd, context ctx){ this.url = url; this.usr = usr; this.pwd = pwd; this.ctx = ctx; } public void startstream(handler h, int id){ this.h = h; this.id = id; = new mjpeginputstream(httprequest(url,usr,pwd)); running = true; } public void getframe(){ while (running){ bitmap b; try { b = is.readmjpegframe(); message m = h.obtainmessage(id, b); m.sendtotarget(); } catch (ioexception e) { e.printstacktrace(); } } } public inputstream httprequest(string url, string usr, string pwd){ httpresponse res = null; defaulthttpclient httpclient = new defaulthttpclient(); credentialsprovider credprovider = new basiccredentialsprovider(); credprovider.setcredentials(new authscope(authscope.any_host, authscope.any_port), new usernamepasswordcredentials(usr, pwd)); httpclient.setcredentialsprovider(credprovider); log.d(tag, "1. sending http request"); try { res = httpclient.execute(new httpget(uri.create(url))); log.d(tag, "2. request finished, status = " + res.getstatusline().getstatuscode()); if(res.getstatusline().getstatuscode()==401){ //you must turn off camera user access control before work return null; } return res.getentity().getcontent(); } catch (clientprotocolexception e) { e.printstacktrace(); log.d(tag, "request failed-clientprotocolexception", e); //error connecting camera } catch (ioexception e) { e.printstacktrace(); log.d(tag, "request failed-ioexception", e); //error connecting camera } return null; } }
mjpeginputstream
had increase frame_max_lenght 400000 40000. more stable way.
public class mjpeginputstream extends datainputstream { private static final string tag = "mjpeginputstream"; 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 = 400000 + header_max_length; private int mcontentlength = -1; 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; < frame_max_length; i++) { c = (byte) in.readunsignedbyte(); if(c == sequence[seqindex]) { seqindex++; if(seqindex == sequence.length) { return + 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)); } }
not totally clean works. did 24 hour stability test , no errors. still have come way stop stream thread if camera connection goes down , reconnect when camera pops up.
Comments
Post a Comment