Pantalla de flujo de android

Estoy tratando de fallar Truiton ScreenCapture ejemplo, con el fin de grabar la pantalla del dispositivo utilizando MediaProjection

Al guardar la grabación localmente, funciona

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(); 

Cómo siempre al cambiar a trabajar con FileDescriptor no es

  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(); 

Si no usa el LocalServerSocket, entonces mMediaRecorder.prepare() lanzar excepción, ahora que lo estoy utilizando, obtengo una excepción en el siguiente método en 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*/); } 

La excepción

 Caused by: java.lang.IllegalStateException: failed to get surface at android.media.MediaRecorder.getSurface(Native Method) at com.truiton.screencapture.MainActivity$override.createVirtualDisplay(MainActivity.java:172) at com.truiton.screencapture.MainActivity$override.onActivityResult(MainActivity.java:133) at com.truiton.screencapture.MainActivity$override.access$dispatch(MainActivity.java) at com.truiton.screencapture.MainActivity.onActivityResult(MainActivity.java:0) at android.app.Activity.dispatchActivityResult(Activity.java:6456) at android.app.ActivityThread.deliverResults(ActivityThread.java:3695) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) at android.app.ActivityThread.-wrap16(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Éste es mi servidor de Java, consigo el zócalo después de que mMediaRecorder.prepare() se llama y se pegó en inputStream.read como eccpected. La excepción en Android se produce cuando llamo a 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(); } 

Tienes que usar LocalServerSocket, a continuación es lo que parcialmente funcionó para mí, tengo una clase MediaStreamer que se extiende 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; } } } 

Para grabación

 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(); 


Pero el principal problema es mp4 no es muy fácil de transmitir . El problema básico es que MP4 no es en directo, formato streamable, por lo que a pesar de que los datos se capturan a través de la toma, los archivos de archivos cruciales que normalmente se escriben en la conclusión de una captura de audio o video, faltan (porque sockets no seekeable como Archivos locales) – por lo tanto, los datos no reproducibles (Y por lo tanto, por qué funciona bien cuando se guarda como archivos locales, es comprensible).

No hay una manera fácil de realizar el post-procesamiento en los datos para agregar manualmente los encabezados de los archivos. Así que la solución es o bien no utilice MP4 como el formato de grabación, o, escribir un packetiser similar a lo que se utiliza en el proyecto Spydroid

Espero que esto ayude !

  • Androide lectura entrada de usuario en un servicio
  • Problema de desacoplamiento de parcelables
  • Establecer funcionalidad del botón de retroceso del widget de búsqueda
  • ¿Cómo puedo establecer alarmas exactas y repetitivas en Android 4.4?
  • Mapbox infla la vista en el fragmento
  • ¿Cómo incluir dependencias en el proyecto de gradol de la biblioteca android?
  • ¿Cómo obtengo el búfer de la cámara Android en bruto en C con JNI?
  • Combinación de java y nodejs para la aplicación android
  • Obtener el amanecer y la puesta del sol
  • ¿Restar el modo Blend usando ColorMatrixFilter en Android?
  • Cómo utilizar CompositeDisposable de RxJava 2?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.