2012-03-23 112 views
3

我遇到了相機預覽問題。但首先,這裏是我的應用程序的流程:相機預覽不起作用

1. Show Camera preview for video recording (works fine) 
2. When video recording stops (user presses stop), play the recorded video (works fine) 
3. on Recorded video completion, start camera preview (not working) 

我無法弄清楚,爲什麼它不工作,有在logcat的返回任何錯誤。

任何人有一個想法/建議這個預覽工作?

編輯:當我按下硬件Home鍵然後啓動應用程序回來,相機預覽再次工作。

這裏是我的代碼:

main.xml 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    ...> 

    <VideoView android:id="@+id/videoView1" 
     android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight=".5"/> 


    <RelativeLayout android:id="@+id/surfaceViewWrapper" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight=".5"> 
     <com.sample.video.CameraSurfaceView 
      android:id="@+id/cameraView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#00ff00" 
      /> 
    </RelativeLayout> 
</LinearLayout> 

CameraSurfaceView.java

public class CameraSurfaceView extends ViewGroup implements SurfaceHolder.Callback{ 
    ... 
    private Camera mCamera; 
    private MediaRecorder mMediaRecorder; 
    private int frontCameraId; 

    public CameraSurfaceView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public CameraSurfaceView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     mSurfaceView = new SurfaceView(context); 
     addView(mSurfaceView); 

     mHolder = mSurfaceView.getHolder(); 
     mHolder.addCallback(this); 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     frontCameraId = 0; 
    } 

    //---Recording--- 
    public void startRecording(){ 
     mMediaRecorder.start(); 
    } 

    public boolean prepareVideoRecorder() throws IOException{ 
     //Some code here from google, I didn't include in this post to make this not too long 
     ... 
    } 

    public void stopRecording() { 
     mMediaRecorder.stop(); 
    } 

    public 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 
     } 
    } 

    //###---Camera--- 
    public void releaseCamera(){ 
     //Some code here from google, I didn't include in this post to make this not too long 
     ... 
    } 
    public void useFrontCamera(){ 
     int numberOfCameras = Camera.getNumberOfCameras(); 

     CameraInfo cameraInfo = new CameraInfo(); 
     for (int i = 0; i < numberOfCameras; i++) { 
      Camera.getCameraInfo(i, cameraInfo); 
      if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) { 
       frontCameraId = i; 
      } 
     } 

     mCamera = Camera.open(frontCameraId); 
     if (mCamera != null) { 
      mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
      requestLayout(); 
     } 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     // The Surface has been created, acquire the camera and tell it where 
     // to draw. 
     try { 
      if (mCamera != null) { 
       mCamera.setPreviewDisplay(holder); 
      } 
     } catch (IOException exception) { 
      Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     // Surface will be destroyed when we return, so stop the preview. 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
     } 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     // Now that the size is known, set up the camera parameters and begin 
     // the preview. 
     if (mCamera != null) { 
      Camera.Parameters parameters = mCamera.getParameters(); 
      parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
      requestLayout(); 

      mCamera.setParameters(parameters); 
      mCamera.startPreview(); 
     } 

    } 

    public void startPreview(){ 
     mCamera.startPreview(); 
    } 

    public void setCamera(Camera camera){ 
     this.mCamera = camera; 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     //Some code here from google, I didn't include in this post to make this not too long 
     ... 
    } 

    @Override 
    protected void onLayout(boolean changed, int l, int t, int r, int b) { 
     //Some code here from google, I didn't include in this post to make this not too long 
     ... 
    } 

    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { 
     //Some code here from google, I didn't include in this post to make this not too long 
     ... 
    } 
    } 
    CameraPreview code: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html 

MainActivity.java

