Saving video from Android camera as local .mjpeg file -
i working on application save video .mpeg file on android devices. have been working vanevery's mjpeg project on github modest success, (https://github.com/vanevery/android-mjpeg-video-capture-ffmpeg/blob/master/src/com/mobvcasting/mjpegffmpeg/mjpegffmpegtest.java).
here code far:
public class videocapture extends activity implements onclicklistener, surfaceholder.callback, camera.previewcallback { public static final string logtag = "videocapture"; string szboundarystart = "\r\n\r\n--myboundary\r\ncontent-type: image/jpeg\r\ncontent-length: "; string szboundarydeltatime = "\r\ndelta-time: 110"; string szboundaryend = "\r\n\r\n"; private surfaceholder holder; private camera camera; private camcorderprofile camcorderprofile; boolean brecording = false; boolean bpreviewrunning = false; byte[] previewcallbackbuffer; file mjpegfile; fileoutputstream fos; bufferedoutputstream bos; button btnrecord; camera.parameters p; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); date t = new date(); simpledateformat sdf = new simpledateformat("yyyymmddhhmmss"); string szfilename = "videocapture-"+sdf.format(t)+"-"; try { mjpegfile = file.createtempfile(szfilename, ".mjpeg", environment.getexternalstoragedirectory()); } catch (exception e) { log.v(logtag,e.getmessage()); finish(); } requestwindowfeature(window.feature_no_title); getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, windowmanager.layoutparams.flag_fullscreen); setrequestedorientation(activityinfo.screen_orientation_landscape); setcontentview(r.layout.main); btnrecord = (button) this.findviewbyid(r.id.recordbutton); btnrecord.setonclicklistener(this); camcorderprofile = camcorderprofile.get(camcorderprofile.quality_high); surfaceview cameraview = (surfaceview) findviewbyid(r.id.cameraview); holder = cameraview.getholder(); holder.addcallback(this); holder.settype(surfaceholder.surface_type_push_buffers); cameraview.setclickable(true); cameraview.setonclicklistener(this); } public void onclick(view v) { if (brecording) { brecording = false; try { bos.flush(); bos.close(); } catch (ioexception e) { e.printstacktrace(); } log.v(logtag, "recording stopped"); } else { try { fos = new fileoutputstream(mjpegfile); bos = new bufferedoutputstream(fos); brecording = true; log.v(logtag, "recording started"); } catch (filenotfoundexception e) { e.printstacktrace(); } } } public void surfacecreated(surfaceholder holder) { log.v(logtag, "surfacecreated"); camera = camera.open(); } public void surfacechanged(surfaceholder holder, int format, int width, int height) { log.v(logtag, "surfacechanged"); if (!brecording) { if (bpreviewrunning){ camera.stoppreview(); } try { p = camera.getparameters(); p.setpreviewsize(camcorderprofile.videoframewidth, camcorderprofile.videoframeheight); p.setpreviewframerate(camcorderprofile.videoframerate); camera.setparameters(p); camera.setpreviewdisplay(holder); camera.setpreviewcallback(this); log.v(logtag,"startpreview"); camera.startpreview(); bpreviewrunning = true; } catch (ioexception e) { log.e(logtag,e.getmessage()); e.printstacktrace(); } } } public void surfacedestroyed(surfaceholder holder) { log.v(logtag, "surfacedestroyed"); if (brecording) { brecording = false; try { bos.flush(); bos.close(); } catch (ioexception e) { e.printstacktrace(); } } bpreviewrunning = false; camera.release(); finish(); } public void onpreviewframe(byte[] b, camera c) { if (brecording) { // assuming imageformat.nv21 if (p.getpreviewformat() == imageformat.nv21) { log.v(logtag,"started writing frame"); try { bytearrayoutputstream jpegbytearrayoutputstream = new bytearrayoutputstream(); yuvimage im = new yuvimage(b, imageformat.nv21, p.getpreviewsize().width, p.getpreviewsize().height, null); rect r = new rect(0,0,p.getpreviewsize().width,p.getpreviewsize().height); im.compresstojpeg(r, 5, jpegbytearrayoutputstream); byte[] jpegbytearray = jpegbytearrayoutputstream.tobytearray(); byte[] boundarybytes = (szboundarystart + jpegbytearray.length + szboundarydeltatime + szboundaryend).getbytes(); bos.write(boundarybytes); bos.write(jpegbytearray); bos.flush(); } catch (ioexception e) { e.printstacktrace(); } log.v(logtag,"finished writing frame"); } else { log.v(logtag,"not right format"); } } } @override public void onconfigurationchanged(configuration conf) { super.onconfigurationchanged(conf); } }
i suspect problem may in jpeg formatting (parsing) in onpreviewframe(). or advice highly appreciated. in advance.
it appears there threshold regards jpeg quality required mjpeg file play. changing,
im.compresstojpeg(r, 5, jpegbytearrayoutputstream);
to,
im.compresstojpeg(r, 75, jpegbytearrayoutputstream);
results in valid mjpeg file.
Comments
Post a Comment