android-视频拍摄

1.界面
这里写图片描述

<?xml version="1.0" encoding="utf-8"?>
<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">
    <LinearLayout
        android:id="@+id/ll_video_recorder"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">
        <ImageView
            android:id="@+id/liveBack"
            android:layout_width="?attr/actionBarSize"
            android:layout_height="?attr/actionBarSize"
            android:layout_gravity="center_vertical"
            android:scaleType="centerInside"
            android:src="@mipmap/icon_back"
            />
    </LinearLayout>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_below="@+id/ll_video_recorder">
        <SurfaceView
            android:id="@+id/surfaceview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="top|center"
            />
        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textColor="@color/colorPrimary"
            android:layout_marginBottom="10dp"
            android:textSize="20sp"
            android:text="00:00:00"
            android:layout_gravity="right|top"
            />
        <ImageView
            android:id="@+id/fl_video_priview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_video_grid"
            android:layout_gravity="center"
            android:visibility="gone"/>
    </FrameLayout>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@color/black"
        >
        <Button
            android:id="@+id/start"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:background="@drawable/shape_circle1"
            />
        <Button
            android:id="@+id/stop"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:background="@mipmap/video_record_stop"
            android:visibility="gone"/>
        <Button
            android:id="@+id/save1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_margin="20dp"
            android:text="确定"
            android:textColor="@color/white"
            android:background="@drawable/shape_circle"
            android:textSize="20sp"
            android:visibility="gone"
            />
        <Button
            android:id="@+id/cancel1"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_centerVertical="true"
            android:layout_alignParentLeft="true"
            android:layout_margin="20dp"
            android:text="取消"
            android:textColor="@color/white"
            android:textSize="20sp"
            android:background="@drawable/shape_circle"
           android:visibility="gone"
            />
    </RelativeLayout>
</LinearLayout>

2.录制Activity

import android.app.Activity;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.SensorManager;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.ButterKnife;
public class VideoRecoderActivity extends Activity implements SurfaceHolder.Callback, View.OnClickListener,View.OnTouchListener, MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {
    /**
     * 保存
     */
    @BindView(R.id.save1)
    Button save1;
    /**
     * 取消
     */
    @BindView(R.id.cancel1)
    Button cancel;
    /**
     * 开始录制按钮
     */
    @BindView(R.id.start)
    Button start;
    /**
     * 停止录制按钮
     */
    @BindView(R.id.stop)
    Button stop;
    /**
     * 显示录制时间
     */
    @BindView(R.id.time)
    TextView time;
    /**
     * 返回
     */
    @BindView(R.id.liveBack)
    ImageView back;
    /**
     * 显示视频的控件
     */
    @BindView(R.id.surfaceview)
    SurfaceView surfaceview;
    private MediaRecorder mediarecorder;// 录制视频的类
    private SurfaceHolder surfaceHolder;
    private String videoPath = null;
    private boolean previewRunning = true;
    public static int RESULT_VIDEO_CODE1 = 4001;

    /**
     * 计时器
     */
    private long mlCount = 0;
    private Timer timer = null;
    private TimerTask task = null;
    private Handler handler = null;
    private Message msg = null;
    private Camera camera = null;
    private boolean isRecording;     // 记录是否正在录像,fasle为未录像, true 为正在录像
    private boolean storage1;
    private final static int CAMERA_ID = 0;
    private boolean mIsSufaceCreated = false;
//    private int mWidth;// 视频分辨率宽度
//    private int mHeight;// 视频分辨率高度
//    private Context context;

