Android--MediaRecorder录音录像

简介:

MediaRecorder

  MediaRecorder主要用于记录音频与视频,它位于"android.media.MediaRecorder"下。它为开发人员提供了详尽的AIP以完成记录音频与视频的工作,下面简单介绍一些常用的。

  • void prepar():准备录制。
  • void start():开始录制。
  • void stop():停止录制。
  • void reset():重置MediaRecorder。
  • void release():释放MediaRecorder占用的资源。
  • void setAudioEncoder(int):设置音频记录的编码格式。
  • void setAudoSource(int):设置音频记录的音频源。
  • void setOutoutFormat(int):设置记录的媒体文件的输出转换格式。
  • void setPreviewDisplay(Surface):设置视频的预览界面。
  • void setVideoEncoder(int):设置视频记录的编码格式。
  • void setVideoSource(int):设置视频记录的视频源。
  • void setOutputFile(String):媒体文件输出路径。
  • void setMaxDuration(int):设置最大记录时长,单位为毫秒。

  上面仅仅列出了一些常用的方法,但是通过这个方法可以看出MediaRecorder是需要在多个状态之间切换的,准备、开始、停止、重置等等。MediaRecorder也为我们提供了一套状态切换的规则,只有在既定的状态下,才能完成对应的操作,下图是官方文档提供的状态图。

  上图非常直观的展示了MediaRecorder的状态间的转换,这里只说几点需要注意的地方:

  • 当为MediaRecorder设定媒体录入源之后即初始化完成,这个时候才可以为其设定其他的参数。
  • 在开始录制前必须先调用prepare()准备录制。
  • 只有在Initial初始化状态,才可以对MediaRecorder调用release()释放资源,其他状态必须先stop()或者reset()。
  • 错误状态是游离在所有状态之外的,当发生错误的时候,只有进行reset()才会进入Initial初始状态。

 

  MediaRecorder录制视频必不可少的步骤:

  1. 调用new MediaRecorder()构造函数得到MediaRecorder的实例。
  2. 调用setOutputFormat()设定媒体文件的输出格式,必须在设定音频与视频的编码格式之前设定。
  3. 如果需要记录音频,则调用setAudioSource()设定音频的录入源以及调用setAudioEncoder()设定音频的编码方式。
  4. 如果需要记录视频,则调用setVideoSource()设定视频的录入员以及调用setVideoEncoder()设定视频的编码方式。
  5. 调用setOutputFile()设定记录的媒体文件保存的路径。
  6. 先调用prepare()准备录制,准备完成之后调用start()开始录制。
  7. 记录完成后,调用stop()停止录制。

  

MediaRecorder录制音频

  上面介绍了使用MediaRecorder录制视频必不可少的步骤,因为录制音频无需捕获图像,所以更简单一些。下面直接通过一个简单的示例,演示如何录制音频,录制的音频文件保存在sd根目录下,注释很详细,这里不在累述了。布局很简单,只有两个Button,开始录音、结束录音,就不提供布局代码了。

  实现代码:

 

