MediaRecorder简介

  • MediaRecoder主要方法
  • AudioSource及AudioEncoder
  • VideoSource及VideoEncoder
  • OutputFormat
  • 启动和停止MediaRecorder
  • 示例代码


MediaRecoder主要方法

  • void prepar():准备录制
  • void start():开始录制
  • void stop():停止录制
  • void reset():重置MediaRecorder
  • void release():释放MediaRecorder占用的资源
  • void setAudioEncoder(int):设置音频的编码格式
  • void setAudioSource(int):设置音频的音频源
  • void setVideoEncoder(int):设置视频的编码格式
  • void setVideoSource(int):设置视频的视频源
  • void setOutoutFormat(int):设置记录的媒体文件的输出转换格式
  • void setOutputFile(String):设置媒体文件输出路径

主要的方法有上面部分,其中关于设置录制参数的部分。有一个封装好的方法
public void setProfile(CamcorderProfile profile)

public void setProfile(CamcorderProfile profile) {
        setOutputFormat(profile.fileFormat);
        setVideoFrameRate(profile.videoFrameRate);
        setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
        setVideoEncodingBitRate(profile.videoBitRate);
        setVideoEncoder(profile.videoCodec);
        if (profile.quality >= CamcorderProfile.QUALITY_TIME_LAPSE_LOW &&
             profile.quality <= CamcorderProfile.QUALITY_TIME_LAPSE_QVGA) {
            // Nothing needs to be done. Call to setCaptureRate() enables
            // time lapse video recording.
        } else {
            setAudioEncodingBitRate(profile.audioBitRate);
            setAudioChannels(profile.audioChannels);
            setAudioSamplingRate(profile.audioSampleRate);
            setAudioEncoder(profile.audioCodec);
        }
    }

我们也可以使用这个方法来设置录制参数,其中CamcorderProfile对象可以根据视频的质量直接获取。在系统中是通过MediaProfiles.cpp去查询xmlFiles数组内文件media_profiles_V1_0.xml中的内容,然后解析后获取的。

我们通过从CamcorderProfile获取到的需要设置的参数要详细很多,CamcorderProfile 管理的配置信息包括:
fileFormat:文件输出格式
videoCodec:视频编解码格式
videoBitRate:视频比特率,以位/秒为单位
videoFrameRate:视频帧速率(以每秒帧数为单位)
videoFrameWidth,videoFrameHeight:视频帧宽和高度,
audioCodec:音频编解码格式
audioBitRate:音频比特率,以位/秒为单位,录制的音频通道数。
audioSampleRate:音频采样率
audioChannels:音频声道数

AudioSource及AudioEncoder

AudioSource:

  • DEFAULT 默认音频源
  • MIC 录音来源为主麦克风
  • VOICE_UPLINK/VOICE_DOWNLINK 上行下行的语音,需要Manifest.permission.CAPTURE_AUDIO_OUTPUT权限,第三方应用无法申请
  • VOICE_CALL 呼叫上行下行的语音,需要Manifest.permission.CAPTURE_AUDIO_OUTPUT权限,第三方应用无法申请
  • CAMCORDER 录音来源于同方向的相机麦克风相同,若相机无内置相机或无法识别,则使用预设的麦克风
  • VOICE_RECOGNITION 用于获取语音进行语音识别
  • VOICE_COMMUNICATION 麦克风音频源针对VoIP等语音通信进行了调整,可以接收到通话的双方语音
  • REMOTE_SUBMIX 用于远程呈现的音频流的子混音的音频源,需要Manifest.permission.CAPTURE_AUDIO_OUTPUT权限,第三方应用无法申请
  • UNPROCESSED 与默认相同
  • RADIO_TUNER 用于捕获广播电台调谐器输出的音频源。

AudioEncoder:

public static final int DEFAULT = 0;
    
    /** AMR (Narrowband) audio codec */
    //自适应多速率窄带语音编码,广泛应用于移动通信领域
    public static final int AMR_NB = 1;
    
    /** AMR (Wideband) audio codec */
    //是新型可变速率多模式宽带语音编解码器,专为无线 CDMA 2000标准而设计,目的在于在 50 至 7000 HZ 的频带上进行语音编码,采样率为 16 KH,可以获得较高质量的合成语音
    public static final int AMR_WB = 2;
    
    /** AAC Low Complexity (AAC-LC) audio codec */
    //Advanced Audio Coding(高级音频解码),是一种由MPEG-4标准定义的有损音频
    public static final int AAC = 3;		
    
    /** High Efficiency AAC (HE-AAC) audio codec */
    public static final int HE_AAC = 4;
    
    /** Enhanced Low Delay AAC (AAC-ELD) audio codec */
    public static final int AAC_ELD = 5;
    
    /** Ogg Vorbis audio codec */
    //一种有损压缩格式
    public static final int VORBIS = 6;

VideoSource及VideoEncoder

