package com.ccxt.whl.activity;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.media.MediaRecorder.OnInfoListener;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;
import com.ccxt.whl.R;
import com.ccxt.whl.video.util.Utils;
import com.easemob.util.EMLog;
import com.easemob.util.PathUtil;
public class RecorderVideoActivity extends BaseActivity implements
OnClickListener, Callback, OnErrorListener, OnInfoListener {
private final static String CLASS_LABEL="RecordActivity";
private PowerManager.WakeLock mWakeLock;
private ImageView btnStart;// 开始录制按钮
private ImageView btnStop;// 停止录制按钮
private MediaRecorder mediarecorder;// 录制视频的类
private SurfaceView surfaceview;// 显示视频的控件
private SurfaceHolder surfaceHolder;
String localPath = "";// 录制的视频路径
private Camera mCamera;
//预览的宽高
private int previewWidth=480;
private int previewHeight=480;
Parameters cameraParameters=null;
//分别为 默认摄像头(后置)、默认调用摄像头的分辨率、被选择的摄像头(前置或者后置)
int defaultCameraId = -1, defaultScreenResolution = -1 , cameraSelection = 0;
int defaultVideoFrameRate=-1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏
// 选择支持半透明模式,在有surfaceview的activity中使用
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(R.layout.recorder_activity);
PowerManager pm=(PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock=pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, CLASS_LABEL);
mWakeLock.acquire();
btnStart = (ImageView) findViewById(R.id.recorder_start);
btnStop = (ImageView) findViewById(R.id.recorder_stop);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
surfaceview = (SurfaceView) this.findViewById(R.id.surfaceview);
SurfaceHolder holder = surfaceview.getHolder();// 取得holder
holder.addCallback(this); // holder加入回调接口
// setType必须设置,要不出错.
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void back(View view) {
if (mediarecorder != null) {
// 停止录制
mediarecorder.stop();
// 释放资源
mediarecorder.release();
mediarecorder = null;
}
try {
mCamera.reconnect();
} catch (IOException e) {
Toast.makeText(this, "reconect fail", 0).show();
}
finish();
}
@Override
protected void onResume() {
super.onResume();
if (mWakeLock == null) {
// 获取唤醒锁,保持屏幕常亮
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
CLASS_LABEL);
mWakeLock.acquire();
}
}
private void handleSurfaceChanged(){
if(mCamera==null)
{
finish();
return;
}
boolean hasSupportRate=false;
List<Integer> supportedPreviewFrameRates = mCamera.getParameters().getSupportedPreviewFrameRates();
if(supportedPreviewFrameRates!=null&&supportedPreviewFrameRates.size()>0)
{
Collections.sort(supportedPreviewFrameRates);
for(int i=0;i<supportedPreviewFrameRates.size();i++)
{
int supportRate=supportedPreviewFrameRates.get(i);
if(supportRate==10)
{
hasSupportRate=true;
}
}
if(hasSupportRate)
{
defaultVideoFrameRate=10;
}else{
defaultVideoFrameRate=supportedPreviewFrameRates.get(0);
}
}
Log.d("log supportedPreviewFrameRates"+supportedPreviewFrameRates);
//获取摄像头的所有支持的分辨率
List<Camera.Size> resolutionList=Utils.getResolutionList(mCamera);
if(resolutionList!=null&&resolutionList.size()>0)
{
Collections.sort(resolutionList,new Utils.ResolutionComparator());
Camera.Size previewSize=null;
if(defaultScreenResolution==-1)
{
boolean hasSize=false;
//如果摄像头支持640*480,那么强制设为640*480
for(int i=0;i<resolutionList.size();i++)
{
Size size=resolutionList.get(i);
if(size!=null&&size.width==640&&size.height==480)
{
previewSize=size;
previewWidth=previewSize.width;
previewHeight=previewSize.height;
hasSize=true;
break;
}
}
//如果不支持设为中间的那个
if(!hasSize)
{
int mediumResolution=resolutionList.size()/2;
if(mediumResolution>=resolutionList.size())
mediumResolution=resolutionList.size()-1;
previewSize=resolutionList.get(mediumResolution);
previewWidth=previewSize.width;
previewHeight=previewSize.height;
}
}
}
}
@Override
protected void onPause() {
super.onPause();
if (mWakeLock != null) {
mWakeLock.release();
mWakeLock = null;
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.recorder_start:
mCamera.unlock();
mediarecorder = new MediaRecorder();// 创建mediarecorder对象
mediarecorder.reset();
mediarecorder.setCamera(mCamera);
mediarecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
// 设置录制视频源为Camera(相机)
mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4
mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
// 设置录制的视频编码h263 h264
mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错
mediarecorder.setVideoSize(previewWidth, previewHeight);
// // 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错
if (defaultVideoFrameRate != -1) {
mediarecorder.setVideoFrameRate(defaultVideoFrameRate);
}
mediarecorder.setPreviewDisplay(surfaceHolder.getSurface());
// 设置视频文件输出的路径
localPath = PathUtil.getInstance().getVideoPath() + "/"
+ System.currentTimeMillis() + ".mp4";
mediarecorder.setOutputFile(localPath);
mediarecorder.setOnErrorListener(this);
mediarecorder.setOnInfoListener(this);
try {
// 准备录制
mediarecorder.prepare();
// 开始录制
mediarecorder.start();
Toast.makeText(this, "录像开始", Toast.LENGTH_SHORT).show();
btnStart.setVisibility(View.INVISIBLE);
btnStop.setVisibility(View.VISIBLE);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
case R.id.recorder_stop:
if (mediarecorder != null) {
// 停止录制
mediarecorder.stop();
// 释放资源
mediarecorder.release();
mediarecorder = null;
}
try {
mCamera.reconnect();
} catch (IOException e) {
Toast.makeText(this, "reconect fail", 0).show();
}
btnStart.setVisibility(View.VISIBLE);
btnStop.setVisibility(View.INVISIBLE);
new AlertDialog.Builder(this)
.setMessage("是否发送?")
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0,
int arg1) {
arg0.dismiss();
sendVideo(null);
}
}).setNegativeButton(R.string.cancel, null).show();
break;
default:
break;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// 将holder,这个holder为开始在oncreat里面取得的holder,将它赋给surfaceHolder
surfaceHolder = holder;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 将holder,这个holder为开始在oncreat里面取得的holder,将它赋给surfaceHolder
surfaceHolder = holder;
initpreview();
handleSurfaceChanged();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// surfaceDestroyed的时候同时对象设置为null
surfaceview = null;
surfaceHolder = null;
mediarecorder = null;
releaseCamera();
}
protected void releaseCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
@SuppressLint("NewApi")
protected void initpreview() {
try {
if(Build.VERSION.SDK_INT>Build.VERSION_CODES.FROYO)
{
int numberOfCameras=Camera.getNumberOfCameras();
CameraInfo cameraInfo=new CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if(cameraInfo.facing==cameraSelection)
{
defaultCameraId=i;
}
}
}
if(mCamera!=null)
{
mCamera.stopPreview();
}
mCamera = Camera.open(CameraInfo.CAMERA_FACING_BACK);
mCamera.setPreviewDisplay(surfaceHolder);
setCameraDisplayOrientation(this, CameraInfo.CAMERA_FACING_BACK,
mCamera);
mCamera.startPreview();
} catch (Exception e) {
EMLog.e("###", e.getMessage());
showFailDialog();
return;
}
}
@SuppressLint("NewApi")
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.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);
}
MediaScannerConnection msc = null;
public void sendVideo(View view) {
if (TextUtils.isEmpty(localPath)) {
EMLog.e("Recorder", "recorder fail please try again!");
return;
}
msc = new MediaScannerConnection(this,
new MediaScannerConnectionClient() {
@Override
public void onScanCompleted(String path, Uri uri) {
Log.d("log scanner completed");
msc.disconnect();
setResult(RESULT_OK, getIntent().putExtra("uri", uri));
finish();
}
@Override
public void onMediaScannerConnected() {
msc.scanFile(localPath, "video/*");
}
});
msc.connect();
}
@Override
public void onInfo(MediaRecorder arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
public void onError(MediaRecorder arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
}
@Override
protected void onDestroy() {
super.onDestroy();
releaseCamera();
if(mWakeLock!=null)
{
mWakeLock.release();
mWakeLock=null;
}
}
@Override
public void onBackPressed() {
back(null);
}
private void showFailDialog(){
new AlertDialog.Builder(this).setTitle("提示").setMessage("打开设备失败!").setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}).setCancelable(false).show();
}
}