android camera2 详解说明(二)

2  录制视频短片

MediaRecorder除了可用于录制音频之外,还可用于录制视频。使用MediaRecorder录制视频与录制音频的步骤基本相同。只是录制视频时不仅需要采集声音,还需要采集图像。为了让MediaRecorder录制时采集图像,应该在调用setAudioSource(int audio_source)方法时再调用setVideoSource(int video_source)方法来设置图像来源。
除此之外,还需要在调用setOutputFormat()方法设置输出文件格式之后执行如下步骤。
file:///C:\Users\sxs\AppData\Local\Temp\msohtmlclip1\01\clip_image002.png 调用MediaRecorder对象的setVideoEncoder()、setVideoEncodingBitRate(int bitRate)、setVideoFrameRate()方法设置所录制的视频编码格式、编码位率、每秒多少帧等,这些参数可以控制所录制的视频品质、文件大小。一般来说,视频品质越好,视频文件越大。
file:///C:\Users\sxs\AppData\Local\Temp\msohtmlclip1\01\clip_image004.png 调用MediaRecorder的setPreviewDisplay(Surface sv)方法设置使用哪个SurfaceView来显示视频预览。
剩下的代码则与录制音频的代码基本相同。

实例:录制生活短片

本实例示范了如何录制视频。该程序的界面中提供了两个按钮用于控制开始、结束录制;除此之外,程序界面中还提供了一个SurfaceView来显示视频预览。该程序的界面布局文件如下。
程序清单:codes\11\3\RecordVideo\app\src\main\res\layout\main.xml
<?xml version="1.0"encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    androidrientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<!-- 显示视频预览的SurfaceView -->
<SurfaceView
    android:id="@+id/sView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
<LinearLayout
    androidrientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true">
    <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显示视频预览。录制视频的程序代码如下。
程序清单:codes\11\3\RecordVideo\app\src\main\java\org\crazyit\media\MainActivity.java
public class MainActivity extends Activity
    implementsOnClickListener
{
    // 程序中的两个按钮
    ImageButtonrecord , stop;
    // 系统的视频文件
    FilevideoFile ;
    MediaRecordermRecorder;
    // 显示视频预览的SurfaceView
   SurfaceView sView;
    // 记录是否正在进行录制
    privateboolean isRecording = false;
   @Override
    publicvoid onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.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);
        // 设置Surface不需要自己维护缓冲区
        sView.getHolder().setType(SurfaceHolder
        .SURFACE_TYPE_PUSH_BUFFERS);
        // 设置分辨率
        sView.getHolder().setFixedSize(320,280);
        // 设置该组件让屏幕不会自动关闭
        sView.getHolder().setKeepScreenOn(true);
    }
    @Override
    publicvoid onClick(View source)
    {
        switch(source.getId())
        {
            //单击录制按钮
            caseR.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() +"/myvideo.mp4");
                   // 创建MediaRecorder对象
                   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(320,280);
                   // 每秒 4
                    mRecorder.setVideoFrameRate(4);
                    mRecorder.setOutputFile(videoFile.getAbsolutePath());
                   // 指定使用SurfaceView来预览视频
                    mRecorder.setPreviewDisplay(sView
                        .getHolder().getSurface());  // 
                   mRecorder.prepare();
                   // 开始录制
                   mRecorder.start();
                   System.out.println("---recording---");
                   // record按钮不可用
                   record.setEnabled(false);
                   // stop按钮可用
                   stop.setEnabled(true);
                   isRecording = true;
               }
               catch (Exception e)
               {
                   e.printStackTrace();
               }
               break;
            //单击停止按钮
            caseR.id.stop:
                // 如果正在进行录制
               if (isRecording)
               {
                   // 停止录制
                   mRecorder.stop();
                   // 释放资源
                   mRecorder.release();
                   mRecorder = null;
                    // record按钮可用
                   record.setEnabled(true);
                   // stop按钮不可用
                   stop.setEnabled(false);
               }
               break;
        }
    }
}

 

上面程序中的粗体字代码设置了视频所采集的图像来源,以及视频的压缩格式、视频分辨率等属性,程序的①号粗体字代码则用于设置使用指定SurfaceView显示指定视频预览。
运行该程序需要使用麦克风录制声音,需要使用摄像头采集图像,这些都需要授予相应的权限;不仅如此,由于录制视频时视频文件增大得较快,可能需要使用外部存储器,因此需要对应用程序授予相应的权限,也就是需要在AndroidManifest.xml文件中增加如下授权配置:

 

<!-- 授予该程序录制声音的权限 -->
<uses-permissionandroid:name="android.permission.RECORD_AUDIO"/>
<!-- 授予该程序使用摄像头的权限 -->
<uses-permissionandroid:name="android.permission.CAMERA"/>
<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 授予使用外部存储器的权限 -->
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

当在Genymotion模拟器上运行该程序时,由于Genymotion模拟器可以直接使用宿主电脑上的摄像头作为相机摄像头,因此在该模拟器上运行该程序可以看到如图3所示的界面。
<ignore_js_op>
 
10.png
图3  录制视频短片

本文摘自《疯狂Android讲义(第2版)》

<ignore_js_op>
posted @ 2016-04-22 18:04  肾虚将军  阅读(1640)  评论(0编辑  收藏  举报