码迷,mamicode.com
首页 > 移动开发 > 详细

Android录制视频

时间:2015-02-04 18:48:27      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:android   视频录制   

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

效果图如下图所示:

技术分享技术分享

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


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

技术分享


视频录制步骤:

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

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

实例使用MediaRecorder录制视频:


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 by
				mBtnStartStop.setText("Start");
				mStartedFlg = false;
				time = 0;
				timeView.setText(time + " s");
				break;
			case 3:// 体检结束
				time = 0;
				timeView.setText(time + " s");
				break;

			}
		}

		;
	};

	@Override
	public 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() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if (!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 format
						mRecorder
								.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);// 设置录制的视频编码h263

						mRecorder.setVideoSize(800, 480);// 设置视频录制的分辨率。必须放在设置编码和格式的后面,否则报错
						mRecorder.setVideoFrameRate(30);// 设置录制的视频帧率。必须放在设置编码和格式的后面,否则报错

						mRecorder.setMaxDuration(8000);// 设置最大的录制时间
						mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

						// Set output file path
						String 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() {

								@Override
								public void run() {
									while (time < 8) {
										try {
											time++;
											Thread.sleep(1000);
											handler.sendEmptyMessage(1);
										} catch (InterruptedException e) {
											// TODO Auto-generated catch block
											e.printStackTrace();
										}

									}
									handler.sendEmptyMessage(2);

								}
							}).start();

							mStartedFlg = true;
							mBtnStartStop.setText("Stop");

						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else {
					// stop
					if (mStartedFlg) {
						try {
							mRecorder.stop();
							mRecorder.reset(); // You can reuse the object by
							// going back to
							// setAudioSource() step
							mBtnStartStop.setText("Start");
							handler.sendEmptyMessageDelayed(3, 1000);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
					mStartedFlg = false; // Set button status flag
				}
			}

		});

		SurfaceHolder holder = mSurfaceview.getHolder();// 取得holder

		holder.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;
	}

	@Override
	public 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,将它赋给mSurfaceHolder
		mSurfaceHolder = holder;

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {

		// 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHolder
		mSurfaceHolder = holder;
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		// surfaceDestroyed的时候同时对象设置为null
		mSurfaceview = null;
		mSurfaceHolder = null;
		if (mRecorder != null) {
			mRecorder.release(); // Now the object cannot be reused
			mRecorder = null;
		}
		if (camera != null) {
			camera.release();
			camera = null;
		}
	}
}
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:orientation="vertical"
    android:background="@android:color/white">

    <TextView
        android: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"/>

    <SurfaceView
        android:id="@+id/surfaceview"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_weight="1" />

    <Button
        android: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>



Android录制视频

标签:android   视频录制   

原文地址:http://blog.csdn.net/a296777513/article/details/43488415

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!