5

I'm trying to develop a circular video recorder and I need to save the recorded video in a buffer to recovery the last X minutes in a certain moment. The problem is that when I run 'start()' method of MediaRecorder object:

mMediaRecorder.start();

The following error shows up:

java.lang.IllegalStateException android.media.MediaRecorder.start(Native Method) at picture.wikinova.com.odc.CameraActivity$MediaPrepareTask.doInBackground(CameraActivity.java:298) at picture.wikinova.com.odc.CameraActivity$MediaPrepareTask.doInBackground(CameraActivity.java:289) at android.os.AsyncTask$2.call(AsyncTask.java:333) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:764)

The error does not happen when I'm using 'File' as outputFile of MediaRecorder, but it happens when I'm trying to use LocalSocket to recovery the video buffer in memory.

This is my code to create the LocalServerSocket and capture the video

         mLocalServerSocket = new LocalServerSocket("sockt_ip");
            } catch (Exception e) {
                e.printStackTrace();
            }
            LocalSocket mLocalClientSocket = null;
            mLocalClientSocket = mLocalServerSocket.accept();
            InputStream in = mLocalClientSocket.getInputStream();
            byte[] buffer = new byte[1024];
            String retorno = "";
            int len = 0;
            while ((len = in.read(buffer)) >= 0) {
                for (int i = 0; i < len; i++) {
                  retorno += buffer[i];
                }

             }

This is my code to create the MediaRecorder and set the output file

CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
        profile.videoFrameWidth = optimalSize.width;
        profile.videoFrameHeight = optimalSize.height;

        parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
        mCamera.setParameters(parameters);
        try {
            mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
        } catch (IOException e) {
            Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
            return false;
        }


        mMediaRecorder = new MediaRecorder();

        mCamera.unlock();
        mMediaRecorder.setCamera(mCamera);


        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);



        mMediaRecorder.setProfile(profile);

        LocalSocket outSocket = new LocalSocket();
        try {
            outSocket.connect(new LocalSocketAddress("sockt_ip"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        mMediaRecorder.setOutputFile(outSocket.getFileDescriptor());


        mMediaRecorder.prepare();
        mMediaRecorder.start();

I already tested the socket connection. I wrote some text in

LocalSocket outSocket 

and received it in

InputStream in = mLocalClientSocket.getInputStream();
byte[] buffer = new byte[1024];

The problem is the part that I set The socket FileDescriptor as outputFile to the mediaRecorder, but I cannot figure t out what can be.

Rafael
  • 155
  • 1
  • 3
  • 15

2 Answers2

0

Try creating your LocalSocket with new LocalSocket(LocalSocket.SOCKET_STREAM) rather than new LocalSocket().

If you don't set your socket type as shown above, LocalSocketImpl, which is the actual system socket encapsulated by LocalSocket, complains precisely with a IllegalStateException, the only one within that class:

public void create (int sockType) throws IOException {
    // no error if socket already created
    // need this for LocalServerSocket.accept()
    if (fd == null) {
        int osType;
        switch (sockType) {
            case LocalSocket.SOCKET_DGRAM:
                osType = OsConstants.SOCK_DGRAM;
                break;
            case LocalSocket.SOCKET_STREAM:
                osType = OsConstants.SOCK_STREAM;
                break;
            case LocalSocket.SOCKET_SEQPACKET:
                osType = OsConstants.SOCK_SEQPACKET;
                break;
            default:
                throw new IllegalStateException("unknown sockType");
        }
        try {
            fd = Os.socket(OsConstants.AF_UNIX, osType, 0);
            mFdCreatedInternally = true;
        } catch (ErrnoException e) {
            e.rethrowAsIOException();
        }
    }
}

The reason why it should be SOCKET_STREAM, is because the internal LocalSocketImpl inside LocalServerSocket uses that type as well.

0

Use below code

    CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
            profile.videoFrameWidth = optimalSize.width;
            profile.videoFrameHeight = optimalSize.height;

            parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
            mCamera.setParameters(parameters);
            try {
                mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
            } catch (IOException e) {
                Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
                return false;
            }


            mMediaRecorder = new MediaRecorder();

            mCamera.unlock();
            mMediaRecorder.setCamera(mCamera);


            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);



            mMediaRecorder.setProfile(profile);

            LocalSocket outSocket = new LocalSocket(LocalSocket.SOCKET_STREAM);
            try {
                outSocket.connect(new LocalSocketAddress("sockt_ip"));
            } catch (Exception e) {
                e.printStackTrace();
            }
            mMediaRecorder.setOutputFile(outSocket.getFileDescriptor());


            mMediaRecorder.prepare();
            mMediaRecorder.start();
Akash
  • 587
  • 5
  • 12