2015-12-09 42 views
0

试图在没有默认的android相机的情况下录制视频。我发现了一些示例代码来修复我的解决方案。现在在该相机预览方向framelayout很少weired。当我用肖像开始记录时,预览是横向的,反之亦然。使用framelayout和surfaceview拍摄的摄像机

我试着为surfaceview和framelayout设置旋转角度。然后我尝试着设置方向,没有为我工作。

我的应用程序是保存前置摄像头的录制视频并保存它的SD卡。除定位问题外,所有工作都很好。

我的代码低于,

 Layout: 

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
> 
<RelativeLayout 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
    <FrameLayout 
     android:id="@+id/videoview" 
     android:layout_width="200dp" 
     android:layout_height="200dp"/> 
    <Button 
     android:id="@+id/mybutton" 
     android:layout_width="100dp" 
     android:layout_height="50dp" 
     android:layout_centerHorizontal="true" 
     android:layout_alignParentBottom="true" 
     android:text="REC" 
     android:textSize="12dp"/> 
</RelativeLayout> 

Java File: 

    public class RecordVideo extends Activity{ 

private Camera myCamera; 
private MyCameraSurfaceView myCameraSurfaceView; 
private MediaRecorder mediaRecorder; 

Button myButton; 
SurfaceHolder surfaceHolder; 
boolean recording; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR | ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
    recording = false; 

    setContentView(R.layout.main); 

    //Get Camera for preview 
    myCamera = getCameraInstance(); 
    if(myCamera == null){ 
     Toast.makeText(RecordVideo.this, 
       "Fail to get Camera", 
       Toast.LENGTH_LONG).show(); 
    } 

    myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera); 
    //myCameraSurfaceView.setO 
    FrameLayout myCameraPreview = (FrameLayout)findViewById(R.id.videoview); 
    myCameraPreview.addView(myCameraSurfaceView); 

    myButton = (Button)findViewById(R.id.mybutton); 
    myButton.setOnClickListener(myButtonOnClickListener); 
} 

Button.OnClickListener myButtonOnClickListener 
= new Button.OnClickListener(){ 

    @Override 
    public void onClick(View v) { 
     // TODO Auto-generated method stub 
     if(recording){ 
      // stop recording and release camera 
      mediaRecorder.stop(); // stop the recording 
      releaseMediaRecorder(); // release the MediaRecorder object 

      //Exit after saved 
      finish(); 
     }else{ 

      //Release Camera before MediaRecorder start 
      releaseCamera(); 

      if(!prepareMediaRecorder()){ 
       Toast.makeText(RecordVideo.this, 
         "Fail in prepareMediaRecorder()!\n - Ended -", 
         Toast.LENGTH_LONG).show(); 
       finish(); 
      } 

      mediaRecorder.start(); 
      recording = true; 
      myButton.setText("STOP"); 
     } 
    }}; 

private Camera getCameraInstance(){ 
    // TODO Auto-generated method stub 
    Camera c = null; 
    try { 
     c = Camera.open(); // attempt to get a Camera instance 
    } 
    catch (Exception e){ 
     // Camera is not available (in use or does not exist) 
    } 
    return c; // returns null if camera is unavailable 
} 

private boolean prepareMediaRecorder(){ 
    myCamera = getCameraInstance(); 
    mediaRecorder = new MediaRecorder(); 

    myCamera.unlock(); 
    mediaRecorder.setCamera(myCamera); 

    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 

    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); 

    mediaRecorder.setOutputFile("/sdcard/myvideo.mp4"); 
    mediaRecorder.setMaxDuration(60000); // Set max duration 60 sec. 
    mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M 

    mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder().getSurface()); 

    try { 
     mediaRecorder.prepare(); 
    } catch (IllegalStateException e) { 
     releaseMediaRecorder(); 
     return false; 
    } catch (IOException e) { 
     releaseMediaRecorder(); 
     return false; 
    } 
    return true; 

} 

@Override 
protected void onPause() { 
    super.onPause(); 
    releaseMediaRecorder();  // if you are using MediaRecorder, release it first 
    releaseCamera();    // release the camera immediately on pause event 
} 

private void releaseMediaRecorder(){ 
    if (mediaRecorder != null) { 
     mediaRecorder.reset(); // clear recorder configuration 
     mediaRecorder.release(); // release the recorder object 
     mediaRecorder = null; 
     myCamera.lock();   // lock camera for later use 
    } 
} 

private void releaseCamera(){ 
    if (myCamera != null){ 
     myCamera.release();  // release the camera for other applications 
     myCamera = null; 
    } 
} 

public class MyCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{ 

    private SurfaceHolder mHolder; 
    private Camera mCamera; 

    public MyCameraSurfaceView(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 
    public void surfaceChanged(SurfaceHolder holder, int format, int weight, 
      int height) { 
     // 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 
     } 

     // make any resize, rotate or reformatting changes here 

     // start preview with new settings 
     try { 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 

     } catch (Exception e){ 
     } 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 
     // The Surface has been created, now tell the camera where to draw the preview. 
     try { 
      mCamera.setPreviewDisplay(holder); 
      mCamera.startPreview(); 
     } catch (IOException e) { 
     } 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 

    } 
} 
} 
+0

我发现另外一个教程,以实现我的应用程序的目标。但它只能在横向模式下工作,如果我旋转它的行为类似于上面所述的旧模式。链接是,[请看这里](http://examples.javacodegeeks.com/android/core/android-video-capture-example/) –

回答

1

这应该可以解决您的问题:

private static void setCameraDisplayOrientation(Context mContext, android.hardware.Camera.CameraInfo info) { 
    int rotation = ((MainActivity) mContext).getWindowManager().getDefaultDisplay() 
      .getRotation(); 
    int degrees = 0; 
    switch (rotation) { 
     case Surface.ROTATION_0: 
      degrees = 0; 
      break; 
     case Surface.ROTATION_90: 
      degrees = 90; 
      break; 
     case Surface.ROTATION_180: 
      degrees = 180; 
      break; 
     case Surface.ROTATION_270: 
      degrees = 270; 
      break; 
    } 

    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
     previewRotation = (info.orientation + degrees) % 360; 
     previewRotation = (360 - previewRotation) % 360; // compensate the mirror 
    } else { // back-facing 
     previewRotation = (info.orientation - degrees + 360) % 360; 
    } 
    mCameraInstance.setDisplayOrientation(previewRotation); 
} 
+0

对不起,延迟回复。我应该在哪里设置。我不理解,如果你可以请解释我如何在我的代码中实现这一点。 –

相关问题