Android Open Source - VideoRecorder Recorder Activity






From Project

Back to project page VideoRecorder.

License

The source code is released under:

Apache License

If you think the Android project VideoRecorder listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2013?12?31? The Android Open Source Project
 *//from w  ww. j a v  a 2s.  c  o  m
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Auther?yinglovezhuzhu@gmail.com
 * FileName:RecorderActivity.java
 * Date?2013?12?31?
 * Version?v1.0
 */  
package com.opensource.videorecorder;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;

import com.opensource.videorecorder.utils.DateUtil;
import com.opensource.videorecorder.utils.LogUtil;
import com.opensource.videorecorder.utils.StringUtil;

/**
 * ???
 * 
 * @author yinglovezhuzhu@gmail.com
 */
public class RecorderActivity extends BaseActivity implements SurfaceHolder.Callback {
  
  private static final String TAG = RecorderActivity.class.getSimpleName();
  
  private SurfaceView mSurfaceView;
  private ImageButton mIbtnCancel;
  private ImageButton mIbtnOk;
  private Button mButton;
  private TextView mTvTimeCount;
  
  private SurfaceHolder mSurfaceHolder;
  private MediaRecorder mMediaRecorder;
  private Camera mCamera;
  
  private File mOutputFile;
  
  private boolean mIsRecording = false;
  

  private Resources mResources;
  private String mPackageName;
  
  private List<Size> mSupportVideoSizes;
  
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    mResources = getResources();
    mPackageName = getPackageName();
    
    
    int layoutId = mResources.getIdentifier("yuninfo_activity_video_recorder", "layout", mPackageName);
    setContentView(layoutId);
    
