转自:http://blog.csdn.net/ameyume/article/details/7884118
MediaRecorder可以实现录音和录像。
MediaRecorder官方说明:
http://developer.android.com/reference/android/media/MediaRecorder.html
使用MediaRecorder录音录像时需要严格遵守API说明中的函数调用先后顺序,否则不能成功执行。
下面是MediaRecorder实现录像的例子。
此程序在高通MSM7225平台的华为U8500 2.2版本上可以正常录像。但在MTK MT6575平台的联想A750上不能正常运行,无法实现录像。
在展讯8810 2.3.5平台可以实现录像,但播放没有声音,通过mediaInfo查看,已经有视频数据了,但是无法播放,在PC上也不能播放,可能是录制的时候出现了问题。
可见,通过camera录像的程序对平台和硬件的依赖性很强,同样的程序在不同的手机上表现差别很大。
1.Activity类
- public class MainActivity extends Activity implements SurfaceHolder.Callback {
- private static final String TAG = "MainActivity";
- private SurfaceView mSurfaceview;
- private Button mBtnStartStop;
- private boolean mStartedFlg = false;
- private MediaRecorder mRecorder;
- private SurfaceHolder mSurfaceHolder;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏
- // 设置横屏显示
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
- // 选择支持半透明模式,在有surfaceview的activity中使用。
- getWindow().setFormat(PixelFormat.TRANSLUCENT);
- setContentView(R.layout.activity_main);
- mSurfaceview = (SurfaceView)findViewById(R.id.surfaceview);
- mBtnStartStop = (Button)findViewById(R.id.btnStartStop);
- mBtnStartStop.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- if (!mStartedFlg) {
- // Start
- if (mRecorder == null) {
- mRecorder = new MediaRecorder(); // Create MediaRecorder
- }
- try {
- // Set audio and video source and encoder
- // 这两项需要放在setOutputFormat之前
- mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
- mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
- // Set output file format
- mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- // 这两项需要放在setOutputFormat之后
- mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
- mRecorder.setVideoSize(320, 240);
- mRecorder.setVideoFrameRate(20);
- 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() + ".3gp";
- mRecorder.setOutputFile(path);
- Log.d(TAG, "bf mRecorder.prepare()");
- mRecorder.prepare();
- Log.d(TAG, "af mRecorder.prepare()");
- Log.d(TAG, "bf mRecorder.start()");
- mRecorder.start(); // Recording is now started
- Log.d(TAG, "af mRecorder.start()");
- mStartedFlg = true;
- mBtnStartStop.setText("Stop");
- Log.d(TAG, "Start recording ...");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- // stop
- if (mStartedFlg) {
- try {
- Log.d(TAG, "Stop recording ...");
- Log.d(TAG, "bf mRecorder.stop(");
- mRecorder.stop();
- Log.d(TAG, "af mRecorder.stop(");
- mRecorder.reset(); // You can reuse the object by going back to setAudioSource() step
- mBtnStartStop.setText("Start");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- mStartedFlg = false; // Set button status flag
- }
- }
- });
- SurfaceHolder holder = mSurfaceview.getHolder();// 取得holder
- holder.addCallback(this); // holder加入回调接口
- // setType必须设置,要不出错.
- holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
- }
- /**
- * 获取系统时间
- * @return
- */
- public static String getDate(){
- Calendar ca = Calendar.getInstance();
- int year = ca.get(Calendar.YEAR); // 获取年份
- int month = ca.get(Calendar.MONTH); // 获取月份
- int day = ca.get(Calendar.DATE); // 获取日
- int minute = ca.get(Calendar.MINUTE); // 分
- int hour = ca.get(Calendar.HOUR); // 小时
- int second = ca.get(Calendar.SECOND); // 秒
- String date = "" + year + (month + 1 )+ day + hour + minute + second;
- Log.d(TAG, "date:" + date);
- 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();// 获取跟目录
- return sdDir.toString();
- }
- return null;
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- // TODO Auto-generated method stub
- // 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHolder
- mSurfaceHolder = holder;
- Log.d(TAG, "surfaceChanged 1");
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- // TODO Auto-generated method stub
- // 将holder,这个holder为开始在onCreate里面取得的holder,将它赋给mSurfaceHolder
- mSurfaceHolder = holder;
- Log.d(TAG, "surfaceChanged 2");
- }
- @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;
- Log.d(TAG, "surfaceDestroyed release mRecorder");
- }
- }
- }
2. Layout文件
布局文件只有一个Surface用于显示录制的视频和一个按钮用于控制开始和结束。
- <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="horizontal">
- <SurfaceView
- android:id="@+id/surfaceview"
- android:layout_weight="1"
- android:layout_width="0dip"
- android:layout_height="fill_parent" />
- <Button
- android:id="@+id/btnStartStop"
- android:layout_width="55dip"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:text="Start"
- tools:context=".MainActivity" />
- </LinearLayout>
3.Manifest文件增加权限
需要增加使用Camera,Mic,Sd卡的权限,代码如下:
- <uses-permission android:name="android.permission.CAMERA" >
- </uses-permission>
- <uses-permission android:name="android.permission.RECORD_AUDIO" >
- </uses-permission>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
- </uses-permission>