在特定设备上使用相机录制视频不会成功

时间:2014-07-15 09:09:20

标签: android android-camera android-mediarecorder

录制会在某些设备上生成有效的mp4文件,但会在我正在使用的设备上生成损坏的mp4文件。这个受损文件的特点是绿色,每个看到它的人都评论说它看起来像编解码器问题。即使在录制过程中,您也可以看到当该帧消失并显示下一帧时,当前帧中的某些对象不会被删除。

public class Record_activity extends ActionBarActivity {
    RecordFragment m_recordFragment=new RecordFragment(this); 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record_activity);


        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
            .add(R.id.container,m_recordFragment ).commit();
        }
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        m_recordFragment.onPause();
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.record_activity, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    /** Check if this device has a camera */
    private boolean checkCameraHardware(Context context) {
        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }
    }
    /**
     * A placeholder fragment containing a simple view.
     */
    public static class RecordFragment extends Fragment {
        public static final int MEDIA_TYPE_IMAGE = 1;
        public static final int MEDIA_TYPE_VIDEO = 2;
        private static Camera mCamera;
        private CameraPreview mPreview;
        Context m_context;
        private MediaRecorder mMediaRecorder;

        private boolean isRecording = false;
        private Button m_captureButton;
        private int ScreenWidth;
        private int ScreenHeight;

        public RecordFragment(Context aContext) {
            m_context=aContext;
        }
        @Override
        public void onPause() {
            // TODO Auto-generated method stub
            super.onPause();

            releaseMediaRecorder();       // if you are using MediaRecorder, release it first
            releaseCamera();              // release the camera immediately on pause event
        }
        /** A safe way to get an instance of the Camera object. */
        public static Camera getCameraInstance(boolean aIsBackCamera){
            if(mCamera==null)
            {
                int numCameras=Camera.getNumberOfCameras();
                try {
                    if(aIsBackCamera)
                        mCamera = Camera.open(0); // attempt to get a Camera instance
                    else mCamera=Camera.open(numCameras-1); // attempt to get a Camera instance
                }
                catch (Exception e){
                    Log.d("record", "open camera exception:"+e.getMessage());
                    // Camera is not available (in use or does not exist)
                }
            }

            return mCamera; // returns null if camera is unavailable
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_record_activity,
                    container, false);

            // Create an instance of Camera
            mCamera = getCameraInstance(true);

            Display display =((Activity)m_context).getWindowManager().getDefaultDisplay(); 
            ScreenWidth = display.getWidth();  // deprecated
            ScreenHeight = display.getHeight();  // deprecated
            Log.d("record", "screenWidth:"+ScreenWidth+"screenHeight:"+ScreenHeight);

            // Create our Preview view and set it as the content of our activity.
            mPreview = new CameraPreview(m_context, mCamera);
            FrameLayout preview = (FrameLayout) rootView.findViewById(R.id.camera_preview);
            preview.addView(mPreview);

            // Add a listener to the Capture button
            m_captureButton = (Button) rootView.findViewById(R.id.button_capture);
            m_captureButton.setOnClickListener(
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (isRecording) {
                                // stop recording and release camera
                                mMediaRecorder.stop();  // stop the recording
                                releaseMediaRecorder(); // release the MediaRecorder object
                                mCamera.lock();         // take camera access back from MediaRecorder

                                // inform the user that recording has stopped
                                setCaptureButtonText("Capture");
                                isRecording = false;
                            } else {
                                // initialize video camera
                                if (prepareVideoRecorder()) {
                                    // Camera is available and unlocked, MediaRecorder is prepared,
                                    // now you can start recording
                                    mMediaRecorder.start();

                                    // inform the user that recording has started
                                    setCaptureButtonText("Stop");
                                    isRecording = true;
                                } else {
                                    // prepare didn't work, release the camera
                                    releaseMediaRecorder();
                                    // inform user
                                }
                            }
                        }

                        private void setCaptureButtonText(String string) {
                            m_captureButton.setText(string);

                        }
                    }
                    );
            return rootView;
        }
        private boolean prepareVideoRecorder(){

            mCamera = getCameraInstance(true);
            mMediaRecorder = new MediaRecorder();

            // Step 1: Unlock and set camera to MediaRecorder
            mCamera.unlock();
            mMediaRecorder.setCamera(mCamera);

            // Step 2: Set sources
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

            // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
            mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

            // Step 4: Set output file
            mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

            // Step 5: Set the preview output
            mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

            // Step 6: Prepare configured MediaRecorder
            try {
                mMediaRecorder.prepare();
            } catch (IllegalStateException e) {
                Log.d("record", "IllegalStateException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                return false;
            } catch (IOException e) {
                Log.d("record", "IOException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                return false;
            }
            return true;
        }
        private void releaseMediaRecorder(){
            if (mMediaRecorder != null) {
                mMediaRecorder.reset();   // clear recorder configuration
                mMediaRecorder.release(); // release the recorder object
                mMediaRecorder = null;
                mCamera.lock();           // lock camera for later use
            }
        }
        private void releaseCamera(){
            if (mCamera != null){
                mCamera.release();        // release the camera for other applications
                mCamera = null;
            }
        }
        /** Create a File for saving an image or video */
        private static File getOutputMediaFile(int type){
            // To be safe, you should check that the SDCard is mounted
            // using Environment.getExternalStorageState() before doing this.

            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_PICTURES), "MyCameraApp");
            // This location works best if you want the created images to be shared
            // between applications and persist after your app has been uninstalled.

            // Create the storage directory if it does not exist
            if (! mediaStorageDir.exists()){
                if (! mediaStorageDir.mkdirs()){
                    Log.d("MyCameraApp", "failed to create directory");
                    return null;
                }
            }

            // Create a media file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            File mediaFile;
            if (type == MEDIA_TYPE_IMAGE){
                mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                        "IMG_"+ timeStamp + ".jpg");
            } else if(type == MEDIA_TYPE_VIDEO) {
                mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                        "VID_"+ timeStamp + ".mp4");
            } else {
                return null;
            }

            return mediaFile;
        }

        public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback 
        {
            private SurfaceHolder mHolder;
            private Camera mCamera;

            public CameraPreview(Context context, Camera camera) {
                super(context);
                mCamera = camera;

                // Install a SurfaceHolder.Callback so we get notified when the
                // underlying surface is created and destroyed.
                mHolder = getHolder();
                mHolder.addCallback(this);
                // deprecated setting, but required on Android versions prior to 3.0
                mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
            @Override
            protected void onSizeChanged(int w, int h, int oldw, int oldh) {
                // TODO Auto-generated method stub
                super.onSizeChanged(w, h, oldw, oldh);
            }
            public void surfaceCreated(SurfaceHolder holder) {
                // The Surface has been created, now tell the camera where to draw the preview.
                try {
                    mCamera = getCameraInstance(true);
                    mCamera.setPreviewDisplay(holder);
                    // mCamera.startPreview();
                } catch (IOException e) {
                    Log.d("record", "Error setting camera preview: " + e.getMessage());
                }
            }

            public void surfaceDestroyed(SurfaceHolder holder) {
                // empty. Take care of releasing the Camera preview in your activity.
            }
            private Camera.Size getBestPreviewSize(int width, int height,
                    Camera.Parameters parameters) {
                Camera.Size result=null;

                for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
                    if (size.width<=width && size.height<=height) {
                        if (result==null) {
                            result=size;
                        }
                        else {
                            int resultArea=result.width*result.height;
                            int newArea=size.width*size.height;

                            if (newArea>resultArea) {
                                result=size;
                            }
                        }
                    }
                }

                return(result);
            }
            public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
                // If your preview can change or rotate, take care of those events here.
                // Make sure to stop the preview before resizing or reformatting it.

                if (mHolder.getSurface() == null){
                    // preview surface does not exist
                    return;
                }

                // stop preview before making changes
                try {
                    //  mCamera.stopPreview();
                } catch (Exception e){
                    // ignore: tried to stop a non-existent preview
                }

                Parameters params=mCamera.getParameters();
                Size size=getBestPreviewSize(w, h,params );
                Log.d("record", "surface width:"+w+"surface height"+h+"previewWidth:"+size.width+"previewHeight:"+size.height);
                params.setPreviewSize(size.width,size.height);
                // start preview with new settings
                try {
                    mCamera.setPreviewDisplay(mHolder);

                    // set preview size and make any resize, rotate or
                    // reformatting changes here



                    mCamera.startPreview();

                } catch (Exception e){
                    Log.d("record", "Error starting camera preview: " + e.getMessage());
                }
            }
        }

    }

    /** A basic Camera preview class */
}

fragment_record_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.recordapp.RecordFragment" >

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        />

    <Button
        android:id="@+id/button_capture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Capture" />

</LinearLayout>

1 个答案:

答案 0 :(得分:0)

O.K,我找到了答案,我使用了http://developer.android.com/samples/MediaRecorder/index.html,它有编解码器支持,问题解决了。