复制代码
  1 package cn.bgxt.mediarecorderdemo;
  2 
  3 import java.io.File;
  4 import android.app.Activity;
  5 import android.media.MediaRecorder;
  6 import android.media.MediaRecorder.OnErrorListener;
  7 import android.os.Bundle;
  8 import android.view.View;
  9 import android.view.View.OnClickListener;
 10 import android.widget.Button;
 11 import android.widget.Toast;
 12 
 13 public class RecordActivity extends Activity {
 14     private Button btn_RecordStart, btn_RecordStop;
 15     private MediaRecorder mediaRecorder;
 16     private boolean isRecording;
 17     @Override
 18     protected void onCreate(Bundle savedInstanceState) {
 19         // TODO Auto-generated method stub
 20         super.onCreate(savedInstanceState);
 21         setContentView(R.layout.activity_record);
 22 
 23         btn_RecordStart = (Button) findViewById(R.id.btn_RecordStart);
 24         btn_RecordStop = (Button) findViewById(R.id.btn_RecordStop);
 25         
 26         btn_RecordStop.setEnabled(false);
 27         
 28         btn_RecordStart.setOnClickListener(click);
 29         btn_RecordStop.setOnClickListener(click);
 30     }
 31 
 32     private View.OnClickListener click = new OnClickListener() {
 33 
 34         @Override
 35         public void onClick(View v) {
 36             switch (v.getId()) {
 37             case R.id.btn_RecordStart:
 38                 start();
 39                 break;
 40             case R.id.btn_RecordStop:
 41                 stop();
 42                 break;
 43             default:
 44                 break;
 45             }
 46         }
 47     };
 48 
 49     /**
 50      * 开始录音
 51      */
 52     protected void start() {
 53         try {
 54             File file = new File("/sdcard/mediarecorder.amr");
 55             if (file.exists()) {
 56                 // 如果文件存在,删除它,演示代码保证设备上只有一个录音文件
 57                 file.delete();
 58             }
 59             mediaRecorder = new MediaRecorder();
 60             // 设置音频录入源
 61             mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 62             // 设置录制音频的输出格式
 63             mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
 64             // 设置音频的编码格式
 65             mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
 66             // 设置录制音频文件输出文件路径
 67             mediaRecorder.setOutputFile(file.getAbsolutePath());
 68 
 69             mediaRecorder.setOnErrorListener(new OnErrorListener() {
 70                 
 71                 @Override
 72                 public void onError(MediaRecorder mr, int what, int extra) {
 73                     // 发生错误,停止录制
 74                     mediaRecorder.stop();
 75                     mediaRecorder.release();
 76                     mediaRecorder = null;
 77                     isRecording=false;
 78                     btn_RecordStart.setEnabled(true);
 79                     btn_RecordStop.setEnabled(false);
 80                     Toast.makeText(RecordActivity.this, "录音发生错误", 0).show();
 81                 }
 82             });
 83             
 84             // 准备、开始
 85             mediaRecorder.prepare();
 86             mediaRecorder.start();
 87             
 88             isRecording=true;
 89             btn_RecordStart.setEnabled(false);
 90             btn_RecordStop.setEnabled(true);
 91             Toast.makeText(RecordActivity.this, "开始录音", 0).show();
 92         } catch (Exception e) {
 93             e.printStackTrace();
 94         }
 95     }
 96 
 97     /**
 98      * 录音结束
 99      */
100     protected void stop() {
101         if (isRecording) {
102             // 如果正在录音,停止并释放资源
103             mediaRecorder.stop();
104             mediaRecorder.release();
105             mediaRecorder = null;
106             isRecording=false;
107             btn_RecordStart.setEnabled(true);
108             btn_RecordStop.setEnabled(false);
109             Toast.makeText(RecordActivity.this, "录音结束", 0).show();
110         }
111     }
112 
113     @Override
114     protected void onDestroy() {
115         if (isRecording) {
116             // 如果正在录音,停止并释放资源
117             mediaRecorder.stop();
118             mediaRecorder.release();
119             mediaRecorder = null;
120         }
121         super.onDestroy();
122     }
123 
124 }
复制代码

  录制音频需要访问麦克风设备,访问设备需要添加权限:

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

  效果展示:

 

MediaRecorder录制视频

  上面已经介绍了使用MediaRecorder录制视频的步骤,这里依照步骤一步一步写代码就可以了。下面通过一个简单的Demo演示如何使用MediaRecorder录制一段从摄像头捕获到的视频,录制的视频文件将保持在SD卡上。布局很简单,两个Button,开始、停止,然后还有一个SurfaceView显示预览效果,就不给出布局代码了。

  实现代码:

