• Android使用摄像头和麦克风录制视频


    MediaRecorder除了可用于录制音频之外,还可用于录制视频。使用MediaRecorder录制视频与录制音频的步骤基本相同。只是录制视频时不仅需要采集声音,还需要采集图像。为了让MediaRecorder录制时采集图像,应该在调用setAudioSource(int audio_source)方法时再调用setVideoSource(int video_source)方法来设置图像的来源。

    除此之外,还需要在调用setOutputFormat()方法设置输出文件格式之后执行如下步骤:
    Step1:调用MediaRecorder对象的setVideoEncoder()、setVideoEncodingBitRate(int bitRate)、setVideoFrameRate()方法设置所录制的视频编码格式、编码位率、每秒多少帧等,这些参数可以控制所录制的视频品质、文件大小。一般来说,视频品质越好,视频文件越大;
    Step2:调用MediaRecorder的setPreviewDisplay(Surface sv)方法设置使用哪个SurfaceView来显示视频预览。

    下面的Demo程序示范了如何录制视频,该程序的界面中提供了两个按钮用于控制开始、结束录制;除此之外,程序界面中还提供了一个SurfaceView来显示视频预览。

    • layout/activity_main.xml界面布局代码如下:
      <?xml version="1.0" encoding="utf-8"?>
      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
          <!-- 显示视频预览的SurfaceView -->
          <SurfaceView
              android:id="@+id/sView"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
      
          <LinearLayout
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentBottom="true"
              android:layout_centerHorizontal="true"
              android:gravity="center_horizontal"
              android:orientation="horizontal">
      
              <ImageButton
                  android:id="@+id/record"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:src="@drawable/record" />
      
              <ImageButton
                  android:id="@+id/stop"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:src="@drawable/stop" />
          </LinearLayout>
      </RelativeLayout>

      提供了上面的所示的界面布局文件之后,接下来就可以在程序中使用MediaRecorder来录制视频了。录制视频与录制音频的步骤基本相似,只是需要额外设置视频的图像来源、视频格式等等。除此之外,还需要设置使用SurfaceView显示视频预览。

    • MainActivity.java逻辑代码如下:
      import android.app.Activity;
      import android.media.MediaRecorder;
      import android.os.Bundle;
      import android.os.Environment;
      import android.util.Log;
      import android.view.SurfaceView;
      import android.view.View;
      import android.view.View.OnClickListener;
      import android.widget.ImageButton;
      import android.widget.Toast;
      
      import java.io.File;
      
      public class MainActivity extends Activity implements OnClickListener {
      
          private static final String TAG = "MainActivity";
          // 程序中的两个按钮
          ImageButton record, stop;
          // 系统的视频文件
          File videoFile;
          MediaRecorder mRecorder;
          // 显示视频预览的SurfaceView
          SurfaceView sView;
          // 记录是否正在进行录制
          private boolean isRecording = false;
      
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              // 获取程序界面中的两个按钮
              record = (ImageButton) findViewById(R.id.record);
              stop = (ImageButton) findViewById(R.id.stop);
              // 让stop按钮不可用
              stop.setEnabled(false);
              // 为两个按钮的单击事件绑定监听器
              record.setOnClickListener(this);
              stop.setOnClickListener(this);
              // 获取程序界面中的SurfaceView
              sView = (SurfaceView) this.findViewById(R.id.sView);
              // 设置分辨率
              sView.getHolder().setFixedSize(1920, 1080);   // 1080P
              // 设置该组件让屏幕不会自动关闭
              sView.getHolder().setKeepScreenOn(true);
          }
      
          @Override
          public void onClick(View v) {
              // 单击录制按钮
              if (v.getId() == R.id.record) {
                  if (!Environment.getExternalStorageState().equals(
                          android.os.Environment.MEDIA_MOUNTED)) {
                      Toast.makeText(MainActivity.this, "SD卡不存在,请插入SD卡!", Toast.LENGTH_SHORT).show();
                      return;
                  }
                  try {
                      // 创建保存录制视频的视频文件
                      videoFile = new File(Environment.getExternalStorageDirectory()
                              .getCanonicalFile() + "/my_video.mp4");
                      // 创建MediaPlayer对象
                      mRecorder = new MediaRecorder();
                      mRecorder.reset();
                      // 设置从麦克风采集声音
                      mRecorder.setAudioSource(MediaRecorder
                              .AudioSource.MIC);
                      // 设置从摄像头采集图像
                      mRecorder.setVideoSource(MediaRecorder
                              .VideoSource.CAMERA);
                      // 设置视频文件的输出格式
                      // 必须在设置声音编码格式、图像编码格式之前设置
                      mRecorder.setOutputFormat(MediaRecorder
                              .OutputFormat.MPEG_4);
                      // 设置声音编码的格式
                      mRecorder.setAudioEncoder(MediaRecorder
                              .AudioEncoder.DEFAULT);
                      // 设置图像编码的格式
                      mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
                      mRecorder.setVideoSize(1920, 1080);  // 1080P
                      // 每秒16帧
                      mRecorder.setVideoFrameRate(16);
                      mRecorder.setOutputFile(videoFile.getAbsolutePath());
                      // 指定使用SurfaceView来预览视频
                      mRecorder.setPreviewDisplay(sView.getHolder().getSurface());  //
                      mRecorder.prepare();
                      // 开始录制
                      mRecorder.start();
                      Log.d(TAG, "---recording---");
                      // 让record按钮不可用
                      record.setEnabled(false);
                      // 让stop按钮可用
                      stop.setEnabled(true);
                      isRecording = true;
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              } else if (v.getId() == R.id.stop) {   // 单击停止按钮
                  // 如果正在进行录制
                  if (isRecording) {
                      // 停止录制
                      mRecorder.stop();
                      // 释放资源
                      mRecorder.release();
                      mRecorder = null;
                      // 让record按钮可用
                      record.setEnabled(true);
                      // 让stop按钮不可用
                      stop.setEnabled(false);
                  }
              }
          }
      }

      上面的代码设置了视频所采集的图像的来源,以及视频的压缩格式、视频分辨率等属性,标序号①的代码则用于设置使用指定SurfaceView显示指定视频预览。

    • 注意:由于该程序需要使用系统的麦克风进行录音、需要使用摄像头采集图像以及保存文件到外部存储卡,因此还需要在清单文件AndroidManifest.xml文件中授权相应的权限:
      <!-- 授予该程序录制声音的权限 -->
          <uses-permission android:name="android.permission.RECORD_AUDIO" />
          <!-- 授予该程序使用摄像头的权限 -->
          <uses-permission android:name="android.permission.CAMERA" />
          <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
          <!-- 授予使用外部存储器的权限 -->
          <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    • Demo程序运行效果界面截图如下:
    •  Demo程序源码下载地址

  • 相关阅读:
    一步一步实现自己的模拟控件(4)——根控件
    一步一步实现自己的模拟控件(6)——控件树及控件区域
    ATL COM初探(1)
    一步一步实现自己的模拟控件(2)——窗口过程thunk
    一步一步实现自己的模拟控件(3)——Widget驱动
    关于硬盘的一些知识
    Win32中TreeView控件的使用方法,类似于资源管理器中文件树形显示方式
    笔记本双系统XP与Ubuntu,重装XP后如何恢复grup引导,另附操作系统启动过程
    vim常用命令
    MFC中CListCtrl控件的使用方法
  • 原文地址:https://www.cnblogs.com/wangdayang/p/14913260.html
Copyright © 2020-2023  润新知