android camera2 详解说明(二)

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版)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值