Android仿微信录制小视频

本文实例为大家分享了Android仿微信录制小视频的具体代码,供大家参考,具体内容如下

先上张图片看看效果

简单叙述下

  • 首先通过Camera类调用系统相机
  • 通过surfaceview绘制出来
  • 通过MediaRecorder来录制视频
  • 闪光灯 和 切换摄像头 需要重新配置Camera的参数
  • Camera预览界面画面拉升的原因是因为Surfaceview的大小与设定的比例不一致的

**本次版本更新了 切换前置摄像头录制视频问题

Android部分手机录制视频适配IOS手机问题 (OPPO手机部分不适配 目前启用的H264格式)**

完整的代码

import android.app.Activity;

import android.content.Intent;

import android.graphics.Bitmap;

import android.hardware.Camera;

import android.media.MediaMetadataRetriever;

import android.media.MediaRecorder;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.view.KeyEvent;

import android.view.MotionEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.view.ViewGroup;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.ProgressBar;

import android.widget.TextView;

import android.widget.Toast;

import com.tongxun.atongmu.dialog.CommonDialog;

import java.io.File;

import java.io.IOException;

import java.util.List;

import java.util.Timer;

import java.util.TimerTask;

public class CircleViedoActivity extends Activity implements View.OnClickListener,MediaRecorder.OnErrorListener {

private SurfaceView mSurfaceView;

private SurfaceHolder mSurfaceHolder;

private ProgressBar mProgressBar;

private Button shoot_button;

private ImageView circle_light_btn;

private ImageView circle_change_camera_btn;

private TextView circle_camera_time;

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 int mNumberOfCameras=0;//手机摄像头的数量

Bitmap bitmap;//图片缩略图

private int screenWidth;

public static File mVecordFile = null;// 文件

private boolean isOpenFlash=false;

private boolean isBackCamera=true;

private int mbackCamera;

private int mfrontCamera;

private CommonDialog commonDialog;

private static final int MOVICE_SUCCESS=1000;//录制完成

private static final int MOVICE_FILE=1001;//录制失败

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_super_video);

init_datas();

init_view();

set_datas();

init_event();

}

private void init_datas() {

isOpenCamera=true;//默认一开始就打开相机

mRecordMaxTime=10;//设置录制的时间

//获取手机摄像头的数量

Camera.CameraInfo cameraInfo=new Camera.CameraInfo();

mNumberOfCameras=Camera.getNumberOfCameras();

for(int camidx=0;camidx<mNumberOfCameras;camidx++){

Camera.getCameraInfo(camidx, cameraInfo);

if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_BACK){

mbackCamera=camidx;

}else if(cameraInfo.facing==Camera.CameraInfo.CAMERA_FACING_FRONT){

mfrontCamera=camidx;

}

}

}

private void init_view() {

mWidth=640;

mHeight=480;

//获取屏幕的宽度

screenWidth = getWindowManager().getDefaultDisplay().getWidth();

mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);//预览界面

mProgressBar = (ProgressBar) findViewById(R.id.progressBar);//进度条

shoot_button = (Button) findViewById(R.id.shoot_button);//拍摄按钮

circle_camera_time= (TextView) findViewById(R.id.circle_camera_time);

circle_change_camera_btn= (ImageView) findViewById(R.id.circle_change_camera_btn);//切换摄像头

circle_light_btn= (ImageView) findViewById(R.id.circle_light_btn);//开启闪光灯

ViewGroup.LayoutParams params=mSurfaceView.getLayoutParams();

params.height=(screenWidth*4)/3;

params.width=screenWidth;

mSurfaceView.setLayoutParams(params);

top_model2_left_img= (ImageView)findViewById(R.id.top_model2_left_img);

top_model2_left_img.setOnClickListener(this);

top_model2_right_img= (ImageView)findViewById(R.id.top_model2_right_img);

top_model2_right_img.setVisibility(View.INVISIBLE);

top_model2_txt= (TextView)findViewById(R.id.top_model2_txt);

top_model2_txt.setText("视频录制");

}

