录制视频并同时实时获取帧

时间:2014-06-18 11:50:31

标签: android

我发现了这样的问题。有人说这是可能的,但解决方案对我没有用,有些人说这是不可能的。

我有这个代码用于记录mp4:

    import java.io.IOException;

    import android.app.Activity;
    import android.content.pm.ActivityInfo;
    import android.media.CamcorderProfile;
    import android.media.MediaRecorder;
    import android.os.Bundle;
    import android.os.Environment;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.View.OnClickListener;


    public class MainActivity extends Activity implements OnClickListener, SurfaceHolder.Callback {
        MediaRecorder recorder;
        SurfaceHolder holder;
        boolean recording = false;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);


            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

            recorder = new MediaRecorder();
            initRecorder();
            setContentView(R.layout.activity_main);

            SurfaceView cameraView = (SurfaceView) findViewById(R.id.surfaceView1);
            holder = cameraView.getHolder();
            holder.addCallback(this);
            holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

            cameraView.setClickable(true);
            cameraView.setOnClickListener(this);


        }

        private void initRecorder() {


            recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
            recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);

            CamcorderProfile cpHigh = CamcorderProfile
                    .get(CamcorderProfile.QUALITY_HIGH);
            recorder.setProfile(cpHigh);

            recorder.setOutputFile(Environment.getExternalStorageDirectory().getPath() + "/video.mp4");
            recorder.setMaxDuration(5 * 1000); // 50 seconds
            recorder.setMaxFileSize(5 * 1000000); // Approximately 5 megabytes


        }

        private void prepareRecorder() {
            recorder.setPreviewDisplay(holder.getSurface());

            try {
                recorder.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
                finish();
            } catch (IOException e) {
                e.printStackTrace();
                finish();
            }
        }

        public void onClick(View v) {
            if (recording) {
                recorder.stop();
                recording = false;


                // Let's initRecorder so we can record again
                initRecorder();
                prepareRecorder();
            } else {
                recording = true;
                recorder.start();
            }
        }

        public void surfaceCreated(SurfaceHolder holder) {
            prepareRecorder();
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
        }



        public void surfaceDestroyed(SurfaceHolder holder) {
            if (recording) {
                recorder.stop();
                recording = false;
            }
            recorder.release();
            finish();
        }
    }

另一个用于实时获取帧:

        import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;

    import android.app.Activity;
    import android.content.pm.ActivityInfo;
    import android.graphics.ImageFormat;
    import android.hardware.Camera;
    import android.hardware.Camera.ErrorCallback;
    import android.hardware.Camera.Size;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.SurfaceHolder.Callback;

    public class MainActivity extends Activity {
        SurfaceView mVideoCaptureView;
        Camera mCamera;




        @Override
        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            mVideoCaptureView = (SurfaceView) findViewById(R.id.surfaceView1);
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            SurfaceHolder videoCaptureViewHolder = mVideoCaptureView.getHolder();
            videoCaptureViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            videoCaptureViewHolder.addCallback(new Callback() {
                public void surfaceDestroyed(SurfaceHolder holder) {
                    stopVideo();
                }
                public void surfaceCreated(SurfaceHolder holder) {
                    startVideo();
                }

                public void surfaceChanged(SurfaceHolder holder, int format,
                        int width, int height) {
                }
            });
        }





        private void startVideo() {

            //Open camera
            SurfaceHolder videoCaptureViewHolder = null;
            try {
                mCamera = Camera.open();
            } catch (RuntimeException e) {
                Log.e("CameraTest", "Camera Open failed");
                return;
            }
            mCamera.setErrorCallback(new ErrorCallback() {
                public void onError(int error, Camera camera) {
                }
            }); 

            //Get params
            Camera.Parameters parameters = mCamera.getParameters();


            //Get Frame rate
            int[] minFrameRate = {90000,90000};
            List<int[]> supportedPreviewFps=parameters.getSupportedPreviewFpsRange();
            Iterator<int[]> supportedPreviewFpsIterator=supportedPreviewFps.iterator();
            while(supportedPreviewFpsIterator.hasNext()){
                int[] tmpRate=supportedPreviewFpsIterator.next();   

                if(tmpRate[0]<minFrameRate[0])
                {
                    minFrameRate[0] = tmpRate[0];
                    minFrameRate[1] = tmpRate[1];
                }


            }

            //Set frame rate
            parameters.setPreviewFpsRange(minFrameRate[0],minFrameRate[1]);
            Log.i("Info", "Frame rate set to: " + minFrameRate[0] + ','+ minFrameRate[1]);

            //Get image size
            List<Size> supportedPreviewSizes=parameters.getSupportedPreviewSizes();
            Iterator<Size> supportedPreviewSizesIterator=supportedPreviewSizes.iterator();
            while(supportedPreviewSizesIterator.hasNext()){
                Size tmpSize=supportedPreviewSizesIterator.next();
                Log.v("CameraTest","supportedPreviewSize.width = "+tmpSize.width+"supportedPreviewSize.height = "+tmpSize.height);
            }

            //Set params
            mCamera.setParameters(parameters);
            if ( mVideoCaptureView!=null)
                videoCaptureViewHolder = mVideoCaptureView.getHolder();
            try 
            {
                mCamera.setPreviewDisplay(videoCaptureViewHolder);
            } catch (Throwable t) 
            {
                Log.e("Error","mCamera.setPreviewDisplay(videoCaptureViewHolder) fail");
            }


            //Start camera
            Size previewSize=mCamera.getParameters().getPreviewSize();
            int dataBufferSize=(int)(previewSize.height*previewSize.width*
                                   (ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat())/8.0));
            mCamera.addCallbackBuffer(new byte[dataBufferSize]);
            mCamera.addCallbackBuffer(new byte[dataBufferSize]);
            mCamera.addCallbackBuffer(new byte[dataBufferSize]);




            mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {           

                public synchronized void onPreviewFrame(byte[] data, Camera camera) {


                    try
                    {                   
                        camera.addCallbackBuffer(data);

                    }catch (Exception e) {

                        Log.e("CameraTest", "addCallbackBuffer error");

                    }


                }
            });







            try {
                mCamera.startPreview();
            } catch (Throwable e) {
                mCamera.release();
                mCamera = null;
                return;
            }
        }






        private void stopVideo() {

            Log.i("StopVideo","OK");


            if(null==mCamera)
                return;
            try {
                mCamera.stopPreview();
                mCamera.setPreviewDisplay(null);
                mCamera.setPreviewCallbackWithBuffer(null);
                mCamera.release();
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            mCamera = null;
        }
        public void finish(){
            stopVideo();
            super.finish();
        }





        @Override
        public void onBackPressed() {

            stopVideo();
            super.onBackPressed();
        };







    }

这最后一段代码有一个功能“onPreviewFrame”,可以实时获取帧。

如何将此功能包含在第一段代码中?

我试图使用Camera对象,但如果Camara打开并开始录制mp4失败,因为它不能同时执行这两项操作

0 个答案:

没有答案