public class MainActivity extends Activity{ 
    CameraSurfaceView cameraSurfaceView; 
    private boolean isRecording = false; 
    private VideoView mVideoView; 
    MediaPlayer mpPlayer; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     cameraSurfaceView = (CameraSurfaceView)findViewById(R.id.cameraView); 
     mVideoView = (VideoView)findViewById(R.id.videoView1); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     cameraSurfaceView.useFrontCamera(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     cameraSurfaceView.releaseMediaRecorder(); 
     cameraSurfaceView.releaseCamera(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu){ 
     menu.add(0, 0, 0, "Start Recording"); 
     menu.add(0, 1, 0, "Stop Recording"); 
     menu.add(0, 2, 0, "Play Recording"); 
     return super.onCreateOptionsMenu(menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item){ 
     switch (item.getItemId()) 
     { 
      case 0: 
       if(isRecording){ 
        // stop recording and release camera 
        cameraSurfaceView.stopRecording(); // stop the recording 
        cameraSurfaceView.releaseMediaRecorder(); // release the MediaRecorder object 

        isRecording = false; 
       }else{ 
        try { 
         // initialize video camera 
         if (cameraSurfaceView.prepareVideoRecorder()) { 


          // Camera is available and unlocked, MediaRecorder is prepared, 
          // now you can start recording 
          cameraSurfaceView.startRecording(); 

          // inform the user that recording has started 
          isRecording = true; 
          Toast.makeText(getBaseContext(), "Recording Start.", Toast.LENGTH_SHORT).show(); 
         } else { 
          // prepare didn't work, release the camera 
          cameraSurfaceView.releaseMediaRecorder(); 
         } 
        }catch (Exception e) { 
         String message = e.getMessage(); 
         Log.i(null, "Problem Start"+message); 
         cameraSurfaceView.releaseMediaRecorder(); 
        } 
       } 

       break; 
      case 1: 
       if(isRecording){ 
        // stop recording and release camera 
        cameraSurfaceView.stopRecording(); // stop the recording 
        cameraSurfaceView.releaseMediaRecorder(); // release the MediaRecorder object 

        // inform the user that recording has stopped 
        isRecording = false; 
       } 
       break; 
      case 2: 
       //play video 
       cameraSurfaceView.releaseMediaRecorder(); 
       cameraSurfaceView.releaseCamera(); 

       if (mVideoView.getVisibility() == View.INVISIBLE) { 
        mVideoView.setVisibility(View.VISIBLE); 
       } 


       if(cameraSurfaceView.getVisibility() == View.VISIBLE) 
        cameraSurfaceView.setVisibility(View.INVISIBLE); 


       try { 
        mpPlayer = new MediaPlayer(); 
        mpPlayer.setDisplay(mVideoView.getHolder()); 
        mpPlayer.setDataSource(MainActivity2.this, Uri.parse(Environment.getExternalStorageDirectory() + "/Sample Video Recording/sample.mp4")); 
        mpPlayer.setOnCompletionListener(onVideoComplete); 
        mpPlayer.setOnErrorListener(onErrorMediaPlayer); 
        mpPlayer.prepare(); 
        mpPlayer.start(); 
       } catch (IllegalArgumentException e) {e.printStackTrace(); 
       } catch (SecurityException e) {e.printStackTrace(); 
       } catch (IllegalStateException e) {e.printStackTrace(); 
       } catch (IOException e) {e.printStackTrace(); 
       } 
       break; 
      default: 
       break; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    public MediaPlayer.OnErrorListener onErrorMediaPlayer = new MediaPlayer.OnErrorListener(){ 
     @Override 
     public boolean onError(MediaPlayer mp, int what, int extra) { 
      mp.reset(); 
      return false; 
     } 

    }; 
    public MediaPlayer.OnPreparedListener onNarrPreparedListener = new MediaPlayer.OnPreparedListener(){ 
     @Override 
     public void onPrepared(MediaPlayer mp) { 

     } 
    }; 

    private MediaPlayer.OnCompletionListener onVideoComplete = new MediaPlayer.OnCompletionListener() { 
     @Override 
     public void onCompletion(MediaPlayer mp) { 
      mpPlayer.stop(); 
      mpPlayer.release(); 

      if (mVideoView.getVisibility() == View.VISIBLE) { 
       mVideoView.setVisibility(View.INVISIBLE); 
      } 

      if(cameraSurfaceView != null){ 
      cameraSurfaceView.releaseMediaRecorder(); 
      cameraSurfaceView.releaseCamera(); 
      } 

      if(cameraSurfaceView.getVisibility() == View.INVISIBLE) 
       cameraSurfaceView.setVisibility(View.VISIBLE); 

      cameraSurfaceView.useFrontCamera(); 
      cameraSurfaceView.startPreview(); 
     } 
    }; 
} 

清單:

... 
    <uses-permission android:name="android.permission.CAMERA"/> 
    <uses-permission android:name="android.permission.RECORD_AUDIO"/> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

    <uses-feature android:name="android.hardware.camera" android:required="false"/> 
... 

提前感謝你們。

+0

能否請您發送清單文件? – CsaByte 2012-03-23 06:25:58

+0

@CsaByte我張貼清單。 – jayellos 2012-03-23 06:38:15

回答

3

您必須在創建MediaRecorder之前解鎖相機。 並在釋放它之前鎖定它。

試試這個代碼,它會工作 玩得開心......

if(mCamera == null) 

{ 
mCamera = Camera.open(); 
mCamera.unlock(); 
} 


if(mMediaRecorder == null) 
    mMediaRecorder = new MediaRecorder(); 


mMediaRecorder.setPreviewDisplay(surface); 
mMediaRecorder.setCamera(mCamera); 
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
+0

我的錄音機工作正常。 – jayellos 2012-03-23 06:33:23