1

I'm working in a remote ScreenRecord in real time based in this code. With this code of reference i'm able to record screen of my smartphone with success and saving .mp4 file in some folder previous defined.

But to my project, i need that this content be sent to server (similar to Team View for android).

My last attempt to sent this content to server side was like this:

OutputStream os = clientSocket.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream (os);
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(encodedData);

oos.flush();
bos.flush();
os.flush();

Reference => this question

but comes a error of:

java.io.NotSerializableException in this line > oos.writeObject(encodedData);

Then, i want know how solve it or some other way to make this task.

Here is complete code:

 /////////////////////////////////////// CLIENTSOCKET ///////////////////////////////////////////

    Socket clientSocket;
    int SERVERPORT = 60;
    String SERVER_IP = "192.168.15.6";

    class ClientThread implements Runnable {

        @Override
        public void run() {

            try {

                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

                clientSocket = new Socket(serverAddr, SERVERPORT);

                new Thread(new CommsThread()).start();

            } catch (Exception e1) {
                System.out.println(e1.toString());
            }
        }
    }

    class CommsThread implements Runnable {

        @Override
        public void run() {

            try {
                System.out.println("Waiting for server request");

                while(clientSocket.isConnected()){

                    BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())),true);

                    if (reader.ready()) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            System.out.println(line);

                            if(line != null && !line.trim().isEmpty()) {

                                if(line.equalsIgnoreCase("screenrecord")){

                                    System.out.println(out.toString());

                                    mMediaProjectionManager = (MediaProjectionManager)getSystemService(android.content.Context.MEDIA_PROJECTION_SERVICE);
                                    Intent permissionIntent = mMediaProjectionManager.createScreenCaptureIntent();
                                    startActivityForResult(permissionIntent, REQUEST_CODE_CAPTURE_PERM);

                                    out.flush();
                                }

                                if(line.equalsIgnoreCase("exit")) {

                                    stopRecording();
                                    break;
                                }
                            }
                        }

                    }
                    Thread.sleep(100);
                }
                System.out.println("Shutting down Socket!!");
                clientSocket.close();
            } catch (Exception e1) {
                System.out.println(e1.toString());
            }
        }
    }

    ////////////////////////////////////// MEDIAPROJECTION /////////////////////////////////////////

    private static final int REQUEST_CODE_CAPTURE_PERM = 1234;
    private static final String VIDEO_MIME_TYPE = "video/avc";
    int VIDEO_WIDTH, VIDEO_HEIGHT;

    private boolean mMuxerStarted = false;
    private MediaProjectionManager mMediaProjectionManager;
    private MediaProjection mMediaProjection;
    private Surface mInputSurface;
    private MediaMuxer mMuxer;
    private MediaCodec mVideoEncoder;
    private MediaCodec.BufferInfo mVideoBufferInfo;
    private int mTrackIndex = -1;

    private final Handler mDrainHandler = new Handler(Looper.getMainLooper());
    private Runnable mDrainEncoderRunnable = new Runnable() {
        @Override
        public void run() {
            drainEncoder();
        }
    };

    public void stopRecording(){

        releaseEncoders();
    }

    private void startRecording() {
        DisplayManager dm = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
        Display defaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
        if (defaultDisplay == null) {
            throw new RuntimeException("No display found.");
        }

        DisplayMetrics metrics = getResources().getDisplayMetrics();
        int screenWidth = metrics.widthPixels;
        int screenHeight = metrics.heightPixels;
        int screenDensity = metrics.densityDpi;
        VIDEO_WIDTH = screenWidth;
        VIDEO_HEIGHT = screenHeight;

        prepareVideoEncoder();

        mMediaProjection.createVirtualDisplay("Recording Display", screenWidth, screenHeight, screenDensity, 0, mInputSurface, null, null);

        drainEncoder();
    }

    private void prepareVideoEncoder() {
        mVideoBufferInfo = new MediaCodec.BufferInfo();
        MediaFormat format = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, VIDEO_WIDTH, VIDEO_HEIGHT);
        int frameRate = 30;

        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
        format.setInteger(MediaFormat.KEY_BIT_RATE, 6000000);
        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
        format.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate);
        format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 1000000 / frameRate);
        format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);

        try {
            mVideoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE);
            mVideoEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            mInputSurface = mVideoEncoder.createInputSurface();
            mVideoEncoder.start();
        } catch (IOException e) {
            releaseEncoders();
        }
    }

    private boolean drainEncoder() {
        mDrainHandler.removeCallbacks(mDrainEncoderRunnable);
        while (true) {
            int bufferIndex = mVideoEncoder.dequeueOutputBuffer(mVideoBufferInfo, 0);

            if (bufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
                break;
            } else if (bufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {

            } else if (bufferIndex < 0) {

            } else {
                ByteBuffer encodedData = mVideoEncoder.getOutputBuffer(bufferIndex);
                if (encodedData == null) {
                    throw new RuntimeException("couldn't fetch buffer at index " + bufferIndex);
                }

                if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                    mVideoBufferInfo.size = 0;
                }

                if (mVideoBufferInfo.size != 0) {

                        encodedData.position(mVideoBufferInfo.offset);
                        encodedData.limit(mVideoBufferInfo.offset + mVideoBufferInfo.size);

                    try {
                        OutputStream os = clientSocket.getOutputStream();
                        BufferedOutputStream bos = new BufferedOutputStream (os);
                        ObjectOutputStream oos = new ObjectOutputStream(bos);
                        oos.writeObject(encodedData);

                        oos.flush();
                        bos.flush();
                        os.flush();

                    } catch (IOException e) {
                        throw new RuntimeException("couldn't send data to server");
                    }
                } else {

                    }
                       mVideoEncoder.releaseOutputBuffer(bufferIndex, false);
                }

                if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    break;
                }
            }

        mDrainHandler.postDelayed(mDrainEncoderRunnable, 10);
        return false;
    }

    private void releaseEncoders() {
        mDrainHandler.removeCallbacks(mDrainEncoderRunnable);
        if (mMuxer != null) {
            if (mMuxerStarted) {
                mMuxer.stop();
            }
            mMuxer.release();
            mMuxer = null;
            mMuxerStarted = false;
        }
        if (mVideoEncoder != null) {
            mVideoEncoder.stop();
            mVideoEncoder.release();
            mVideoEncoder = null;
        }
        if (mInputSurface != null) {
            mInputSurface.release();
            mInputSurface = null;
        }
        if (mMediaProjection != null) {
            mMediaProjection.stop();
            mMediaProjection = null;
        }
        mVideoBufferInfo = null;
        mDrainEncoderRunnable = null;
        mTrackIndex = -1;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////

     @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Thread(new ClientThread()).start();
    }

     public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (REQUEST_CODE_CAPTURE_PERM == requestCode) {
            if (resultCode == RESULT_OK) {
                mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, intent);
                startRecording();
            } else {

            }
        }
    }

0 Answers0