    initView();
  }
  
  @SuppressWarnings("deprecation")
  private void initView() {
    
    mSurfaceView = (SurfaceView) findViewById(mResources.getIdentifier("yuninfo_sv_recorder_preview", "id", mPackageName));
    mButton = (Button) findViewById(mResources.getIdentifier("yuninfo_btn_video_record", "id", mPackageName));
    mIbtnCancel = (ImageButton) findViewById(mResources.getIdentifier("yuninfo_ibtn_video_cancel", "id", mPackageName));
    mIbtnOk = (ImageButton) findViewById(mResources.getIdentifier("yuninfo_ibtn_video_ok", "id", mPackageName));
    mIbtnCancel.setOnClickListener(mCancelListener);
    mIbtnOk.setOnClickListener(mOkListener);
    mIbtnCancel.setVisibility(View.INVISIBLE);
    mIbtnOk.setVisibility(View.INVISIBLE);
    mTvTimeCount = (TextView) findViewById(mResources.getIdentifier("yuninfo_tv_recorder_time_count", "id", mPackageName));
    mTvTimeCount.setVisibility(View.INVISIBLE);
    
    mButton.setBackgroundResource(mResources.getIdentifier("yuninfo_btn_video_start", "drawable", mPackageName));
    mButton.setOnClickListener(mBtnListener);
    
    mSurfaceHolder = mSurfaceView.getHolder();
    mSurfaceHolder.addCallback(this);
    
    if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
      try {
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
      } catch (Exception e) {
        LogUtil.e(TAG, e);
      }
    }
    
  }
  
  
  private void exit(final int resultCode, final Intent data) {
    if(mIsRecording) {
      new AlertDialog.Builder(RecorderActivity.this)
      .setTitle("????")
      .setMessage("??????????????")
      .setPositiveButton("??", new DialogInterface.OnClickListener() {
        
        @Override
        public void onClick(DialogInterface dialog, int which) {
          stopRecord();
          if(resultCode == RESULT_CANCELED) {
            deleteFile(mOutputFile);
          }
          setResult(resultCode, data);
          finish();
        }
      })
      .setNegativeButton("????", new DialogInterface.OnClickListener() {
        
        @Override
        public void onClick(DialogInterface dialog, int which) {
          // TODO Auto-generated method stub
          
        }
      }).show();
      return;
    }
    if(resultCode == RESULT_CANCELED) {
      deleteFile(mOutputFile);
    }
    setResult(resultCode, data);
    finish();
  }
  
  private void deleteFile(File delFile) {
    if(delFile == null) {
      return;
    }
    final File file = new File(delFile.getAbsolutePath());
    delFile = null;
    new Thread() {
      @Override
      public void run() {
        super.run();
        if(file.exists()) {
          file.delete();
        }
      }
    }.start();
  }
  
  @SuppressLint("HandlerLeak")
  private Handler mHandler = new Handler() {
    
    @Override
    public void handleMessage(android.os.Message msg) {
      switch (msg.what) {
      case Config.YUNINFO_ID_TIME_COUNT:
        if(mIsRecording) {
          if(msg.arg1 > msg.arg2) {
//          mTvTimeCount.setVisibility(View.INVISIBLE);
            mTvTimeCount.setText("00:00");
            stopRecord();
          } else {
            mTvTimeCount.setText("00:0" + (msg.arg2 - msg.arg1));
            Message msg2 = mHandler.obtainMessage(Config.YUNINFO_ID_TIME_COUNT, msg.arg1 + 1, msg.arg2);
            mHandler.sendMessageDelayed(msg2, 1000);
          }
        }
        break;

      default:
        break;
      }
    };
    
  };
  
  private View.OnClickListener mBtnListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      // TODO Auto-generated method stub
      if(mIsRecording) {
        stopRecord();
      } else {
        startRecord();
      }
    }
  };
  
  private View.OnClickListener mCancelListener = new View.OnClickListener() {
    
    @Override
    public void onClick(View v) {
      exit(RESULT_CANCELED, null);
    }
  };
  
  private View.OnClickListener mOkListener = new View.OnClickListener() {
    
    @Override
    public void onClick(View v) {
      Intent data = new Intent();
      if(mOutputFile != null && !StringUtil.isEmpty(mOutputFile.getAbsolutePath())) {
        data.putExtra(Config.YUNINFO_RESULT_DATA, mOutputFile);
      }
      exit(RESULT_OK, data);
    }
  };
  
  @SuppressLint("NewApi")
  private void openCamera() {
    //Open camera
    try {
      this.mCamera = Camera.open();
      Camera.Parameters parameters = mCamera.getParameters();
      parameters.setRotation(90);
      System.out.println(parameters.flatten());
      parameters.set("orientation", "portrait");
//      parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
      mCamera.setParameters(parameters);
      mCamera.lock();
      if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
        try {
          mCamera.setDisplayOrientation(90);
        } catch (NoSuchMethodError e) {
          e.printStackTrace();
        }
      }
      mSupportVideoSizes = parameters.getSupportedVideoSizes();
      if(mSupportVideoSizes == null || mSupportVideoSizes.isEmpty()) {  //For some device can't get supported video size
        String videoSize = parameters.get("video-size");
        LogUtil.i(TAG, videoSize);
        mSupportVideoSizes = new ArrayList<Camera.Size>();
        if(!StringUtil.isEmpty(videoSize)) {
          String [] size = videoSize.split("x");
          if(size.length > 1) {
            try {
              int width = Integer.parseInt(size[0]);
              int height = Integer.parseInt(size[1]);
              mSupportVideoSizes.add(mCamera.new Size(width, height));
            } catch (Exception e) {
              LogUtil.e(TAG, e.toString());
            }
          }
        }
      }
      for (Size size : mSupportVideoSizes) {
        LogUtil.i(TAG, size.width + "<>" + size.height);
      }
    } catch (Exception e) {
      LogUtil.e(TAG, "Open Camera error\n" + e.toString());
    }
  }
  
  @SuppressLint("NewApi")
  private boolean initVideoRecorder() {

    mCamera.unlock();
    mMediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    LogUtil.i("Camera", mCamera);
    LogUtil.i("Camera", mMediaRecorder);
    mMediaRecorder.setCamera(mCamera);
    
    // Step 2: Set sources
    try {
      mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
      mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
    } catch (Exception e) {
      mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
      mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
      e.printStackTrace();
    }

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
      try {
        CamcorderProfile lowProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
        CamcorderProfile hightProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
        if(lowProfile != null && hightProfile != null) {
          int audioBitRate = lowProfile.audioBitRate > 128000 ? 128000 : lowProfile.audioBitRate;
          lowProfile.audioBitRate = audioBitRate > hightProfile.audioBitRate ? hightProfile.audioBitRate : audioBitRate;
          lowProfile.audioSampleRate = 48000 > hightProfile.audioSampleRate ? hightProfile.audioSampleRate : 48000;
//          lowProfile.duration = 20 > hightProfile.duration ? hightProfile.duration : 20;
//          lowProfile.videoFrameRate = 20 > hightProfile.videoFrameRate ? hightProfile.videoFrameRate : 20;
          lowProfile.duration = hightProfile.duration;
          lowProfile.videoFrameRate = hightProfile.videoFrameRate;
          lowProfile.videoBitRate = 1500000 > hightProfile.videoBitRate ? hightProfile.videoBitRate : 1500000;;
          if(mSupportVideoSizes != null && !mSupportVideoSizes.isEmpty()) {
            int width = 640;
            int height = 480;
            Collections.sort(mSupportVideoSizes, new SizeComparator());
            int lwd = mSupportVideoSizes.get(0).width;
            for (Size size : mSupportVideoSizes) {
              int wd = Math.abs(size.width - 640);
              if(wd < lwd) {
                width = size.width;
                height = size.height;
                lwd = wd;
              } else {
                break;
              }
            }
            lowProfile.videoFrameWidth = width;
            lowProfile.videoFrameHeight = height;
          }
          System.out.println(lowProfile.audioBitRate);
          System.out.println(lowProfile.audioChannels);
          System.out.println(lowProfile.audioCodec);
          System.out.println(lowProfile.audioSampleRate);
          System.out.println(lowProfile.duration);
          System.out.println(lowProfile.fileFormat);
          System.out.println(lowProfile.quality);
          System.out.println(lowProfile.videoBitRate);
          System.out.println(lowProfile.videoCodec);
          System.out.println(lowProfile.videoFrameHeight);
          System.out.println(lowProfile.videoFrameWidth);
          System.out.println(lowProfile.videoFrameRate);

          mMediaRecorder.setProfile(lowProfile);
        }
      } catch (Exception e) {
        try {
          mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        } catch (Exception ex) {
          e.printStackTrace();
        }
        try {
          mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
        } catch (Exception ex) {
          e.printStackTrace();
        }
        if(mSupportVideoSizes != null && !mSupportVideoSizes.isEmpty()) {
          Collections.sort(mSupportVideoSizes, new SizeComparator());
          Size size = mSupportVideoSizes.get(0);
          try {
            mMediaRecorder.setVideoSize(size.width, size.height);
          } catch (Exception ex) {
            e.printStackTrace();
          }
        } else {
          try {
            mMediaRecorder.setVideoSize(640, 480); // Its is not on android docs but
            // it needs to be done. (640x480
            // = VGA resolution)
          } catch (Exception ex) {
            e.printStackTrace();
          }
        }
        e.printStackTrace();
      }
    } else {
      try {
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
      } catch (Exception e) {
        e.printStackTrace();
      }
      try {
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
      } catch (Exception e) {
        e.printStackTrace();
      }
      if(mSupportVideoSizes != null && !mSupportVideoSizes.isEmpty()) {
        Collections.sort(mSupportVideoSizes, new SizeComparator());
        Size size = mSupportVideoSizes.get(0);
        try {
          mMediaRecorder.setVideoSize(size.width, size.height);
        } catch (Exception e) {
          e.printStackTrace();
        }
      } else {
        try {
          mMediaRecorder.setVideoSize(640, 480); // Its is not on android docs but
          // it needs to be done. (640x480
          // = VGA resolution)
        } catch (Exception e) {
          e.printStackTrace();
        }
      }

    }
      
    // Step 4: Set output file
    mOutputFile = new File(Environment.getExternalStorageDirectory(), "Video_" 
        + DateUtil.getSystemDate("yyyy_MM_dd_HHmmss") + ".mp4");
    mMediaRecorder.setOutputFile(mOutputFile.getAbsolutePath());

    // Step 5: Set the preview output
    mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
    
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
      try {
        mMediaRecorder.setOrientationHint(90);
      } catch (NoSuchMethodError e) {
        e.printStackTrace();
      }
    }

    
    // Step 6: Prepare configured MediaRecorder
    try {
      mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
      Log.d("VideoPreview", "IllegalStateException preparing MediaRecorder: "  + e.getMessage());
      releaseMediaRecorder();
      return false;
    } catch (IOException e) {
      Log.d("VideoPreview", "IOException preparing MediaRecorder: " + e.getMessage());
      releaseMediaRecorder();
      return false;
    }