    private Camera.Parameters params;
    private Timer mTimer;
    private TimerTask mTimerTask;
    private Camera.AutoFocusCallback mAutoFocusCallback;
    private Camera.PreviewCallback previewCallback;
    private boolean isVideoAuto = true;//是否自动聚焦
    /**定义一个常量值*/
    private static final int SENSOR_VALUE = 100;
    /**SensorManager对象*/
    private SensorManager mSensorManager;
    /**Vibrator对象*/
    private Vibrator mVibrator;
    @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.activity_video_recoder);
        ButterKnife.bind(this);
        init();
        initTime();
        storage1 = Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED);
        if (storage1) {
            start.setOnClickListener(this);
            stop.setOnClickListener(this);
            save1.setOnClickListener(this);
            cancel.setOnClickListener(this);
            back.setOnClickListener(this);
        }

    }

    private void init() {
        surfaceview.setZOrderOnTop(true);
        surfaceview.setZOrderMediaOverlay(true);
        surfaceHolder = surfaceview.getHolder();// 取得surfaceHolder
        surfaceHolder.setFormat(PixelFormat.TRANSLUCENT);

        // setType必须设置,要不出错.
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceHolder.addCallback(this); // surfaceHolder加入回调接口
        //自动聚焦回调
        mAutoFocusCallback = new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if (success) {
                    // isAutoFocus = true;
//                    camera.setOneShotPreviewCallback(null);
                }
                else {
                    mTimerTask.run();
                }
            }
        };
        //自动聚焦定时器
        mTimer = new Timer();
        mTimerTask = new TimerTask() {
            @Override
            public void run() {
                if (camera != null) {
                    camera.autoFocus(mAutoFocusCallback);
                }
            }
        };
        mTimer.schedule(mTimerTask, 0, 5000);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start:// 开始录制
                startTakeVideo();
                break;
            case R.id.stop:// 停止
                stopTakeVideo();
                break;
            case R.id.save1:// 确定
                File f = new File(videoPath);
                long size1 = getFileSize(f);
                Intent intent1 = new Intent(VideoRecoderActivity.this, MainActivity.class);
                Bundle bundle = new Bundle();
                bundle.putString("path", videoPath);
                intent1.putExtras(bundle);
                setResult(RESULT_VIDEO_CODE1, intent1);
                finish();
                break;
            case R.id.cancel1:   // 取消
                File f1 = new File(videoPath);
                FileUtil.deleteFile(f1);
                videoPath = null;
                start.setVisibility(View.VISIBLE);
                stop.setVisibility(View.GONE);
                save1.setVisibility(View.GONE);
                cancel.setVisibility(View.GONE);
                time.setVisibility(View.GONE);
                break;
            case R.id.liveBack:// 返回
                if (videoPath != null) {
                    File f2 = new File(videoPath);
                    deleteFile(f2);
                    videoPath = null;
                }
                finish();
                break;
        }
    }

    /**
     * 获取指定文件大小
     * @param
     * @return
     * @throws Exception
     */
    private long getFileSize(File file) {
        long size = 0;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            size = fis.available();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return size;
    }

    @Override
    public void onError(MediaRecorder mr, int what, int extra) {
        try {
            if (mr != null)
                mr.reset();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void startTakeVideo() {
        initMediaRecorder();

        try {
            // 准备录制
            mediarecorder.prepare();
            mediarecorder.setOnInfoListener(VideoRecoderActivity.this);
            mediarecorder.setOnErrorListener(VideoRecoderActivity.this);
            // 开始录制
            mediarecorder.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        initTime();
        time.setVisibility(View.VISIBLE);
        if (null == timer) {
            if (null == task) {
                 task = new TimerTask() {

                    @Override
                    public void run() {
                        if (null == msg) {
                            msg = new Message();
                        } else {
                            msg = Message.obtain();
                        }
                        msg.what = 1;
                        handler.sendEmptyMessageDelayed(0,2000);
                        handler.sendMessage(msg);

                    }

                };
            }
            timer = new Timer(true);
            timer.schedule(task, 1000, 1000);

        }
        start.setVisibility(View.GONE);
        stop.setVisibility(View.VISIBLE);
        save1.setVisibility(View.GONE);
        cancel.setVisibility(View.GONE);

    }

    private void initMediaRecorder() {
        mediarecorder = new MediaRecorder();//实例化
        if (camera != null) {
            camera.unlock();
        }
        //给Recorder设置Camera对象,保证录像跟预览的方向保持一致
        mediarecorder.setCamera(camera);
        mediarecorder.setOrientationHint(90);  //改变保存后的视频文件播放时是否横屏(不加这句,视频文件播放的时候角度是反的)
        mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置从麦克风采集声音
//        mediarecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
        mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 设置从摄像头采集图像
        mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);  // 设置视频的输出格式 为MP4
        mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); // 设置音频的编码格式
        mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 设置视频的编码格式
        mediarecorder.setVideoSize(640, 480);  // 设置视频大小(不同手机的分辨率不同,4.0 版本 (176,144))
//        mediarecorder.setVideoFrameRate(20); // 设置帧率
        mediarecorder.setVideoEncodingBitRate(5 * 1024 * 1024);// 设置帧频率,然后就清晰了
//        mRecorder.setMaxDuration(10000); //设置最大录像时间为10s
        mediarecorder.setPreviewDisplay(surfaceHolder.getSurface());

        //设置视频存储路径
        File file = new File(Environment.getExternalStorageDirectory() + File.separator + "VideoRecorder");
        if (!file.exists()) {
            //多级文件夹的创建
            file.mkdirs();
        }
        videoPath = file.getPath() + File.separator + "VID_" + System.currentTimeMillis() + ".mp4";
        mediarecorder.setOutputFile(videoPath);
    }


    private void stopTakeVideo() {
        stop.setVisibility(View.GONE);
        start.setVisibility(View.GONE);
        save1.setVisibility(View.VISIBLE);
        cancel.setVisibility(View.VISIBLE);
        //设置后不会崩
        if (mediarecorder != null) {

            // 停止录制
            mediarecorder.stop();
            // 释放资源
            mediarecorder.release();
            mediarecorder = null;
        }
        task.cancel();
        task = null;
        timer.cancel();
        timer.purge();
        timer = null;
        handler.removeMessages(msg.what);
        if (camera != null) {
            camera.lock();
        }
        camera.stopPreview();


    }

    private void initTime() {
        mlCount = 0;
        time.setVisibility(View.VISIBLE);
        time.setText("00:00:00");
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 1:
                        mlCount++;
                        int totalSec = 0;
                        totalSec = (int) (mlCount);
                        // Set time display
                        int hor = (totalSec / 3600);
                        int min = (totalSec / 60);
                        if (min >= 60) {
                            min = (totalSec - hor * 3600) / 60;
                        }
                        int sec = (totalSec % 60);
                        try {
                            // second(1000ms)
                            time.setText(String.format("%1$02d:%2$02d:%3$02d", hor, min, sec));
                        } catch (Exception e) {
                            time.setText("" + hor + ":" + min + ":" + sec);
                            e.printStackTrace();
                        }
                        break;

                    default:
                        break;
                }

                super.handleMessage(msg);
            }

        };
    }

    /**
     * 释放摄像头资源
     */
    private void freeCameraResource() {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.lock();
            camera.release();
            camera = null;
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
        if (camera != null && !mIsSufaceCreated) {
            return;
        }

//        Camera.Size size = getBestPreviewSize(width,height, params);
//        if (size != null) {
//            // 在使用摄像头支持的最大分辨率进行拍摄的时候会出现stop failed错误,无法关闭MediaRecorder,原因不明!
//            params.setPreviewSize(size.width,size.height);
//        }
//        params = camera.getParameters();
//        params.setPictureFormat(PixelFormat.JPEG);
//        // 设置预浏尺寸,注意要在摄像头支持的范围内选择
        params.setPreviewSize(176,144);
//        params.setPreviewSize(640, 480);//arg2--width, arg3--height
 设置照片分辨率,注意要在摄像头支持的范围内选择
        params.setPictureSize(640,480);//(手机5.0以下会出错)
//        camera.setParameters(params);
//
//        if (Build.VERSION.SDK_INT >= 14) {
//            params.setFocusMode("auto");
//            camera.autoFocus(mAutoFocusCallback);
//        } else {
//            params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
//            isVideoAuto = false;
//        }
//        params.setPreviewFrameRate(20);
//        //设置相机预览方向
//        camera.setDisplayOrientation(90);
//
//        try {
//            camera.setPreviewDisplay(holder);
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        initCamera();

    }
    /**
     *加载相机相关组件
     */
    private void initCamera() {
        surfaceview.setFocusable(false);
        surfaceview.setEnabled(false);
        if(camera==null){
            camera = Camera.open(CAMERA_ID);
        }
        params = camera.getParameters();
        //获得摄像头支持的分辨率
//        List<Camera.Size> supportedPreviewSizes = params.getSupportedPreviewSizes();
//        for(Camera.Size size:supportedPreviewSizes){
//            Log.d("tag", "width" + size.width + ",height" + size.height);
//        }
//        if (Build.VERSION.SDK_INT >= 14) {
//            params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//            camera.autoFocus(mAutoFocusCallback);
//        } else {
//            isVideoAuto = false;
//        }


        List<Camera.Size> sizeList = params.getSupportedPreviewSizes();
        int PreviewWidth = 640;
        int PreviewHeight = 480;
        Boolean findSize = false;
        if (sizeList.size() > 1) {
            Iterator itor = sizeList.iterator();
            while (itor.hasNext()) {
                Camera.Size cur = (Camera.Size) itor.next();
                if (cur.width >= PreviewWidth
                && cur.height >= PreviewHeight) {
                    findSize = true;
                    PreviewWidth = cur.width;
                    PreviewHeight = cur.height;
                    break;
                    }
                }
            }
        if (!findSize) {
            PreviewWidth = sizeList.get(0).width;
            PreviewHeight = sizeList.get(0).height;
            }
        params.setPreviewSize(PreviewWidth, PreviewHeight);

//        params.setPreviewSize(640, 480);
        params.setPreviewFrameRate(20);
        if (params.isVideoStabilizationSupported())
        {
            params.setVideoStabilization(true);
        }
        params.setRotation(90);
        camera.setParameters(params);
        //设置相机预览方向
        camera.setDisplayOrientation(90);
        try {
            camera.setPreviewDisplay(surfaceview.getHolder());
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        surfaceview.setOnTouchListener(this);
        camera.startPreview();
        params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mIsSufaceCreated = true;
        if (camera != null) {
            freeCameraResource();
        }
        if (null == camera) {
            try {
                camera = Camera.open(CAMERA_ID);
                camera.setPreviewDisplay(holder);
//                camera.autoFocus(mAutoFocusCallback);
            } catch (Exception e) {
                e.printStackTrace();
                freeCameraResource();
            }

        }

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // surfaceDestroyed的时候同时对象设置为null
        if (camera != null) {
            camera.stopPreview();
            camera.release();
            camera = null;
        }
        surfaceview = null;
        mediarecorder = null;
        mIsSufaceCreated = false;
        mAutoFocusCallback = null;
    }

    @Override
    public void onInfo(MediaRecorder mediaRecorder, int i, int i1) {

    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (camera != null && isVideoAuto) {
                float x = event.getX();
                float y = event.getY();
                float touchMajor = event.getTouchMajor();
                float touchMinor = event.getTouchMinor();

                Rect touchRect = new Rect((int) (x - touchMajor / 2),
                        (int) (y - touchMinor / 2), (int) (x+touchMajor / 2),
                (int) (y + touchMinor / 2));

                this.submitFocusAreaRect(touchRect);
            }
        }
        return false;
    }
    private void submitFocusAreaRect(final Rect touchRect) {
        Camera.Parameters cameraParameters = camera.getParameters();
        if (cameraParameters == null
                || cameraParameters.getMaxNumFocusAreas() == 0) {
            return;
        }

        // Convert from View's width and height to +/- 1000
        Rect focusArea = new Rect();
        focusArea.set(touchRect.left * 2000 / surfaceview.getWidth() - 1000,
                touchRect.top * 2000 / surfaceview.getHeight() - 1000,
                touchRect.right * 2000 / surfaceview.getWidth() - 1000,
                touchRect.bottom * 2000 / surfaceview.getHeight() - 1000);
        // Submit focus area to camera
        ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
        focusAreas.add(new Camera.Area(focusArea, 1000));
        cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        cameraParameters.setFocusAreas(focusAreas);
        try {
            camera.setParameters(cameraParameters);
            camera.autoFocus(mAutoFocusCallback);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 删除文件
     * @param file 已经存在的文件
     */
    public static void deleteFile(File file) {
        if (file.exists()) { // 判断文件是否存在
            if (file.isFile()) { // 判断是否是文件
                file.delete(); // delete()方法 你应该知道 是删除的意思;
            } else if (file.isDirectory()) { // 否则如果它是一个目录
                File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
                    deleteFile(files[i]); // 把每个文件 用这个方法进行迭代
                }
            }
            file.delete();
        } else {

        }
    }
    }

3.在AndroidManifest.xml表单文件中添加权限

  <!-- 拍摄视频 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.RECORD_VIDEO"/>
     <uses-permission android:name="android.permission.CAMERA" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值