private void set_datas() {

mSurfaceHolder = mSurfaceView.getHolder();

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

mSurfaceHolder.setKeepScreenOn(true);//设置屏幕常亮

mSurfaceHolder.addCallback(new CustomCallBack());

mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

circle_camera_time.setText("");

}

private void init_event() {

circle_light_btn.setOnClickListener(this);

circle_change_camera_btn.setOnClickListener(this);

shoot_button.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN) {

record(new OnRecordFinishListener() {

@Override

public void onRecordFinish() {

//录制时间达到最大值

handler.sendEmptyMessage(MOVICE_SUCCESS);

}

});

} else if (event.getAction() == MotionEvent.ACTION_UP) {

if (mTimeCount > 1 && mTimeCount<10) { //防止达到最大值up事件

//录制时间大于一秒

handler.sendEmptyMessage(MOVICE_SUCCESS);

} else if(mTimeCount<=1) {

//删除小于一秒的视频

if (getmVecordFile() != null) {

getmVecordFile().delete();

}

handler.sendEmptyMessage(MOVICE_FILE);

}

}

return true;

}

});

}

@Override

protected void onResume() {

super.onResume();

if(mCamera!=null){

freeCameraResource();

}

try {

initCamera();

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

// mRecorderView.stop();

}

private Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

//停止拍摄

stopRecord();

switch (msg.what){

case MOVICE_SUCCESS:

String msgs = "确认上传吗?";

commonDialog = new CommonDialog(CircleViedoActivity.this, new CommonDialog.GoCommonDialog() {

@Override

public void go() {

finishActivity();

commonDialog.dismiss();

}

@Override

public void cancel() {

//删除没有上传的视频

if (getmVecordFile() != null) {

getmVecordFile().delete();

}

commonDialog.dismiss();

}

}, msgs, "确定", "取消");

commonDialog.show();

break;

case MOVICE_FILE:

Toast.makeText(CircleViedoActivity.this, "视频录制时间太短", Toast.LENGTH_SHORT).show();

break;

}

}

};

private void finishActivity() {

stop();

Bitmap bitmap = null;

if (getmVecordFile() != null) {

//得到文件 File类型

File mfile = getmVecordFile();

bitmap = getVideoThumbnail(mfile.toString());

}

/**

* 部分Android手机缩略图拉不到,找到一种解决办法不是太满意 有没有大神提供思路

*/

// VideoPlayerActivity.startActivity(this, mRecorderView.getVecordFile().toString());

Intent intent = new Intent();

intent.putExtra("bitmap",bitmap);

setResult(RESULT_OK,intent);

finish();

}

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

}

}

@Override

public void onClick(View v) {

switch (v.getId()){

case R.id.circle_light_btn:

//开启关闭闪光灯 默认关闭

if(isOpenFlash){

isOpenFlash=false;

circle_light_btn.setImageResource(R.drawable.camera_light);

}else {

isOpenFlash=true;

circle_light_btn.setImageResource(R.drawable.camera_no_light);

}

try {

initCamera();

} catch (IOException e) {

e.printStackTrace();

}

break;

case R.id.circle_change_camera_btn:

if(isBackCamera){

isBackCamera=false;

}else {

isBackCamera=true;

}

try {

initCamera();

} catch (IOException e) {

e.printStackTrace();

}

break;

case R.id.top_model2_left_img:

stop();

finish();

break;

}

}

