Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to switch between front and back camera when using MediaRecorder android

if anyone has any idea that how to switch between front and back camera when using MediaRecorder . I defing a button for this function, but have no idea how to define the onclickListener.

the total activity is the following:

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Test_cameraActivity extends Activity implements Callback {

    // Camera variables to fiddle with video preview.
    // private Camera cam;
    // Viewholders etc
    private SurfaceHolder recordViewHolder;
    private SurfaceView recordSurface;
    private int width, height;
    // Button
    private Button recordBut;
    private Button switchBut;
    private Button libraryBut;

    private final static String DIRECTORY = "/hdrecorder"; // Directory where
                                                            // the film is
                                                            // stored
    private final static String recordFileName = "/hdtestfile.mp4"; 
    private final static String saveFileName = "/hdsavefile.mp4"; 
    private MyMediaRecorder recorder = null;
    private final static String LOG_TAG = "HD Recorder";
    private String filePath;

    // Activity overrides
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // *******************************************
        // fullscreen mode
        // *******************************************
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // *******************************************

        setContentView(R.layout.main);

        File dir = new File(Environment.getExternalStorageDirectory()
                + DIRECTORY);
        if (!dir.exists()) {
            if (dir.mkdir()) {
                Log.v(LOG_TAG, "Created directory");
            } else {
                Log.v(LOG_TAG, "Failed to create Directory");
            }
        }

        File videoFile = new File(Environment.getExternalStorageDirectory()
                + DIRECTORY + recordFileName);

        if (!videoFile.exists()) {
            videoFile.delete(); // Reset recording
        }

        filePath = videoFile.getAbsolutePath();
        Log.v(LOG_TAG, "PATH:" + filePath);
        Log.v(LOG_TAG, "PATH:" + filePath);

        recordSurface = (SurfaceView) findViewById(R.id.videoSurface);
        recordBut = (Button) findViewById(R.id.RecordBut);
        recordBut.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (recorder.getState() != MyMediaRecorder.RECORDING) {
                    startRecord();
                } else {
                    stopRecord();
                    recorder.release();
                    moveRecordFileToSave();
                    if (recorder == null) {
                        Log.v(LOG_TAG, "Recorder is null");
                    }
                    Log.v(LOG_TAG, "Value of recorder:" + recorder);
                    createRecorder();
                    initiateRecorder(recordViewHolder, width, height);
                }
            }
        });

        switchBut = (Button) findViewById(R.id.SwitchBut);
        switchBut.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {


            }
        });

        libraryBut = (Button) findViewById(R.id.LibraryBut);
        libraryBut.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Test_cameraActivity.this,
                        FileExplorer.class);
                Test_cameraActivity.this.startActivity(intent);
            }
        });

        recordViewHolder = recordSurface.getHolder();
        recordViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        recordViewHolder.addCallback(this);
        // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        createRecorder();

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.v(LOG_TAG, "OnStart");
        if (recorder != null) {
            if (recorder.getState() == MyMediaRecorder.RELEASED) {
                createRecorder();
            }
        }
        Log.v(LOG_TAG, "SurfaceView create initiated. OnStart Done");

    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.v(LOG_TAG, "onStop received");
        forceStopRecorder();
    }

    // General Helpers.
    private void createRecorder() {
        recorder = new MyMediaRecorder();
    }

    private void startRecord() {
        if (recorder.getState() != MyMediaRecorder.PREPARED) {
            Log.e(LOG_TAG, "Not recordable yet");
            return;
        }
        recorder.start();
        Log.v(LOG_TAG, "Recording started");
        recordBut.setText("Stop Record");
    }

    private void stopRecord() {
        Log.v(LOG_TAG, "Stop of recorder");
        if (recorder.getState() == MyMediaRecorder.RECORDING) {
            recorder.stop();
        }
        recorder.reset();
        recordBut.setText("Record");
    }

    private void initiateRecorder(SurfaceHolder holder, int width, int height) {
        Log.v(LOG_TAG, "H: " + height + " W:" + width);
        if (recorder.getState() != MyMediaRecorder.INITIAL) {
            Log.v(LOG_TAG, "Dude - not existing MediaRecorder - quitting");
            return;
        }
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setOutputFile(this.filePath);
        recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        recorder.setVideoSize(width, height);
        recorder.setVideoFrameRate(24);
        recorder.setPreviewDisplay(holder.getSurface());

        Log.d(LOG_TAG, "Preview restarted");
        try {
            recorder.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // isPrepared = true;
    }

    private void forceStopRecorder() {
        Log.v(LOG_TAG, "Force release of recorder");
        if (recorder.getState() != MyMediaRecorder.RELEASED) {
            stopRecord();
            recorder.release();
        }
    }

    private void moveRecordFileToSave() {
        File source = new File(filePath);
        File dest = new File(Environment.getExternalStorageDirectory()
                + DIRECTORY + saveFileName);
        if (dest.exists()) {
            Log.v(LOG_TAG, "Delete old save file");
            dest.delete();
        }
        source.renameTo(dest);
    }

    // ***** Implementing Callback ********/
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        recordViewHolder = holder;
        this.width = width;
        this.height = height;
        if (recorder.getState() == MyMediaRecorder.RECORDING) {
            stopRecord();
        }

        if (recorder.getState() == MyMediaRecorder.PREPARED) {
            recorder.reset();
        }
        initiateRecorder(holder, width, height);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        Log.v(LOG_TAG, "Surface is created: Path to use" + filePath);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        Log.v(LOG_TAG, "Surface is Destroyed");
        forceStopRecorder();
    }

}
like image 534
catherine8473 Avatar asked Sep 19 '11 12:09

catherine8473


1 Answers

I have something that might also help, in order to jump to the other camera, follow this method:

public void flipit() {
    //myCamera is the Camera object
    if (Camera.getNumberOfCameras()>=2) {
        myCamera.stopPreview();
        myCamera.release();
        //"which" is just an integer flag
        switch (which) {
        case 0:
            myCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
            which = 1;
            break;
        case 1:
            myCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            which = 0;
            break;
        }
        try {
            myCamera.setPreviewDisplay(mHolder);
            //"this" is a SurfaceView which implements SurfaceHolder.Callback,
            //as found in the code examples
            myCamera.setPreviewCallback(this);
            myCamera.startPreview();
        } catch (IOException exception) {
            myCamera.release();
            myCamera = null;
        }
    }
}

Now... for the magic trick, don't call this method from the main thread. Instead this method has to be kicked off from a separate thread, my code does this:

        //btn is a Button that the user clicks on
    btn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            //onClick is invoked from main thread
            //kick-off a different Thread to handle this call
            Thread t = new Thread() {
                public void run() {
                    //myViewer is the SurfaceView object which uses
                    //the camera
                    myViewer.flipit();
                }
            };
            t.start();
        }
    });

I've tested this on Android 4.1.1 so I think it might work for you. (or until Google decides to break the way the camera opening/closing/releasing/unlocking/reconnecting/surfaceholder/onPause/onResume/etc..? works)

like image 159
giannileuani Avatar answered Sep 30 '22 20:09

giannileuani