复制代码
  1 package cn.bgxt.mediarecorderdemo;
  2 
  3 import java.io.File;
  4 import java.io.IOException;
  5 
  6 import android.app.Activity;
  7 import android.media.MediaRecorder;
  8 import android.media.MediaRecorder.OnErrorListener;
  9 import android.os.Bundle;
 10 import android.view.SurfaceHolder;
 11 import android.view.SurfaceView;
 12 import android.view.View;
 13 import android.view.View.OnClickListener;
 14 import android.widget.Button;
 15 import android.widget.Toast;
 16 
 17 public class VideoActivity extends Activity {
 18     private Button btn_VideoStart, btn_VideoStop;
 19     private SurfaceView sv_view;
 20     private boolean isRecording;
 21     private MediaRecorder mediaRecorder;
 22 
 23     @Override
 24     protected void onCreate(Bundle savedInstanceState) {
 25         super.onCreate(savedInstanceState);
 26         setContentView(R.layout.activity_video);
 27 
 28         btn_VideoStart = (Button) findViewById(R.id.btn_VideoStart);
 29         btn_VideoStop = (Button) findViewById(R.id.btn_VideoStop);
 30         sv_view = (SurfaceView) findViewById(R.id.sv_view);
 31 
 32         btn_VideoStop.setEnabled(false);
 33 
 34         btn_VideoStart.setOnClickListener(click);
 35         btn_VideoStop.setOnClickListener(click);
 36         
 37         // 声明Surface不维护自己的缓冲区,针对Android3.0以下设备支持
 38         sv_view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 39     }
 40 
 41     private View.OnClickListener click = new OnClickListener() {
 42 
 43         @Override
 44         public void onClick(View v) {
 45             switch (v.getId()) {
 46             case R.id.btn_VideoStart:
 47                 start();
 48                 break;
 49             case R.id.btn_VideoStop:
 50                 stop();
 51                 break;
 52             default:
 53                 break;
 54             }
 55         }
 56     };
 57 
 58     protected void start() {
 59         try {
 60             File file = new File("/sdcard/video.mp4");
 61             if (file.exists()) {
 62                 // 如果文件存在,删除它,演示代码保证设备上只有一个录音文件
 63                 file.delete();
 64             }
 65             
 66             mediaRecorder = new MediaRecorder();
 67             mediaRecorder.reset();
 68             // 设置音频录入源
 69             mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 70             // 设置视频图像的录入源
 71             mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
 72             // 设置录入媒体的输出格式
 73             mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
 74             // 设置音频的编码格式
 75             mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
 76             // 设置视频的编码格式
 77             mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
 78             // 设置视频的采样率,每秒4帧
 79             mediaRecorder.setVideoFrameRate(4);
 80             // 设置录制视频文件的输出路径
 81             mediaRecorder.setOutputFile(file.getAbsolutePath());
 82             // 设置捕获视频图像的预览界面
 83             mediaRecorder.setPreviewDisplay(sv_view.getHolder().getSurface());
 84             
 85             mediaRecorder.setOnErrorListener(new OnErrorListener() {
 86                 
 87                 @Override
 88                 public void onError(MediaRecorder mr, int what, int extra) {
 89                     // 发生错误,停止录制
 90                     mediaRecorder.stop();
 91                     mediaRecorder.release();
 92                     mediaRecorder = null;
 93                     isRecording=false;
 94                     btn_VideoStart.setEnabled(true);
 95                     btn_VideoStop.setEnabled(false);
 96                     Toast.makeText(VideoActivity.this, "录制出错", 0).show();
 97                 }
 98             });
 99             
100             // 准备、开始
101             mediaRecorder.prepare();
102             mediaRecorder.start();
103 
104             btn_VideoStart.setEnabled(false);
105             btn_VideoStop.setEnabled(true);
106             isRecording = true;
107             Toast.makeText(VideoActivity.this, "开始录像", 0).show();
108         } catch (Exception e) {
109             e.printStackTrace();
110         }
111 
112     }
113 
114     protected void stop() {
115         if (isRecording) {
116             // 如果正在录制,停止并释放资源
117             mediaRecorder.stop();
118             mediaRecorder.release();
119             mediaRecorder = null;
120             isRecording=false;
121             btn_VideoStart.setEnabled(true);
122             btn_VideoStop.setEnabled(false);
123             Toast.makeText(VideoActivity.this, "停止录像,并保存文件", 0).show();
124         }
125     }
126 
127     @Override
128     protected void onDestroy() {
129         if (isRecording) {
130             mediaRecorder.stop();
131             mediaRecorder.release();
132             mediaRecorder = null;
133         }
134         super.onDestroy();
135     }
136 
137 }
复制代码

  录制视频需要用到麦克风和摄像头硬件,还需要赋予一些相应的权限。

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

  效果展示:

 

