java制作仿微信录制小视频控件

本文为用 MediaRecorder 录制小视频的控件,可以设置视频录制的时间、空间大小、初始时是否打开摄像头等。 此控件为组合控件,继承自 LinearLayout ,为防止出错,需实现 android.media.MediaRecorder.OnErrorListener 接口。

小视频录制界面

MovieRecorderView.java

import java.io.File;

import java.io.IOException;

import java.util.Timer;

import java.util.TimerTask;

import android.content.Context;

import android.content.res.TypedArray;

import android.hardware.Camera;

import android.hardware.Camera.Parameters;

import android.media.MediaRecorder;

import android.media.MediaRecorder.AudioEncoder;

import android.media.MediaRecorder.AudioSource;

import android.media.MediaRecorder.OnErrorListener;

import android.media.MediaRecorder.OutputFormat;

import android.media.MediaRecorder.VideoEncoder;

import android.media.MediaRecorder.VideoSource;

import android.util.AttributeSet;

import android.view.LayoutInflater;

import android.view.SurfaceHolder;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

import android.widget.LinearLayout;

import android.widget.ProgressBar;

import com.contron.dgyj.R;

import com.contron.dgyj.common.Globals;

import com.contron.dgyj.im.ImGlobal;

import com.lidroid.xutils.util.LogUtils;

/**

* 视频播放控件

*

* @author liuyinjun

*

* @date 2015-2-5

*/

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 MovieRecorderView(Context context) {

this(context, null);

}

public MovieRecorderView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public MovieRecorderView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MovieRecorderView, defStyle, 0);

mWidth = a.getInteger(R.styleable.MovieRecorderView_width, 320);// 默认320

mHeight = a.getInteger(R.styleable.MovieRecorderView_height, 240);// 默认240

isOpenCamera = a.getBoolean(R.styleable.MovieRecorderView_is_open_camera, true);// 默认打开

mRecordMaxTime = a.getInteger(R.styleable.MovieRecorderView_record_max_time, 10);// 默认为10

LayoutInflater.from(context).inflate(R.layout.movie_recorder_view, this);

mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);

mProgressBar = (ProgressBar) findViewById(R.id.progressBar);

mProgressBar.setMax(mRecordMaxTime);// 设置进度条最大量

mSurfaceHolder = mSurfaceView.getHolder();

mSurfaceHolder.addCallback(new CustomCallBack());

mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

a.recycle();

}

/**

*

* @author liuyinjun

*

* @date 2015-2-5

*/

private class CustomCallBack implements Callback {

@Override

public void surfaceCreated(SurfaceHolder holder) {

if (!isOpenCamera)

return;

try {

initCamera();

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

}

}

/**

* 初始化摄像头

*

* @author liuyinjun

* @date 2015-2-5

* @throws IOException

*/

private void initCamera() throws IOException {

if (mCamera != null) {

freeCameraResource();

}

try {

mCamera = Camera.open();

} catch (Exception e) {

e.printStackTrace();

freeCameraResource();

}

if (mCamera == null)

return;

setCameraParams();

mCamera.setDisplayOrientation(90);

mCamera.setPreviewDisplay(mSurfaceHolder);

mCamera.startPreview();

mCamera.unlock();

}

/**

* 设置摄像头为竖屏

*

* @author liuyinjun

* @date 2015-2-5

*/

private void setCameraParams() {

if (mCamera != null) {

Parameters params = mCamera.getParameters();

params.set("orientation", "portrait");

mCamera.setParameters(params);

}

}

/**

* 释放摄像头资源

*

* @author liuyinjun

* @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/");

if (!sampleDir.exists()) {

sampleDir.mkdirs();

}

File vecordDir = sampleDir;

// 创建文件

try {

mVecordFile = File.createTempFile("recording", ".mp4", vecordDir);//mp4格式

LogUtils.i(mVecordFile.getAbsolutePath());

} catch (IOException e) {

}

}

/**

* 初始化

*

* @author liuyinjun

* @date 2015-2-5

* @throws IOException

*/

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);// 设置帧频率,然后就清晰了

mMediaRecorder.setOrientationHint(90);// 输出旋转90度,保持竖屏录制

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

}

}

/**

* 开始录制视频

*

* @author liuyinjun

* @date 2015-2-5

* @param fileName

* 视频储存位置

* @param onRecordFinishListener

* 达到指定时间之后回调接口

*/

public void record(final OnRecordFinishListener onRecordFinishListener) {

this.mOnRecordFinishListener = onRecordFinishListener;

createRecordDir();

try {

if (!isOpenCamera)// 如果未打开摄像头,则打开

initCamera();

initRecord();

mTimeCount = 0;// 时间计数器重新赋值

mTimer = new Timer();

mTimer.schedule(new TimerTask() {

@Override

public void run() {

// TODO Auto-generated method stub

mTimeCount++;

mProgressBar.setProgress(mTimeCount);// 设置进度条

if (mTimeCount == mRecordMaxTime) {// 达到指定时间,停止拍摄

stop();

if (mOnRecordFinishListener != null)

mOnRecordFinishListener.onRecordFinish();

}

}

}, 0, 1000);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 停止拍摄

*

* @author liuyinjun

* @date 2015-2-5

*/

public void stop() {

stopRecord();

releaseRecord();

freeCameraResource();

}

/**

* 停止录制

*

* @author liuyinjun

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

}

}

}

/**

* 释放资源

*

* @author liuyinjun

* @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 liuyinjun

*

* @date 2015-2-5

*/

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

}

}

}

movie_recorder_view.xml

<?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:background="@android:color/background_dark"

android:orientation="vertical">

<SurfaceView

android:id="@+id/surfaceview"

android:layout_width="fill_parent"

android:layout_height="0dp"

android:layout_weight="1"

/>

<ProgressBar

android:id="@+id/progressBar"

style="?android:attr/progressBarStyleHorizontal"

android:layout_width="match_parent"

android:layout_height="2dp"

/>

</LinearLayout>

attrs.xml

<?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:background="@android:color/background_dark"

android:orientation="vertical">

<SurfaceView

android:id="@+id/surfaceview"

android:layout_width="fill_parent"

android:layout_height="0dp"

android:layout_weight="1"

/>

<ProgressBar

android:id="@+id/progressBar"

style="?android:attr/progressBarStyleHorizontal"

android:layout_width="match_parent"

android:layout_height="2dp"

/>

</LinearLayout>

以上所述就是本文的全部内容了,希望大家能够喜欢。

以上是 java制作仿微信录制小视频控件 的全部内容, 来源链接: utcz.com/p/207189.html

回到顶部