VideoSource:

  • DEFAULT
  • CAMERA Camera video source 使用Camera的API
  • SURFACE Surface video source使用Camera2的API,需要通过MediaRecorder getSurface()

VideoEncoder:

public static final int DEFAULT = 0;
        
        //1995年,ITU-T针对低比特率视频应用制定了H.263标准,H263经常被用于3gp的container format
        public static final int H263 = 1;
        
        //2001年12月,ITU-T和ISO联合制定一个新的视频编码标准。H264,或者叫AVC以及MPEG-4第10部分
        public static final int H264 = 2;
        
        //MPEG4-SP是一种特殊的简单MPEG4实现,SP代表simple profile
        public static final int MPEG_4_SP = 3;
        
        //Google推出的
        public static final int VP8 = 4;
        
        //也就是H265
        public static final int HEVC = 5;

OutputFormat

用于在MediaRecorder.java中定义要求和mediarecorder.h中的保持一致。目前Android中支持的有如下容器格式,其中有支持视频的和只支持音频的

public final class OutputFormat {
      /* Do not change these values without updating their counterparts
       * in include/media/mediarecorder.h!
       */
        private OutputFormat() {}
        public static final int DEFAULT = 0;
        /** 3GPP media file format*/
        public static final int THREE_GPP = 1;
        /** MPEG4 media file format*/
        public static final int MPEG_4 = 2;		

        /** The following formats are audio only .aac or .amr formats */

        /**
         * AMR NB file format
         * @deprecated  Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB
         */
        public static final int RAW_AMR = 3;

        /** AMR NB file format */
        public static final int AMR_NB = 3;

        /** AMR WB file format */
        public static final int AMR_WB = 4;

        /** @hide AAC ADIF file format */
        public static final int AAC_ADIF = 5;

        /** AAC ADTS file format */
        public static final int AAC_ADTS = 6;

        /** @hide Stream over a socket, limited to a single stream */
        public static final int OUTPUT_FORMAT_RTP_AVP = 7;

        /** H.264/AAC data encapsulated in MPEG2/TS */
        public static final int MPEG_2_TS = 8;

        /** VP8/VORBIS data in a WEBM container */
        public static final int WEBM = 9;
    };

启动和停止MediaRecorder

使用 MediaRecorder 类开始和停止视频录制时,您必须严格按照下列特定顺序执行操作。

  1. 使用 Camera.unlock() 解锁相机
  2. 配置 MediaRecorder,如上述代码示例所示
  3. 使用MediaRecorder.start() 开始录制
  4. 录制视频
  5. 使用 MediaRecorder.stop() 停止录制
  6. 使用MediaRecorder.release() 释放媒体录制器
  7. 使用 Camera.lock() 锁定相机

下图是一个状态机图

MediaRecorder start在哪里定义 media removed_Source


MediaRecorder要严格遵守各个状态之间的变化,否则会出错:

  • Initial:初始状态,创建一个新的MediaRecorder对象或者调用了reset()方法时,MediaRecorder对象处于Initial状态。通过调用reset()方法都可以使MediaRecorder进入Initial状态。在设定视频源或者音频源之后将转换为Initialized状态。
  • Initialized:已初始化状态,在Initial状态下调用setAudioSource()或setVideoSource()方法会转变成Initialized状态。这个状态可以通过setOutputFormat()方法设置输出格式,此时MediaRecorder转换为DataSourceConfigured状态。
  • DataSourceConfigured:数据源配置状态,这个状态下可以设定编码方式、输出文件、屏幕旋转、预览显示等等。可以在Initialized状态通过setOutputFormat()方法进入该状态。这个状态下可以通过reset()方法回到Initial状态,或者通过prepare()方法到达Prepared状态。
  • Prepared:就绪状态,在DataSourceConfigured状态通过prepare()方法进入该状态。在这个状态可以通过start()进入录制状态。
  • Recording:录制状态,可以在Prepared状态通过调用start()方法进入该状态。它可以通过stop()方法或reset()方法回到Initial状态。
  • Released:释放状态也叫作Idle state空闲状态,可以通过在Initial状态调用release()方法来进入这个状态,这时将会释放所有和MediaRecorder对象绑定的资源。
  • Error:错误状态,当错误发生的时候进入这个状态,可以通过调用reset()方法进入Initial状态

示例代码

配置 MediaRecorder,当使用 MediaRecorder 类录制视频时,必须按指定顺序执行配置步骤,然后调用 MediaRecorder.prepare() 方法来检查并实现配置。以下示例代码演示如何正确配置和准备用于录制视频的 MediaRecorder 类

private boolean prepareVideoRecorder(){

    mCamera = getCameraInstance();
    mediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // Step 4: Set output file
    mediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // Step 5: Set the preview output
    mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: Prepare configured MediaRecorder
    try {
        mediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}

这里主要是简单的介绍了一下MediaRecorder,下一篇MediaRecorder录制流程