• 11.3.2 定制视频捕获的完整示例


         下面是将上述所有的步骤汇总在一起的完整示例。它使用了CamcorderProfile,因此需要Android 2.2或更高的版本。

     1 package com.nthm.androidtestActivity;
     2 
     3 import java.io.IOException;
     4 import com.nthm.androidtest.R;
     5 import android.app.Activity;
     6 import android.content.pm.ActivityInfo;
     7 import android.media.CamcorderProfile;
     8 import android.media.MediaRecorder;
     9 import android.os.Bundle;
    10 import android.os.Environment;
    11 import android.view.SurfaceHolder;
    12 import android.view.SurfaceView;
    13 import android.view.View;
    14 import android.view.View.OnClickListener;
    15 import android.view.Window;
    16 import android.view.WindowManager;

        在此示例中,活动将实现OnClickListener,使得用户可以单击以启动和停止录制;同时活动还将实现SurfaceHolder.Callback以处理与表面相关的事件。

    1 public class VideoCapture extends Activity implements OnClickListener,SurfaceHolder.Callback{
    2     private MediaRecorder recorder;
    3     private SurfaceHolder holder;

        我们使用一个布尔值来表示当前是否正在录制。当不在录制时它的值是false;而在录制时它的值是true。

    1     private boolean recording=false;
    2     @Override
    3     protected void onCreate(Bundle savedInstanceState) {
    4         super.onCreate(savedInstanceState);

        此活动将以全屏和横向模式运行,所以将使用下列方法对它进行设置。

    1         requestWindowFeature(Window.FEATURE_NO_TITLE);
    2         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    3         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        接下来将实例化MediaRecorder对象。

    1         recorder=new MediaRecorder();

        initRecorder方法(在后面定义)将处理所有的MediaRecorder设置。

    1         initRecorder();
    2         setContentView(R.layout.videocapture);

        接着,将获得指向SurfaceView和SurfaceHolder的引用,同时将活动注册为SurfaceHolder.Callback。

    1         SurfaceView cameraView=(SurfaceView) findViewById(R.id.CameraView);
    2         holder=cameraView.getHolder();
    3         holder.addCallback(this);
    4         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        设置SurfaceView为可单击,并将活动注册为它的OnClickListener。这样当触摸SurfaceView时,将调用活动的onClick方法。

    1         cameraView.setClickable(true);
    2         cameraView.setOnClickListener(this);
    3     }

        下面定义的initRecorder方法将处理所有的MediaRecorder设置。

    1     private void initRecorder(){

        我们将使用默认的音频和视频源。

    1         recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    2         recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);

        与指定所有单个的设置不同,我们将使用一个内置的CamcorderProfile设置——在当前情况下,其由QUALITY_HIGH常量指定。

    1         CamcorderProfile cpHigh=CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
    2         recorder.setProfile(cpHigh);

        需要指定录制到其中的文件路径。在当前的情况下,它是直接位于SD卡上的一个文件中。

    1         recorder.setOutputFile(Environment.getExternalStorageDirectory()+"/test.mp4");

        然后将以毫秒为单位指定最长持续时间。

    1         recorder.setMaxDuration(50000);

        最后将以字节为单位指定最大文件大小。

    1         recorder.setMaxFileSize(5000000);
    2     }

        下面的prepareRecorder方法将setPreviewDisplay方法与其余的MediaRecorder方法分离开来。之所以这么做,是因为需要在创建表面之后执行这个步骤,而其他步骤可以在实例化MediaRecorder之后或者在它已停止之后的任何时候执行。

    1     private void prepareRecorder(){
    2         recorder.setPreviewDisplay(holder.getSurface());

        在设置预览显示之后,可以调用MediaRecorder对象上的preapre方法。这个步骤为捕获操作做好准备。必须将该步骤包装在一个try/catch块中,因为它会抛出一些异常。如果得到任何异常,那么本活动将仅仅是结束。在你的应用程序中,你可能希望更合理的处理他们。

     1         try {
     2             recorder.prepare();
     3         } catch (IllegalStateException e) {
     4             e.printStackTrace();
     5             finish();
     6         } catch (IOException e) {
     7             e.printStackTrace();
     8             finish();
     9         }
    10     }

        当单击SurfaceView时,将调用活动的onClick方法。

    1     @Override
    2     public void onClick(View v) {

        如果recording布尔值为true,那么将调用recording对象上的stop方法,并设置recording布尔值为false。另外,如果完成了MediaRecorder的使用,那么应该调用release方法以释放它的资源,因为每次只有一个应用程序可以使用这些资源。

    1            if(recording){
    2                recorder.stop();
    3                //recorder.release();
    4                recording=false;

        此示例需要允许用户再次录制,因此将调用initRecorder和prepareRecorder方法重置所有的内容。之所以这么做,是因为在使用stop方法停止录制之后,其状态就和刚刚初始化一样,因此不会再次准备好录制。

    1                //调用initRecorder,从而可以重新录制
    2                initRecorder();
    3                prepareRecorder();
    4            }else{

        如果recording布尔值为false,那么将调用MediaRecorder上的start方法,并更新该布尔值。

    1                recording=true;
    2                recorder.start();
    3            }
    4     }

        正如之前所述,一旦创建表面,就调用prepareRecorder方法。

     1     @Override
     2     public void surfaceCreated(SurfaceHolder holder) {
     3         prepareRecorder();
     4     }
     5 
     6     @Override
     7     public void surfaceChanged(SurfaceHolder holder, int format, int width,
     8             int height) {
     9         
    10     }

        当销毁表面时,如果正在录制,那么停止录制。这可能会在活动不再可见时发生。由于MediaRecorder使用共享资源,如摄像头和麦克风,因此会调用release方法,以便其他应用程序可以使用他们。此外,没有理由需要保持这个应用程序继续运行;可以调用finish方法,从而当该应用程序下次启动时重新初始化所有内容。

     1     @Override
     2     public void surfaceDestroyed(SurfaceHolder holder) {
     3         if(recording){
     4             recorder.stop();
     5             recording=false;
     6         }
     7         recorder.release();
     8         finish();
     9     }
    10 }

        下面用于上述活动的布局XML。

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:orientation="vertical"
     5     >
     6  <SurfaceView 
     7      android:id="@+id/CameraView"
     8      android:layout_width="640px"
     9      android:layout_height="480px"/>
    10 </LinearLayout>

         下面是本示例中需要的权限:

    1     <uses-permission android:name="android.permission.CAMERA"/>
    2     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    3     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

        编写一个应用程序以执行定制视频捕获并不是十分的困难,但是如果没有注意表面的创建和步骤的顺序,那么它可能会面临一些困难。创建自己的应用程序将在更改设置方面获得很大的灵活性,例如编解码器、比特率和用于录制的格式等。

       

  • 相关阅读:
    TCP/IP 协议体系结构模型
    A*算法详解
    导航规划之CH算法介绍
    Crp(customizable route planning) 算法介绍
    机器学习面试题总结(笔记)
    机器学习面试问题总结
    机器学习面试常见问题
    seata-微服务集成seata
    seata-部署seata连接nacos
    Sentinel授权规则-规则管理三种模式
  • 原文地址:https://www.cnblogs.com/ZSS-Android/p/3962395.html
Copyright © 2020-2023  润新知