Android 录视频可切换摄像头,记录时间,一分钟小于5M,

本demo自定义控件实现视频录制,可切换摄像头,记录录制时间,测试录制一分钟小于5M。
完整demo下载地址:http://download.csdn.net/detail/bnm52007/9594709

自定义MovieRecorder

package record.lip.com.videoDemo;

import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
/**
* 视频录制控件
*
* @author lip
* @date 2015-3-16
*/
public class MovieRecorderView extends LinearLayout implements OnErrorListener {

private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private ProgressBar mProgressBar;
private MediaRecorder mMediaRecorder;
private Camera mCamera;
private Timer mTimer;// 计时器
private OnRecordFinishListener mOnRecordFinishListener;// 录制完成回调接口

private int mWidth;// 视频分辨率宽度
private int mHeight;// 视频分辨率高度
private boolean isOpenCamera;// 是否一开始就打开摄像头
private int mRecordMaxTime;// 一次拍摄最长时间
private int mTimeCount;// 时间计数
private File mVecordFile = null;// 文件
public int mark = Camera.CameraInfo.CAMERA_FACING_BACK;
private TextView timer;
//记录录制时间
Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (1 == msg.what) {
            mTimeCount = (int) msg.obj;
            if (mTimeCount > 9) {
                timer.setText("00:" + mTimeCount);
            } else {
                timer.setText("00:0" + mTimeCount);
            }
        }
    }
};

public MovieRecorderView(Context context) {
    this(context, null);
}

public MovieRecorderView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}


@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public MovieRecorderView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mWidth = 1280;
    mHeight = 720;
    isOpenCamera = true;
    mRecordMaxTime = 60;

    LayoutInflater.from(context).inflate(R.layout.moive_recorder_view, this);
    mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
    timer = (TextView) findViewById(R.id.timer);
    mProgressBar.setMax(mRecordMaxTime);// 设置进度条最大量
    mSurfaceHolder = mSurfaceView.getHolder();
    mSurfaceHolder.addCallback(new CustomCallBack());
    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

/**
 * @date 2015-2-5
 */
private class CustomCallBack implements Callback {

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (!isOpenCamera){
            return;
        }
        try {
            initCamera(mark);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (!isOpenCamera)
            return;
        freeCameraResource();
    }

}

/**
 * 初始化摄像头
 *
 * @throws IOException
 * @author lip
 * @date 2015-3-16
 */
private void initCamera(int mark) throws IOException {
    if (mCamera != null) {
        freeCameraResource();
    }
    try {
        mCamera = Camera.open(mark);
    } catch (Exception e) {
        e.printStackTrace();
        freeCameraResource();
    }
    if (mCamera == null) {
        return;
    }
    setCameraParams();
    mCamera.setDisplayOrientation(90);
    mCamera.setPreviewDisplay(mSurfaceHolder);
    mCamera.startPreview();
    mCamera.unlock();
}

/**
 * 设置摄像头为竖屏
 *
 * @author lip
 * @date 2015-3-16
 */
private void setCameraParams() {
    if (mCamera != null) {
        Parameters params = mCamera.getParameters();
        params.set("orientation", "portrait");
        mCamera.setParameters(params);
    }
}

/**
 * 释放摄像头资源
 *
 * @date 2015-2-5
 */
private void freeCameraResource() {
    if (mCamera != null) {
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.lock();
        mCamera.release();
        mCamera = null;
    }
}

private void createRecordDir() {
    // File sampleDir = new File(Environment.getExternalStorageDirectory() + File.separator + "im/video/");
    File sampleDir = new File(Environment.getExternalStorageDirectory() + File.separator + "RecordVideo/");
    //File sampleDir = new File("/video/");
    if (!sampleDir.exists()) {
        sampleDir.mkdirs();
    }
    File vecordDir = sampleDir;
    // 创建文件
    try {
        mVecordFile = File.createTempFile("recording", ".mp4", vecordDir);//mp4格式
        //LogUtils.i(mVecordFile.getAbsolutePath());
        Log.d("Path:", mVecordFile.getAbsolutePath());
    } catch (IOException e) {
    }
}

