您的位置:首页 > 其它

自定义安卓视频录制功能

2014-06-09 17:57 429 查看
自定义安卓视频录制功能:

<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" >

    <RelativeLayout

        android:layout_width="fill_parent"

        android:layout_height="0dp"

        android:layout_weight="1" >

        <com.example.camera.MediaRecorderSurface

            android:id="@+id/surfaceViewCamera"

            android:layout_width="fill_parent"

            android:layout_height="fill_parent" />

        <TextView

            android:id="@+id/recordTimes"

            android:layout_width="fill_parent"

            android:layout_height="60dp"

            android:layout_alignParentTop="true"

            android:layout_centerHorizontal="true"

            android:background="#50000000"

            android:gravity="center"

            android:textAppearance="?android:attr/textAppearanceMedium"

            android:textColor="#cfcfcf"

            android:textSize="25sp"

            android:text="@string/action_settings" />

    </RelativeLayout>

    <RelativeLayout

        android:layout_width="fill_parent"

        android:layout_height="80dp"

        android:background="#FFFFFF"

        android:paddingLeft="10dp"

        android:paddingRight="10dp" >

        <Button

            android:id="@+id/btn_back"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_centerVertical="true"

            android:background="@drawable/back" />

        <RelativeLayout

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_centerInParent="true" >

            <Button

                android:id="@+id/btn_record"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:background="@drawable/camera"

                android:onClick="capture" />

            <Button

                android:id="@+id/btn_recorder"

                android:layout_width="20dp"

                android:layout_height="20dp"

                android:layout_toRightOf="@id/btn_record"

                android:background="@drawable/video" />

        </RelativeLayout>

        <ImageView

            android:id="@+id/img"

            android:layout_width="40dp"

            android:layout_height="40dp"

            android:layout_alignParentRight="true"

            android:layout_centerVertical="true"

            android:background="@drawable/gallery"

            android:scaleType="fitXY" />

    </RelativeLayout>

</LinearLayout>

public class MainActivity extends Activity implements OnClickListener {

private MediaRecorderSurface mSurface;
private boolean isStart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_mediarecord_test);

mSurface = (MediaRecorderSurface) findViewById(R.id.surfaceViewCamera);
mSurface.setOnClickListener(this);

//开始/停止录像
View view = findViewById(R.id.btn_record);
view.setOnClickListener(this);
//返回
view = findViewById(R.id.btn_back);
view.setOnClickListener(this);

//转换摄像机
view = findViewById(R.id.img);
view.setOnClickListener(this);

((TextView)findViewById(R.id.recordTimes)).setText("00:00");
}
private boolean flag;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_record:
if (!isStart) {
Toast.makeText(this, "开始录像", Toast.LENGTH_SHORT).show();
timer = 0;//清零
mSurface.start();

startTimer();//录制时间
isStart = true;
}else{
Toast.makeText(this, "停止录像", Toast.LENGTH_SHORT).show();
mSurface.stop();
isStart = false;
showDialog();
}
break;
case R.id.img:
if (flag) {
mSurface.swapCamera(2);

}else{
mSurface.swapCamera(1);
}
flag = !flag;
break;
case R.id.btn_back:
if (flag) {
mSurface.openLight();
}else
mSurface.closeLight();

// finish();
break;
}
}

private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:
String str = (String) msg.obj;
((TextView)findViewById(R.id.recordTimes)).setText(str);
break;
case 2:
isStart = false;//停止播放
mSurface.stop();//停止录音
showDialog();
((TextView)findViewById(R.id.recordTimes)).setText("00:00");
break;
}

};

};

private void showDialog(){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("提示");
long size = mSurface.getOutFile().length();
size = Math.round(size/1024/1024.0);
dialog.setMessage("录制完毕,保存路径:"+mSurface.getOutFile().getAbsolutePath()+"\n"+size+"M");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();

Intent intent = new Intent("android.intent.action.VIEW");

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

intent.putExtra("oneshot", 0);

intent.putExtra("configchange", 0);

Uri uri = Uri.fromFile(mSurface.getOutFile());

  intent.setDataAndType(uri, "video/*");
startActivity(intent);
}
});

dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});

dialog.show();
}
private long timer = 0;
private void startTimer(){

new Thread(){
public void run() {
while (isStart) {
timer+=1000;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (timer>=30*1000) {//录制完成
isStart = false;//停止
handler.sendEmptyMessage(2);
}else{
Message msg = handler.obtainMessage();
msg.what = 1;
String str = ToolUtils.formatTimer(timer);
Log.i("CAMERA", str);
msg.obj = str;
handler.sendMessage(msg);
}
}

};

}.start();

}

}

/*****************************

 * 视频录制

 * 

 * 

 * @author util_c

 *

 */

public class MediaRecorderSurface extends SurfaceView implements
SurfaceHolder.Callback,Camera.AutoFocusCallback, OnInfoListener, OnErrorListener{

private Camera mCamera;
private MediaRecorder mMediaRecorder;
private File outputFile;
private SurfaceHolder holder;
private int camera_id = 0;//相机的ID
private boolean isStart,isOpenLight;//开始录像/是否打开闪光灯
public MediaRecorderSurface(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);

init();
}

public MediaRecorderSurface(Context context, AttributeSet attrs) {
super(context, attrs);

init();
}

public MediaRecorderSurface(Context context) {
super(context);

init();
}

private void init() {
holder = this.getHolder();
holder.addCallback(this);
this.setKeepScreenOn(true);
//获取相机
mCamera = getMyCamera();
// 设置像素/大小

// setmCameraParameters(mCamera);
// 显示水平角度
mCamera.setDisplayOrientation(90);// 90
}