//     mMediaRecorder.setCamera(mCamera);
//
//          mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
//          mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//          if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
//
//              mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
//              mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
//              mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
//
//          } else {
//            CamcorderProfile camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
//            mMediaRecorder.setProfile(camcorderProfile);
//
//              mMediaRecorder.setVideoSize(720, 480);
//          }
//
//          mOutputFile = new File(Environment.getExternalStorageDirectory(), "Video_" 
//          + DateUtil.getSystemDate("yyyy_MM_dd_HHmmss") + ".mp4");
//      mMediaRecorder.setOutputFile(mOutputFile.getAbsolutePath());
//          mMediaRecorder.setMaxDuration(60000);
//          mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
//
//          try {
//              mMediaRecorder.prepare();
//          } catch (IllegalStateException e) {
//              releaseMediaRecorder();
//              return false;
//          } catch (IOException e) {
//              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;
    }
  }
  
  private void startRecord() {
    try {
      // initialize video camera
      if (initVideoRecorder()) {
        // Camera is available and unlocked, MediaRecorder is prepared,
        // now you can start recording
        mMediaRecorder.start();
        mButton.setBackgroundResource(mResources.getIdentifier("yuninfo_btn_video_stop", "drawable", mPackageName));
//        mButton.setEnabled(false);
      } else {
        // prepare didn't work, release the camera
        releaseMediaRecorder();
        // inform user
        mButton.setBackgroundResource(mResources.getIdentifier("yuninfo_btn_video_start", "drawable", mPackageName));
      }
      mTvTimeCount.setVisibility(View.VISIBLE);
      mTvTimeCount.setText("00:0" + (Config.YUNINFO_MAX_VIDEO_DURATION / 1000));
      Message msg = mHandler.obtainMessage(Config.YUNINFO_ID_TIME_COUNT, 1, Config.YUNINFO_MAX_VIDEO_DURATION / 1000);
      mHandler.sendMessage(msg);
      mIsRecording = true;
    } catch (Exception e) {
      showShortToast("??????????????");
      e.printStackTrace();
      exit(RESULT_ERROR, null);
    }
  }
  

  private void stopRecord() {
    // stop recording and release camera
    try {
      mMediaRecorder.stop(); // stop the recording
    } catch (Exception e) {
      if(mOutputFile != null && mOutputFile.exists()) {
        mOutputFile.delete();
        mOutputFile = null;
      }
      LogUtil.e(TAG, e.toString());
    }
    releaseMediaRecorder(); // release the MediaRecorder object
    mCamera.lock(); // take camera access back from MediaRecorder
//    releaseCamera(); // release camera
    mButton.setBackgroundResource(mResources.getIdentifier("yuninfo_btn_video_start", "drawable", mPackageName));
    mIsRecording = false;
    
    mButton.setVisibility(View.GONE);
    mIbtnCancel.setVisibility(View.VISIBLE);
    mIbtnOk.setVisibility(View.VISIBLE);
  }
  
  /**
   * 
   * @param activity
   * @param cameraId
   * @param camera
   */
  @SuppressLint("NewApi")
  public static void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) {
       Camera.CameraInfo info = new Camera.CameraInfo(); //Since API level 9
       Camera.getCameraInfo(cameraId, info);
       int rotation = activity.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;
       }

       int result;
       if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
           result = (info.orientation + degrees) % 360;
           result = (360 - result) % 360;  // compensate the mirror
       } else {  // back-facing
           result = (info.orientation - degrees + 360) % 360;
       }
       camera.setDisplayOrientation(result);
   }
  
  @Override
  protected void onResume() {
    super.onResume();
    openCamera();
  }
  
  @Override
  protected void onPause() {
    super.onPause();
    releaseCamera();
  }


  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    if(mCamera != null) {
      try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
      } catch (Exception e) {
        LogUtil.e(TAG, "Error setting camera preview: " + e.toString());
      }
    }
  }

  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width,
      int height) {
    // TODO Auto-generated method stub

  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    if (mCamera != null) {
      try {
        mCamera.stopPreview();
      } catch (Exception e) {
        LogUtil.e(TAG, "Error setting camera preview: " + e.toString());
      }
    }
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_BACK) {
      exit(RESULT_CANCELED, null);
      return true;
    }
    return super.onKeyDown(keyCode, event);
  }
  
  
  private class SizeComparator implements Comparator<Size> {

    @Override
    public int compare(Size lhs, Size rhs) {
      return rhs.width - lhs.width;
    }
  }
}




Java Source Code List

com.opensource.videorecorder.BaseActivity.java
com.opensource.videorecorder.Config.java
com.opensource.videorecorder.MainActivity.java
com.opensource.videorecorder.RecorderActivity.java
com.opensource.videorecorder.utils.DateUtil.java
com.opensource.videorecorder.utils.LogUtil.java
com.opensource.videorecorder.utils.StringUtil.java