/**
 * 初始化
 *
 * @throws IOException
 * @author lip
 * @date 2015-3-16
 */
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
private void initRecord() throws IOException {
    mMediaRecorder = new MediaRecorder();
    mMediaRecorder.reset();
    if (mCamera != null)
        mMediaRecorder.setCamera(mCamera);
    mMediaRecorder.setOnErrorListener(this);
    mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
    mMediaRecorder.setVideoSource(VideoSource.CAMERA);// 视频源
    mMediaRecorder.setAudioSource(AudioSource.MIC);// 音频源
    mMediaRecorder.setOutputFormat(OutputFormat.MPEG_4);// 视频输出格式
    mMediaRecorder.setAudioEncoder(AudioEncoder.AMR_NB);// 音频格式
    mMediaRecorder.setVideoSize(mWidth, mHeight);// 设置分辨率:

// mMediaRecorder.setVideoFrameRate(16);// 这个我把它去掉了,感觉没什么用
mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 512);// 设置帧频率,然后就清晰了
if (mark == Camera.CameraInfo.CAMERA_FACING_BACK) {
mMediaRecorder.setOrientationHint(90);// 输出旋转90度,保持竖屏录制
} else {
mMediaRecorder.setOrientationHint(270);//前置摄像头
}
mMediaRecorder.setVideoEncoder(VideoEncoder.MPEG_4_SP);// 视频录制格式
// mediaRecorder.setMaxDuration(Constant.MAXVEDIOTIME * 1000);
mMediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());
mMediaRecorder.prepare();
try {
mMediaRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (RuntimeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/**
 * 开始录制视频
 *
 * @param onRecordFinishListener 达到指定时间之后回调接口
 * @date 2015-2-5
 * //     * @param fileName
 * //     *            视频储存位置
 */
public void record(final OnRecordFinishListener onRecordFinishListener, final int mark) {
    this.mOnRecordFinishListener = onRecordFinishListener;
    createRecordDir();
    try {
        if (!isOpenCamera) {
            initCamera(mark); // 如果未打开摄像头,则打开
        }
        initRecord();
        mTimeCount = 0;// 时间计数器重新赋值
        mTimer = new Timer();
        mTimer.schedule(new TimerTask() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                mTimeCount++;
                Message message = new Message();
                message.what = 1;
                message.obj = mTimeCount;
                handler.sendMessage(message);
                mProgressBar.setProgress(mTimeCount);// 设置进度条
                if (mTimeCount == mRecordMaxTime) {// 达到指定时间,停止拍摄
                    stop();
                    if (mOnRecordFinishListener != null)
                        mOnRecordFinishListener.onRecordFinish();
                }
            }
        }, 0, 1000);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * 停止拍摄
 *
 * @date 2015-2-5
 */
public void stop() {
    stopRecord();
    releaseRecord();
    freeCameraResource();
}

/**
 * 停止录制
 *
 * @date 2015-2-5
 */
public void stopRecord() {
    mProgressBar.setProgress(0);
    if (mTimer != null)
        mTimer.cancel();
    if (mMediaRecorder != null) {
        // 设置后不会崩
        mMediaRecorder.setOnErrorListener(null);
        mMediaRecorder.setPreviewDisplay(null);
        try {
            mMediaRecorder.stop();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (RuntimeException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/**
 * 释放资源
 *
 * @date 2015-2-5
 */
private void releaseRecord() {
    if (mMediaRecorder != null) {
        mMediaRecorder.setOnErrorListener(null);
        try {
            mMediaRecorder.release();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    mMediaRecorder = null;
}

public int getTimeCount() {
    return mTimeCount;
}

/**
 * @return the mVecordFile
 */
public File getmVecordFile() {
    return mVecordFile;
}

/**
 * 录制完成回调接口
 *
 * @author lip
 * @date 2015-3-16
 */
public interface OnRecordFinishListener {
    public void onRecordFinish();
}

@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();
    }
}

public void switchover() {
    stop();
    if (mark == Camera.CameraInfo.CAMERA_FACING_BACK) {
        mark = Camera.CameraInfo.CAMERA_FACING_FRONT;
        try {
            initCamera(mark);
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {
        mark = Camera.CameraInfo.CAMERA_FACING_BACK;
        try {
            initCamera(mark);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

MainActivity调用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initEvents();
init();
}
private void init()
{
player=new MediaPlayer();
}
private void initViews()
{
movieRV=(MovieRecorderView)findViewById(R.id.moive_rv);
//录制
startBtn=(Button)findViewById(R.id.start_btn);
stopBtn=(Button)findViewById(R.id.stop_btn);
//切换摄像头
switchover = (Button) findViewById(R.id.switchover);
}

private void initEvents()
{
    //开始录制
    startBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            movieRV.record(new MovieRecorderView.OnRecordFinishListener() {
                @Override
                public void onRecordFinish() {

                }
            }, Camera.CameraInfo.CAMERA_FACING_BACK);
        }
    });

    //停止录制
    stopBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            movieRV.stop();
        }
    });

    //切换摄像头
    switchover.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            movieRV.stop();
            movieRV.switchover();
        }
    });
}

@Override
protected void onStop() {
    super.onStop();
    movieRV.stop();
}

布局

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值