a296777513的专栏

我们一般直接从摄像头和麦克风取数据,经过编码,,保存为文件。android的视频录制需要使用到MediaRecorder,MediaRecorder除了可以用于录制音频,还可用于录制视频。

效果图如下图所示:

一个为录制过程中,可以看到屏幕上方的录制时间显示,后一个为停止录制视频。

然后录制好的视频可以在手机的SD卡中找到,如下图所示:

视频录制步骤:

1)调用MediaRecorder 对象的setVideoEncoder()、setVideoEncodingBitRate(intbitRate)、setVideoFrameRate设置所录制的视频的编码格式、编码位率、每秒多少帧等,这些参数将可以控制所录制的视频的品质、文件的大小。一般来说,视频品质越好,视频文件越大。

2)调用 MediaRecorder的setPreviewDisplay(Surfacesv)方法设置使用哪个SurfaceView来显示视频预览。

实例使用MediaRecorder录制视频:

首先要在AndroidManifest.xml加入以下权限声明:

<uses-permission android:name="android.permission.CAMERA" /><!–camera特性 –><uses-permission android:name="android.permission.RECORD_AUDIO" /><!–视屏录制权限 –><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!–外部存储权限 –>

然后下面是核心代码

import android.annotation.SuppressLint;import android.app.Activity;import android.graphics.PixelFormat;import android.hardware.Camera;import android.media.MediaRecorder;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.view.*;import android.view.SurfaceHolder.Callback;import android.widget.Button;import android.widget.LinearLayout;import android.widget.TextView;import android.widget.Toast;import java.io.File;import java.text.SimpleDateFormat;import java.util.Calendar;@SuppressLint("SimpleDateFormat")public class MyActivity extends Activity implements Callback {private SurfaceView mSurfaceview;private Button mBtnStartStop;// 开始停止录制按键private boolean mStartedFlg = false;private MediaRecorder mRecorder;// 录制视频的类private SurfaceHolder mSurfaceHolder;// 显示视频private Camera camera;private TextView timeView;// 在屏幕顶部显示录制时间private int time = 0;@SuppressLint("HandlerLeak")private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {switch (msg.what) {case 1:// 开始录制timeView.setText(time + " s");break;case 2:// 录制8s结束mRecorder.stop();mRecorder.reset(); // You can reuse the object bymBtnStartStop.setText("Start");mStartedFlg = false;time = 0;timeView.setText(time + " s");break;case 3:// 体检结束time = 0;timeView.setText(time + " s");break;}};};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏getWindow().setFormat(PixelFormat.TRANSLUCENT); // 选择支持半透明模式,在有surfaceview的activity中使用。setContentView(R.layout.main);// 加载布局timeView = (TextView) findViewById(R.id.time);mSurfaceview = (SurfaceView) findViewById(R.id.surfaceview);mBtnStartStop = (Button) findViewById(R.id.btn);mBtnStartStop.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif (!mStartedFlg) {// 开始if (mRecorder == null) {mRecorder = new MediaRecorder(); // 创建mediarecorder的对象}try {camera.unlock();mRecorder.setCamera(camera);mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);// 这两项需要放在setOutputFormat之前mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 设置录制视频源为Camera(相机)mRecorder.setOrientationHint(90);// Set output file formatmRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 设置录制完成后视频的封装格式THREE_GPP为3gp.MPEG_4为mp4// 这两项需要放在setOutputFormat之后mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);// 设置录制的视频编码h263mRecorder.setVideoSize(800, 480);// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错mRecorder.setVideoFrameRate(30);// 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错mRecorder.setMaxDuration(8000);// 设置最大的录制时间mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());// Set output file pathString path = getSDPath();if (path != null) {File dir = new File(path + "/recordtest");if (!dir.exists()) {dir.mkdir();}path = dir + "/" + getDate() + ".mp4";Toast.makeText(MyActivity.this, path,Toast.LENGTH_LONG).show();mRecorder.setOutputFile(path);mRecorder.prepare();// 准备录制mRecorder.start(); // 开始录制new Thread(new Runnable() {@Overridepublic void run() {while (time < 8) {try {time++;Thread.sleep(1000);handler.sendEmptyMessage(1);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}handler.sendEmptyMessage(2);}}).start();mStartedFlg = true;mBtnStartStop.setText("Stop");}} catch (Exception e) {e.printStackTrace();}} else {// stopif (mStartedFlg) {try {mRecorder.stop();mRecorder.reset(); // You can reuse the object by// going back to// setAudioSource() stepmBtnStartStop.setText("Start");handler.sendEmptyMessageDelayed(3, 1000);} catch (Exception e) {e.printStackTrace();}}mStartedFlg = false; // Set button status flag}}});SurfaceHolder holder = mSurfaceview.getHolder();// 取得holderholder.addCallback(this); // holder加入回调接口holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// setType必须设置,要不出错.}/** * 使用时间对录像起名 * * @return */public static String getDate() {Calendar ca = Calendar.getInstance();SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");String date = sdf.format(ca.getTimeInMillis());return date;}/** * 获取SD path * * @return */public String getSDPath() {File sdDir = null;boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在if (sdCardExist) {sdDir = Environment.getExternalStorageDirectory();// 获取跟目录// Toast.makeText(this,sdDir.toString(),Toast.LENGTH_LONG).show();return sdDir.toString();} else {Toast.makeText(this, "没有SD卡", Toast.LENGTH_LONG).show();}return null;}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {camera = Camera.open(); // 获取Camera实例try {camera.setPreviewDisplay(holder);mSurfaceview.setLayoutParams(new LinearLayout.LayoutParams(width,height));} catch (Exception e) {// 如果出现异常,则释放Camera对象camera.release();}camera.setDisplayOrientation(90);// 设置预览视频时时竖屏// 启动预览功能camera.startPreview();// 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHoldermSurfaceHolder = holder;}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHoldermSurfaceHolder = holder;}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stub// surfaceDestroyed的时候同时对象设置为nullmSurfaceview = null;mSurfaceHolder = null;if (mRecorder != null) {mRecorder.release(); // Now the object cannot be reusedmRecorder = null;}if (camera != null) {camera.release();camera = null;}}}XML的布局文件为:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=""xmlns:tools=""android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:background="@android:color/white"><TextViewandroid:id="@+id/time"android:layout_gravity="center"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="16sp"android:text="0 s"android:textColor="@android:color/background_dark"/><SurfaceViewandroid:id="@+id/surfaceview"android:layout_width="fill_parent"android:layout_height="0dip"android:layout_weight="1" /><Buttonandroid:id="@+id/btn"android:layout_width="101dp"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_weight="0.02"android:text="Start"tools:context=".MainActivity" /></LinearLayout>

走走停停,不要害怕错过什么,

a296777513的专栏

相关文章:

你感兴趣的文章:

标签云: