android下自定义Camera进行录像和拍照

源码:

package com.example.myvideocamera;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
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.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 视频录制
 */
@SuppressWarnings("deprecation")
public class MainActivity extends Activity implements OnClickListener,
        SensorEventListener, Callback {
    private SurfaceView surfaceView; // 用于绘制缓冲图像的
    private Button luXiang_bt; // 开始录制的按钮
    private Button tingZhi_bt; // 停止录制的按钮
    private Button auto_focus; // 进行对焦
    private Button screenshot; // 截图
    private TextView time_tv; // 显示时间的文本框
    private MediaRecorder mRecorder;
    private boolean recording; // 记录是否正在录像,fasle为未录像, true 为正在录像
    private File videoFolder; // 存放视频的文件夹
    private File videFile; // 视频文件
    private Handler handler;
    private int time; // 时间
    private Camera myCamera; // 相机声明
    private SurfaceHolder holder; // 用来访问surfaceview的接口
    private SensorManager sManager; // 传感器管理者
    private Sensor sensor; // 传感器对象
    private int mX, mY, mZ; // x y z 坐标
    private Calendar calendar; // 日历
    private long lasttimestamp = 0; // 上一次用时的标志

    /**
     * 录制过程中,时间变化
     */
    private Runnable timeRun = new Runnable() {

        @Override
        public void run() {
            time++;
            time_tv.setText(time + "秒");
            handler.postDelayed(timeRun, 1000);
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 强制横屏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        initView();
        initSensor();
        initCreateFile();
    }

    /**
     * 对传感器进行初始化
     */
    private void initSensor() {
        sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        sensor = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (sManager == null) {
            // throw new IllegalArgumentException("SensorManager is null");
        }
        sManager.registerListener(this, sensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    /**
     * 文件的创建
     */
    private void initCreateFile() {
        // 判断sd卡是否存在
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED);
        if (sdCardExist) {
            // 设定存放视频的文件夹的路径
            String path = Environment.getExternalStorageDirectory()
                    .getAbsolutePath()
                    + File.separator
                    + "VideoFolder"
                    + File.separator;
            // 声明存放视频的文件夹的File对象
            videoFolder = new File(path);
            // 如果不存在此文件夹,则创建
            if (!videoFolder.exists()) {
                videoFolder.mkdirs();
            }
            // 设置surfaceView不管理的缓冲区
            surfaceView.getHolder().setType(
                    SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            // 设置surfaceView分辨率
            //surfaceView.getHolder().setFixedSize(1000, 500);
            luXiang_bt.setOnClickListener(this);
        } else
            Toast.makeText(this, "未找到sdCard!", Toast.LENGTH_LONG).show();
    }

    /**
     * 初始化工作
     */
    private void initView() {
        // 获取控件
        surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
        luXiang_bt = (Button) findViewById(R.id.luXiang_bt);
        tingZhi_bt = (Button) findViewById(R.id.tingZhi_bt);
        time_tv = (TextView) findViewById(R.id.time);
        auto_focus = (Button) findViewById(R.id.auto_focus);
        screenshot = (Button) findViewById(R.id.screenshot);
        handler = new Handler();
        holder = surfaceView.getHolder();
        tingZhi_bt.setOnClickListener(this);
        auto_focus.setOnClickListener(this);
        screenshot.setOnClickListener(this);
        // 添加回调
        holder.addCallback(this);
    }

    /**
     * 将Camera和mediaRecoder释放
     */
    @Override
    protected void onDestroy() {
        handler.removeCallbacks(timeRun);
        if (mRecorder != null) {
            mRecorder.release();
        }
        if (myCamera != null) {
            myCamera.stopPreview();
            myCamera.release();
        }
        super.onDestroy();
    }

    /**
     * 控件点击事件的监听
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.luXiang_bt: // 录像点击事件
            if (!recording) {
                try {
                    // 获取当前时间,作为视频文件的文件名
                    String nowTime = java.text.MessageFormat.format(
                            "{0,date,yyyyMMdd_HHmmss}",
                            new Object[] { new java.sql.Date(System
                                    .currentTimeMillis()) });
                    // 声明视频文件对象
                    videFile = new File(videoFolder.getAbsoluteFile()
                            + File.separator + "video" + nowTime + ".mp4");
                    // 关闭预览并释放资源
                    myCamera.unlock();
                    mRecorder = new MediaRecorder();
                    mRecorder.setCamera(myCamera);
                    // 创建此视频文件
                    videFile.createNewFile();
                    mRecorder.setPreviewDisplay(surfaceView.getHolder()
                            .getSurface()); // 预览
                    mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 视频源
                    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 录音源为麦克风
                    mRecorder
                            .setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 输出格式为mp4
                    /* 引用android.util.DisplayMetrics 获取分辨率 */
                    // DisplayMetrics dm = new DisplayMetrics();
                    // getWindowManager().getDefaultDisplay().getMetrics(dm);
                    mRecorder.setVideoSize(800, 480); // 视频尺寸
                    mRecorder.setVideoEncodingBitRate(2*1280*720); //设置视频编码帧率
                    mRecorder.setVideoFrameRate(30); // 视频帧频率
                    mRecorder
                            .setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); // 视频编码
                    mRecorder
                            .setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 音频编码
                    mRecorder.setMaxDuration(1800000); // 设置最大录制时间
                    mRecorder.setOutputFile(videFile.getAbsolutePath()); // 设置录制文件源
                    mRecorder.prepare(); // 准备录像
                    mRecorder.start(); // 开始录像
                    time_tv.setVisibility(View.VISIBLE); // 设置文本框可见
                    handler.post(timeRun); // 调用Runable
                    recording = true; // 改变录制状态为正在录制
                    setAutofocus();
                } catch (IOException e1) {
                    e1.printStackTrace();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            } else
                Toast.makeText(MainActivity.this, "视频正在录制中...",
                        Toast.LENGTH_LONG).show();
            break;
        case R.id.tingZhi_bt: // 停止点击事件
            if (recording) {
                mRecorder.stop();
                mRecorder.release();
                handler.removeCallbacks(timeRun);
                time_tv.setVisibility(View.GONE);
                int videoTimeLength = time;
                time = 0;
                recording = false;
                Toast.makeText(
                        MainActivity.this,
                        videFile.getAbsolutePath() + "  " + videoTimeLength
                                + "秒", Toast.LENGTH_LONG).show();
            }
            // 开启相机
            if (myCamera == null) {
                myCamera = Camera.open();
                try {
                    myCamera.setPreviewDisplay(holder);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            myCamera.startPreview(); // 开启预览
            break;
        case R.id.auto_focus:
            setAutofocus();
            break;
        case R.id.screenshot:
            myCamera.autoFocus(new AutoFocusCallback() {

                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if (success) {
                        camera.takePicture(null, null, jpegCallBack);
                    }
                }
            });
            break;
        }
    }

    /**
     * 设置自动对焦
     */
    private void setAutofocus() {
        if (myCamera != null) {
            myCamera.autoFocus(new AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if (success) {
                    }
                }
            });
        }
    }

    /**
     * 传感器改变调用的方法
     */
    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor == null) {
            return;
        }
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            int x = (int) event.values[0];
            int y = (int) event.values[1];
            int z = (int) event.values[2];
            calendar = Calendar.getInstance();
            long stamp = calendar.getTimeInMillis();
            int px = Math.abs(mX - x);
            int py = Math.abs(mY - y);
            int pz = Math.abs(mZ - z);
            int maxValue = getMaxValue(px, py, pz);
            if (maxValue > 2 && (stamp - lasttimestamp) > 30) {
                lasttimestamp = stamp;
                setAutofocus();
            }
            mX = x;
            mY = y;
            mZ = z;
        }
    }

    /**
     * 获取最大改变的值
     */
    private int getMaxValue(int px, int py, int pz) {
        int max = 0;
        if (px > py && px > pz) {
            max = px;
        } else if (py > px && py > pz) {
            max = py;
        } else if (pz > px && pz > py) {
            max = pz;
        }
        return max;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    /**
     * suraceView 创建执行的操作
     */
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 开启相机
        if (myCamera == null) {
            myCamera = Camera.open();
            try {
                myCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * suraceView 状态改变执行的操作
     */
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // 开始预览
        myCamera.startPreview();
        Parameters parameters = myCamera.getParameters();// 获取mCamera的参数对象
        Size largestSize = getBestSupportedSize(parameters
                .getSupportedPreviewSizes());
        parameters.setPreviewSize(largestSize.width, largestSize.height);// 设置预览图片尺寸
        largestSize = getBestSupportedSize(parameters
                .getSupportedPictureSizes());// 设置捕捉图片尺寸
        parameters.setPictureSize(largestSize.width, largestSize.height);
        myCamera.setParameters(parameters);
    }
    
    private Size getBestSupportedSize(List<Size> sizes) {
        // 取能适用的最大的SIZE
        Size largestSize = sizes.get(0);
        int largestArea = sizes.get(0).height * sizes.get(0).width;
        for (Size s : sizes) {
            int area = s.width * s.height;
            if (area > largestArea) {
                largestArea = area;
                largestSize = s;
            }
        }
        return largestSize;
    }  

    /**
     * suraceView 销毁执行的操作
     */
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 关闭预览并释放资源
        if (myCamera != null) {
            myCamera.stopPreview();
            myCamera.release();
            myCamera = null;
        }
    }

    /**
     * 创建jpeg图片回调数据对象
     */
    private String filepath = "";
    private PictureCallback jpegCallBack = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            Bitmap oldBitmap = BitmapFactory.decodeByteArray(data, 0,
                    data.length);
            Matrix matrix = new Matrix();
            matrix.setRotate(90);  
            Bitmap newBitmap = Bitmap.createBitmap(oldBitmap, 0, 0,
                    oldBitmap.getWidth(), oldBitmap.getHeight(),
                    matrix, true);  
            filepath = Environment.getExternalStorageDirectory()
                    + File.separator
                    + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                    + ".jpg";
            File file = new File(filepath);
            try {
                BufferedOutputStream bos = new BufferedOutputStream(
                        new FileOutputStream(file));
                newBitmap.compress(Bitmap.CompressFormat.JPEG, 85, bos);
                bos.flush();
                bos.close();
                camera.stopPreview();
                camera.startPreview();
                newBitmap.recycle();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };

}



xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff" >
     
    <SurfaceView
        android:id="@+id/surfaceview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"/>
    
    
     
    <Button
        android:id="@+id/tingZhi_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:text="停止"/>
     
     
    <Button
        android:id="@+id/luXiang_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toLeftOf="@id/tingZhi_bt"
        android:text="录像"/>
    
    <Button
        android:id="@+id/auto_focus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toLeftOf="@id/luXiang_bt"
        android:text="调焦"/>
    
    <Button
        android:id="@+id/screenshot"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toLeftOf="@id/auto_focus"
        android:text="拍照"/>
     
    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FF0000"
        android:text="1秒"
        android:visibility="gone"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"/>
 
</RelativeLayout>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值