MediaRecorder的内部类

  通过上面录制视频的Demo可以看出,使用MediaRecorder录制视频,需要设置一些录入源、编码格式、输出格式等。这些方法都是以int类型的参数设定的,它们其实都是在MediaRecorder的内部类中已经以常量的形式定义好了,直接适用场景进行选择即可。

  • MediaRecorder.AudioEncoder:音频的编码格式。
  • MediaRecorder.AudioSource:录制的音频源。
  • MediaRecorder.OutputFormat:媒体文件的输出编码格式。
  • MediaRecorder.VideoEncoder:视频的编码格式。
  • MediaRecorder.VideoSource:录制的视频源。

 


本文转自承香墨影博客园博客,原文链接:http://www.cnblogs.com/plokmju/p/android_MediaRecorder.html,如需转载请自行联系原作者


相关文章
|
Android开发 开发者 UED
Android平台RTMP推送端实现外部数据对接推送和录像
好多开发者在做Android平台RTMP推送对接的同时,除了编码前的数据外,还有些外部编码数据推送诉求,他们希望外部的编码音视频数据不止可以实现RTMP推送,还可以同时在推送端实时录制下来,本文以我们(官方)Android平台RTMP直播推送模块为例,介绍下外部数据对接流程和数据录制流程。
106 0
|
Android开发 开发者
Android平台GB28181设备接入端如何实现本地录像?
实现Android平台GB28181设备接入的时候,有个功能点不可避免,那就是本地录像,实际上,在实现GB28181设备接入模块之前,我们前些年做RTMP推送和轻量级RTSP服务的时候,早已经实现了本地录像功能。
103 0
|
6月前
|
XML Java Android开发
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
Android Studio App开发中使用录音机、MediaRecorder录制音频和MediaPlayer播放音频讲解及实战(附源码)
208 0
|
3月前
|
开发工具 Android开发 开发者
Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?
本文介绍了一种在Android平台上实现实时截图快照的方法,尤其适用于无需依赖系统接口的情况,如在RTMP推送、RTSP服务或GB28181设备接入等场景下进行截图。通过底层模块(libSmartPublisher.so)实现了截图功能,封装了`SnapShotImpl.java`类来管理截图流程。此外,提供了关键代码片段展示初始化SDK实例、执行截图、以及在Activity销毁时释放资源的过程。此方案还考虑到了快照数据的灵活处理需求,符合GB/T28181-2022的技术规范。对于寻求更灵活快照机制的开发者来说,这是一个值得参考的设计思路。
|
2月前
|
Android开发 开发者
Android平台无纸化同屏如何实现实时录像功能
Android平台无纸化同屏,如果需要本地录像的话,实现难度不大,只要复用之前开发的录像模块的就可以,对我们来说,同屏采集这块,只是数据源不同而已,如果是自采集的其他数据,我们一样可以编码录像。
|
6月前
|
XML 存储 Java
Android 开发音频录播中媒体录制器MediaRecorder和媒体播放器MediaPlayer的讲解及实战(超详细 附源码)
Android 开发音频录播中媒体录制器MediaRecorder和媒体播放器MediaPlayer的讲解及实战(超详细 附源码)
113 0
|
编解码 Java 开发工具
[技术分享]Android平台实时音视频录像模块设计之道
录像有什么难的?无非就是数据过来,编码保存mp4而已,这可能是好多开发者在做录像模块的时候的思考输出。是的,确实不难,但是做好,或者和其他模块有非常好的逻辑配合,确实不容易。
105 0
|
编解码 Android开发 开发者
Android平台GB28181设备接入模块如何实现实时视频和本地录像双码流编码
我们在做Android平台GB28181设备接入模块的时候,遇到这样的场景,比如执法记录仪或智慧工地等场景下,由于GB28181设备接入模块,注册到国标平台后,平时只是心跳保持,或还有实时位置订阅,查看视频的时候,是按需看,而且有时候,网络环境并不是太好,所以,催生了这样一个诉求:部分开发者希望能本地录像的时候,录制高分辨率(比如1920*1080),国标平台侧发起实时视频查看请求的时候,上传低分辨率(如1280*720)数据,有点类似于IPC的主码流和子码流。
|
Android开发
|
算法 测试技术 Android开发