java - Stream android screen -
i trying fallow truiton screencapture example, in order record device screen using mediaprojection
when saving recording localy works
mmediarecorder.setvideosource(mediarecorder.videosource.surface); mmediarecorder.setoutputformat(mediarecorder.outputformat.mpeg_4); string localfilepath = getlocalfilepath(); mmediarecorder.setoutputfile(localfilepath); mmediarecorder.setvideosize(display_width, display_height); mmediarecorder.setvideoencoder(mediarecorder.videoencoder.mpeg_4_sp); mmediarecorder.setvideoframerate(30); mmediarecorder.prepare();
how ever when changing work filedescriptor it's not
mmediarecorder.setvideosource(mediarecorder.videosource.surface); mmediarecorder.setoutputformat(mediarecorder.outputformat.mpeg_4); string hostname = "10.26.100.18"; int port = 2007; socket socket = new socket(inetaddress.getbyname(hostname), port); parcelfiledescriptor filedescriptor = parcelfiledescriptor.fromsocket(socket); localserversocket localserversocket = new localserversocket(filedescriptor.getfiledescriptor()); mmediarecorder.setoutputfile(localserversocket.getfiledescriptor()); mmediarecorder.setvideosize(display_width, display_height); mmediarecorder.setvideoencoder(mediarecorder.videoencoder.mpeg_4_sp); mmediarecorder.setvideoframerate(30); mmediarecorder.prepare();
if not using localserversocket, mmediarecorder.prepare()
throw exception, using it, exception in below method in mmediarecorder.getsurface()
private virtualdisplay createvirtualdisplay() { return mmediaprojection.createvirtualdisplay("mainactivity", display_width, display_height, mscreendensity, displaymanager.virtual_display_flag_auto_mirror, mmediarecorder.getsurface(), null /*callbacks*/, null /*handler*/); }
the exception
caused by: java.lang.illegalstateexception: failed surface @ android.media.mediarecorder.getsurface(native method) @ com.truiton.screencapture.mainactivity$override.createvirtualdisplay(mainactivity.java:172) @ com.truiton.screencapture.mainactivity$override.onactivityresult(mainactivity.java:133) @ com.truiton.screencapture.mainactivity$override.access$dispatch(mainactivity.java) @ com.truiton.screencapture.mainactivity.onactivityresult(mainactivity.java:0) @ android.app.activity.dispatchactivityresult(activity.java:6456) @ android.app.activitythread.deliverresults(activitythread.java:3695) @ android.app.activitythread.handlesendresult(activitythread.java:3742) @ android.app.activitythread.-wrap16(activitythread.java) @ android.app.activitythread$h.handlemessage(activitythread.java:1393) @ android.os.handler.dispatchmessage(handler.java:102) @ android.os.looper.loop(looper.java:148) @ android.app.activitythread.main(activitythread.java:5417) @ java.lang.reflect.method.invoke(native method) @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:726) @ com.android.internal.os.zygoteinit.main(zygoteinit.java:616)
this java server, socket after mmediarecorder.prepare()
called , stuck on inputstream.read
eccpected. exception in android happands when call mmediarecorder.start()
final byte[] buffer = new byte[1024]; try { serversocket serversocket = new serversocket(2007); while (!serversocket.isclosed()) { socket socket = serversocket.accept(); file videofile = createemptyvideofile(); fileoutputstream outputstream = new fileoutputstream(videofile); inputstream inputstream = socket.getinputstream(); int length = inputstream.read(buffer); while (length != -1) { outputstream.write(buffer, 0, length); length = inputstream.read(buffer); } } } catch (ioexception e) { e.printstacktrace(); }
you have use localserversocket, below partially worked me, have mediastreamer class extends mediarecorder.
public class mediastreamer extends mediarecorder { private localserversocket localserversocket = null; private localsocket receiver, sender = null; public void prepare() throws illegalstateexception,ioexception { receiver = new localsocket(); try { localserversocket = new localserversocket("<your_socket_addr>"); receiver.connect(new localsocketaddress("<your_socket_addr>")); receiver.setreceivebuffersize(4096); receiver.setsendbuffersize(4096); sender = localserversocket.accept(); sender.setreceivebuffersize(4096); sender.setsendbuffersize(4096); } catch (ioexception e1) { throw new ioexception("can't create local socket !"); } setoutputfile(sender.getfiledescriptor()); try { super.prepare(); } catch (exception e) { closesockets(); throw e; } } public inputstream getinputstream() { inputstream out = null; try { out = receiver.getinputstream(); } catch (ioexception e) { } return out; } public void stop() { closesockets(); super.stop(); } private void closesockets() { if (localserversocket !=null) { try { localserversocket.close(); sender.close(); receiver.close(); } catch (ioexception e) { } localserversocket = null; sender = null; receiver = null; } } }
for recording
video = new mediastreamer(); video.reset(); video.setvideosource(mediarecorder.videosource.default); video.setpreviewdisplay(holder.getsurface()); video.setoutputformat(mediarecorder.outputformat.mpeg_4); video.setvideoframerate(videoconstants.framerate); video.setvideoencodingbitrate(videoconstants.bitrate*1000); video.setvideosize(videoconstants.resolationx, videoconstants.resolationy); video.setvideoencoder(mediarecorder.videoencoder.mpeg_4_sp); try { video.prepare(); } catch (ioexception e) { e.printstacktrace(); } video.start();
but main problem mp4 not easy stream . basic problem mp4 not live, streamable format, though data captured via socket, crucial file headers written @ conclusion of audio or video capture, missing (because sockets not seekeable local files) - hence unplayable data (and so, why works fine when saved local files, understandable).
there no easy way perform post-processing on data manually add file headers. solution either don't use mp4 recording format, or, write packetiser similar used in spydroid project
hope helps !
Comments
Post a Comment