private class CustomCallBack implements SurfaceHolder.Callback {

@Override

public void surfaceCreated(SurfaceHolder holder) {

if (!isOpenCamera)

return;

try {

initCamera();

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

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

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

}

}

/**

* 初始化摄像头

*/

private void initCamera() throws IOException {

if (mCamera != null) {

freeCameraResource();

}

try {

if(isBackCamera){

mCamera = Camera.open(mbackCamera);//打开后摄像头

setCameraParams(isOpenFlash);

}else {

mCamera=Camera.open(mfrontCamera);//打开前摄像头

}

} catch (Exception e) {

e.printStackTrace();

freeCameraResource();

}

if (mCamera == null)

return;

mCamera.setDisplayOrientation(90);

mCamera.setPreviewDisplay(mSurfaceHolder);

mCamera.startPreview();

mCamera.unlock();

}

/**

* 设置摄像头为竖屏

*/

private void setCameraParams(Boolean isOpenFlash) {

if (mCamera != null) {

Camera.Parameters params = mCamera.getParameters();

//获取预览的各种分辨率

List<Camera.Size> supportedPreviewSizes = params.getSupportedPreviewSizes();

params.set("orientation", "portrait");//竖屏录制

params.setPreviewSize(mWidth, mHeight);//默认640*480

params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//持续对焦

if(isBackCamera){

if(isOpenFlash){

//开启闪光灯

params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);

}else {

//关闭闪光灯

params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);

}

}else {

}

mCamera.setParameters(params);

}

}

/**

* 释放摄像头资源

*/

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 + "ATOMImg/video/");

if (!sampleDir.exists()) {

sampleDir.mkdirs();

}

File vecordDir = sampleDir;

// 创建文件

try {

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

} catch (IOException e) {

}

}

/**

* 初始化

*/

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(MediaRecorder.VideoSource.CAMERA);// 视频源

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 音频源

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 视频输出格式

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 音频格式

mMediaRecorder.setVideoSize(mWidth, mHeight);// 设置分辨率:

// mMediaRecorder.setVideoFrameRate(16);// 这个我把它去掉了,感觉没什么用

mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 1024);// 设置帧频率,然后就清晰了

if(isBackCamera) {

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

}else {

mMediaRecorder.setOrientationHint(270);

}mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// 视频录制格式

----------

/**

这里是配置摄像头的重点 因为我们录制视频需要适配IOS开发和Android不同版本的手机 而IOS和Android通配的视频格式不多 我们这里采用H264格式 它的兼容范围更广阔 主要解决的就是部分OPPO手机不适配问题

*/

----------

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

}

}

/**

* 录制完成回调接口

*/

public interface OnRecordFinishListener {

public void onRecordFinish();

}

/**

* 录制

* @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);// 设置进度条

// handler.sendEmptyMessage(TIME_CHANGW);

runOnUiThread(new Runnable() {

@Override

public void run() {

circle_camera_time.setText(mTimeCount + "″");

}

});

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

//录制完成调用录制回调接口

if (mOnRecordFinishListener != null)

mOnRecordFinishListener.onRecordFinish();

}

}

}, 0, 1000);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 停止拍摄

*/

public void stop() {

stopRecord();

releaseRecord();

freeCameraResource();

}

/**

* 停止录制

*/

public void stopRecord() {

mProgressBar.setProgress(0);

circle_camera_time.setText("");

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

}

}

}

/**

* 获取的视频的位置

* @return

*/

public File getmVecordFile() {

return mVecordFile;

}

/**

* 释放资源

*/

private void releaseRecord() {

if (mMediaRecorder != null) {

mMediaRecorder.setOnErrorListener(null);

try {

mMediaRecorder.release();

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

}

mMediaRecorder = null;

}

@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

if ((keyCode == KeyEvent.KEYCODE_BACK)) {

stop();

finish();

return false;

}else {

return super.onKeyDown(keyCode, event);

}

}

/**

* 获取视频缩略图

* @param filePath

* @return

*/

public Bitmap getVideoThumbnail(String filePath) {

Bitmap bitmap = null;

MediaMetadataRetriever retriever = new MediaMetadataRetriever();

try {

retriever.setDataSource(filePath);

bitmap = retriever.getFrameAtTime();

}

catch(IllegalArgumentException e) {

e.printStackTrace();

}

catch (RuntimeException e) {

e.printStackTrace();

}

finally {

try {

retriever.release();

}

catch (RuntimeException e) {

e.printStackTrace();

}

}

return bitmap;

}

@Override

protected void onDestroy() {

super.onDestroy();

if(bitmap!=null){

try {

bitmap.recycle();

} catch (Exception e) {

e.printStackTrace();

}

bitmap=null;

}

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

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

回到顶部