/*********释放摄像机*********/
private void releaseCamera(Camera mCamera){
if (mCamera!=null) {
//停止预览视图
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}

/**********开始录制视频***************/
public void start(){
if (mCamera!=null) {
//自动距焦
mCamera.autoFocus(this);

//录制的视频路径
outputFile = MediaUtils.getOutputMediaFile(MediaUtils.MEDIA_TYPE_VIDEO);
try {
startRecorder(outputFile);
} catch (IllegalStateException e) {
releaseCamera(mCamera);
e.printStackTrace();
} catch (IOException e) {
releaseCamera(mCamera);
e.printStackTrace();
}

// startVideo();

isStart = true;//开始录制
}else{
logger("start:no camcara");
}

}

/**********停止录制视频***************/
public void stop(){
if (isStart) {
stopRecorder(mCamera);
isStart = false;//可以录制
}
}
/*********打开的灯*********/
public void openLight(){
freshLight(3);//手电筒
}

/*********关闭的灯*********/
public void closeLight(){
freshLight(0);//关
}

/***********
* 转换摄像机
* <只有在,没有开始录像时,才能转换摄像机>
* ********************/
public void swapCamera(int position){
//只有在,没有开始录像时,才能转换摄像机
if (!isStart) {
if (mCamera!=null) {
//转换摄像机
convertCamera(position);
}else{
logger("no camera");
}
}
}

/****************************
* 开始录像
* 创建一个MediaRecorder对象
* @param file
* @throws IllegalStateException
* @throws IOException
*/
private void startRecorder(File file) throws IllegalStateException, IOException{
logger("startRecorder:"+file.getCanonicalPath());
//打开摄像机锁
mCamera.unlock();

mMediaRecorder = new MediaRecorder();

mMediaRecorder.setCamera(mCamera);

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

int sdkVersion = Integer.valueOf(android.os.Build.VERSION.SDK); 
logger("sdkVersion="+sdkVersion);
if (sdkVersion<9) {
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
   mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
   mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

}else{

// mMediaRecorder.setVideoSize(176, 144);

// mMediaRecorder.setOrientationHint(90);
//画面质量为高清0-1
//CamcorderProfile.QUALITY_HIGH高清 1
//CamcorderProfile.QUALITY_LOW 低 0
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mMediaRecorder.setVideoFrameRate(12);//采样率
}

mMediaRecorder.setPreviewDisplay(holder.getSurface());
mMediaRecorder.setOutputFile(file.getCanonicalPath());
mMediaRecorder.prepare();
mMediaRecorder.setOnInfoListener(this);
mMediaRecorder.setOnErrorListener(this);
mMediaRecorder.start();
mCamera.setPreviewCallback(new PreviewCallback() {

@Override
public void onPreviewFrame(byte[] data, Camera camera) {

// logger("Receive data size:"+data.length);
//处理图片
}
});
}

/**************************
* 闪光灯:0,关,1开,2,自动,3,手电筒

     * @param mCamera
* @param count 
*/
public void freshLight(int count) {
Parameters parameters = mCamera.getParameters();
switch (count % 3) {
case 0:// 关
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
break;
case 1:// 开
parameters.setFlashMode(Parameters.FLASH_MODE_ON);
break;
case 2:// 自动
parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
break;
case 3://手电筒
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
break;
}
mCamera.setParameters(parameters);
mCamera.startPreview();
}

/**************************
* 关闭录音,并为摄像机加锁
* @param mCamera
*/
private void stopRecorder(Camera mCamera){
logger("stopRecorder");
if (mMediaRecorder != null) {
mMediaRecorder.stop();

// mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;

//关闭摄像机
if (mCamera!=null) {
mCamera.setPreviewCallback(null);
mCamera.lock();//解除锁
}
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
logger("surfaceChanged");
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
logger("surfaceCreated");

try {
//摄像机所获取的图像显示到指定的视图上
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();//打开预览视图
} catch (IOException e) {
releaseCamera(mCamera);
e.printStackTrace();
}
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
logger("surfaceDestroyed");
releaseCamera(mCamera);
}

@Override
public void onAutoFocus(boolean success, Camera camera) {
logger("onAutoFocus");
}

public void logger(String msg) {

Log.i("TAG", msg);

}

/*************************
* 设置摄像机的映像图大小像素/照片的大小

* @param mCamera
*/
public void setmCameraParameters(Camera mCamera) {
Parameters parameters = mCamera.getParameters();
// 设置照片分辨率
List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();
int previewWidth = 0;
int previewHeight = 0;
// 设置录制像素的宽/高
for (int i = 0; i < previewSizeList.size() - 1; i++) {
// 摄像机的宽/高
previewWidth = previewSizeList.get(i).width;
previewHeight = previewSizeList.get(i).height;
logger("previewWidth=" + previewWidth + ",previewHeight="
+ previewHeight);
//
int nextWidth = previewSizeList.get(i + 1).width;
int nextHeight = previewSizeList.get(i + 1).height;
logger("nextWidth=" + nextWidth + ",nextHeight=" + nextHeight);

if (previewWidth > nextWidth) {
previewWidth = nextWidth;
}

if (previewHeight > nextHeight) {
previewHeight = nextHeight;
}
}

// previewWidth = previewWidth > previewSizeList.get(0).width ? previewWidth

// : previewSizeList.get(0).width;

// previewHeight = previewHeight > previewSizeList.get(0).height ? previewHeight

// : previewSizeList.get(0).height;

// parameters.setPreviewSize(previewWidth, previewHeight);//设置图片的尺寸为最大的

// 设置支持的像素分辨率大小
List<Camera.Size> supportedPictureSizesList = parameters
.getSupportedPictureSizes();

int supportedPictureWidth = 0;
int supportedPictureHeight = 0;

for (int i = 0; i < supportedPictureSizesList.size() - 1; i++) {
supportedPictureWidth = supportedPictureSizesList.get(i).width;
supportedPictureHeight = supportedPictureSizesList.get(i).height;

logger("supportedPictureWidth=" + supportedPictureWidth
+ ",supportedPictureHeight=" + supportedPictureHeight);

int nextWidth = supportedPictureSizesList.get(i + 1).width;
int nextHeight = supportedPictureSizesList.get(i + 1).height;

logger("nextWidth=" + nextWidth + ",nextHeight=" + nextHeight);

//设置所支持的最小尺寸大小
if (supportedPictureWidth > nextWidth) {
supportedPictureWidth = nextWidth;
}
if (supportedPictureHeight > nextHeight) {
supportedPictureHeight = nextHeight;
}
}

// supportedPictureWidth = supportedPictureWidth > supportedPictureSizesList

// .get(0).width ? supportedPictureWidth

// : supportedPictureSizesList.get(0).width;

// supportedPictureHeight = supportedPictureHeight > supportedPictureSizesList

// .get(0).height ? supportedPictureHeight

// : supportedPictureSizesList.get(0).height;

// parameters

// .setPictureSize(supportedPictureWidth, supportedPictureHeight);

logger("____previewWidth=" + previewWidth + ",previewHeight="
+ previewHeight);
logger("___supportedPictureWidth=" + supportedPictureWidth
+ ",supportedPictureHeight=" + supportedPictureHeight);
//画面旋转90度
parameters.setRotation(90);//旋转角度
//打开手电筒
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
}

/********获取相机的个数********/
@SuppressLint("NewApi")
private Camera getMyCamera() {
Camera c = null;
//默认的
if (c == null) {
if (MediaUtils.checkCameraHardware(getContext())) {
c = Camera.open();
}
}

return c;
}

/*************************

* 转换摄像机

* @param cameraPosition
* @param camera
*/
@SuppressLint("NewApi")
private void convertCamera(int cameraPosition){
//切换前后摄像头
   int cameraCount = 0;
   CameraInfo cameraInfo = new CameraInfo();
   cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
   
   if (cameraPosition>cameraCount) {
    Toast.makeText(getContext(), "您只有"+cameraCount+"摄像机", Toast.LENGTH_SHORT).show();
return;
}
   
   for(int i = 0; i < cameraCount; i++) {
       Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
       
       if(cameraPosition == 1) {
       
//代表摄像头的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置  
           //现在是后置,变更为前置
           if(cameraInfo.facing  == Camera.CameraInfo.CAMERA_FACING_FRONT) {
           
try {
           
releaseCamera(mCamera);//释放当前摄像机
mCamera = openCamera(i, holder, 90);
} catch (IOException e1) {
e1.printStackTrace();
}
               break;
           }
           
           logger("前置");
       } else {
       
//代表摄像头的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置  
           //现在是前置, 变更为后置
           if(cameraInfo.facing  == Camera.CameraInfo.CAMERA_FACING_BACK) {
           
try {
           
releaseCamera(mCamera);//释放当前摄像机
           
mCamera = openCamera(i, holder, 90);
} catch (IOException e1) {
e1.printStackTrace();
}
           
camera_id = 1;
               break;
           }
           
           logger("后置");
       }

   }
}

/********获取保存路径************/
public File getOutFile(){
return outputFile;
}

/**********************
* 打开指的一个摄像机
* @param position 那一个摄像机
* @param holder
* @param angle 旋转角色
* @throws IOException
*/
@SuppressLint("NewApi")
private Camera openCamera(int position,SurfaceHolder holder,int angle) throws IOException {
Camera camera = Camera.open(position);// 打开当前选中的摄像头
camera.setPreviewDisplay(holder);// 通过surfaceview显示取景画面
camera.startPreview();// 开始预览
// 设置预览图效果/图片大小

// setmCameraParameters(camera);
// 显示水平角度
camera.setDisplayOrientation(angle);// 90

return camera;
}

@Override
public void onInfo(MediaRecorder mr, int what, int extra) {

}

@Override
public void onError(MediaRecorder mr, int what, int extra) {

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: