前言

  Android除了支持播放多媒体文件之外,还可以从对应的硬件中捕获多媒体,比如从麦克风录音、从摄像头录像等。本篇博客讲解一下Android下如何通过MediaRecorder进行录音以及录像的步骤,最后将以简单的Demo演示。

  本篇博客的主要内容:

  1. MediaRecorder
  2. MediaRecorder录制音频
  3. MediaRecorder录制视频
  4. 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,开始录音、结束录音,就不提供布局代码了。

  实现代码:

 package cn.bgxt.mediarecorderdemo;

 import java.io.File;
import android.app.Activity;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; public class RecordActivity extends Activity {
private Button btn_RecordStart, btn_RecordStop;
private MediaRecorder mediaRecorder;
private boolean isRecording;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record); btn_RecordStart = (Button) findViewById(R.id.btn_RecordStart);
btn_RecordStop = (Button) findViewById(R.id.btn_RecordStop); btn_RecordStop.setEnabled(false); btn_RecordStart.setOnClickListener(click);
btn_RecordStop.setOnClickListener(click);
} private View.OnClickListener click = new OnClickListener() { @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_RecordStart:
start();
break;
case R.id.btn_RecordStop:
stop();
break;
default:
break;
}
}
}; /**
* 开始录音
*/
protected void start() {
try {
File file = new File("/sdcard/mediarecorder.amr");
if (file.exists()) {
// 如果文件存在,删除它,演示代码保证设备上只有一个录音文件
file.delete();
}
mediaRecorder = new MediaRecorder();
// 设置音频录入源
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 设置录制音频的输出格式
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 设置音频的编码格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// 设置录制音频文件输出文件路径
mediaRecorder.setOutputFile(file.getAbsolutePath()); mediaRecorder.setOnErrorListener(new OnErrorListener() { @Override
public void onError(MediaRecorder mr, int what, int extra) {
// 发生错误,停止录制
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
isRecording=false;
btn_RecordStart.setEnabled(true);
btn_RecordStop.setEnabled(false);
Toast.makeText(RecordActivity.this, "录音发生错误", 0).show();
}
}); // 准备、开始
mediaRecorder.prepare();
mediaRecorder.start(); isRecording=true;
btn_RecordStart.setEnabled(false);
btn_RecordStop.setEnabled(true);
Toast.makeText(RecordActivity.this, "开始录音", 0).show();
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 录音结束
*/
protected void stop() {
if (isRecording) {
// 如果正在录音,停止并释放资源
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
isRecording=false;
btn_RecordStart.setEnabled(true);
btn_RecordStop.setEnabled(false);
Toast.makeText(RecordActivity.this, "录音结束", 0).show();
}
} @Override
protected void onDestroy() {
if (isRecording) {
// 如果正在录音,停止并释放资源
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
super.onDestroy();
} }

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

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

  效果展示:

MediaRecorder录制视频

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

  实现代码:

 package cn.bgxt.mediarecorderdemo;

 import java.io.File;
import java.io.IOException; import android.app.Activity;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnErrorListener;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; public class VideoActivity extends Activity {
private Button btn_VideoStart, btn_VideoStop;
private SurfaceView sv_view;
private boolean isRecording;
private MediaRecorder mediaRecorder; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video); btn_VideoStart = (Button) findViewById(R.id.btn_VideoStart);
btn_VideoStop = (Button) findViewById(R.id.btn_VideoStop);
sv_view = (SurfaceView) findViewById(R.id.sv_view); btn_VideoStop.setEnabled(false); btn_VideoStart.setOnClickListener(click);
btn_VideoStop.setOnClickListener(click); // 声明Surface不维护自己的缓冲区,针对Android3.0以下设备支持
sv_view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} private View.OnClickListener click = new OnClickListener() { @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_VideoStart:
start();
break;
case R.id.btn_VideoStop:
stop();
break;
default:
break;
}
}
}; protected void start() {
try {
File file = new File("/sdcard/video.mp4");
if (file.exists()) {
// 如果文件存在,删除它,演示代码保证设备上只有一个录音文件
file.delete();
} mediaRecorder = new MediaRecorder();
mediaRecorder.reset();
// 设置音频录入源
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 设置视频图像的录入源
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 设置录入媒体的输出格式
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// 设置音频的编码格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
// 设置视频的编码格式
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
// 设置视频的采样率,每秒4帧
mediaRecorder.setVideoFrameRate(4);
// 设置录制视频文件的输出路径
mediaRecorder.setOutputFile(file.getAbsolutePath());
// 设置捕获视频图像的预览界面
mediaRecorder.setPreviewDisplay(sv_view.getHolder().getSurface()); mediaRecorder.setOnErrorListener(new OnErrorListener() { @Override
public void onError(MediaRecorder mr, int what, int extra) {
// 发生错误,停止录制
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
isRecording=false;
btn_VideoStart.setEnabled(true);
btn_VideoStop.setEnabled(false);
Toast.makeText(VideoActivity.this, "录制出错", 0).show();
}
}); // 准备、开始
mediaRecorder.prepare();
mediaRecorder.start(); btn_VideoStart.setEnabled(false);
btn_VideoStop.setEnabled(true);
isRecording = true;
Toast.makeText(VideoActivity.this, "开始录像", 0).show();
} catch (Exception e) {
e.printStackTrace();
} } protected void stop() {
if (isRecording) {
// 如果正在录制,停止并释放资源
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
isRecording=false;
btn_VideoStart.setEnabled(true);
btn_VideoStop.setEnabled(false);
Toast.makeText(VideoActivity.this, "停止录像,并保存文件", 0).show();
}
} @Override
protected void onDestroy() {
if (isRecording) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
super.onDestroy();
} }

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

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

  效果展示:

MediaRecorder的内部类

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

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

  源码下载

Android--MediaRecorder录音录像的更多相关文章

  1. Android MediaRecorder解析

    源码路径:frameworks/base/media/java/android/media/MediaRecorder.javaframeworks/base/media/jni/android_me ...

  2. Android MediaRecorder自定义分辨率

    Android MediaRecorder自定义分辨率 工作这么久了,确实积累了不少东西,但都是以文档的形式存在U盘里的,为什么不写博客呢?因为懒啊!!!总感觉博客太难写了(大概是上学时候写作文恐惧症 ...

  3. Android MediaRecorder录制音频

    今天介绍一下在Android中怎么录制音频,在Android中使用MediaRecorder来录制音频,步骤: 1.创建MediaRecorder对象. 2.调用MediaRecorder对象的set ...

  4. Android MediaRecorder实现暂停断点录音功能

    基本原理如下:MediaRecorder通过MIC录音,系统没有自带的pause功能,每次暂停录音,都会结束本次的录音.现在本人的设计思路是:MediaRecorder录音暂停时,保存这段所录下的音频 ...

  5. Android MediaRecorder录音与播放

    上一篇讲到了使用意图录音.这篇文章将使用MediaRecorder类来录音,从而提供很多其它的灵活性. 效果图: 源码奉上: <LinearLayout xmlns:android=" ...

  6. android MediaRecorder start failed:-38【转】

    本文转载自:http://blog.csdn.net/fnuwfnh/article/details/46698509 最近在学习android 录音方面的知识,发现在部分手机正常运行的APP,在华为 ...

  7. Android MediaRecorder录制播放音频

    1.请求录制音频权限 <user-permission android:name="android.permission.RECORD_AUDIO"/> RECORD_ ...

  8. Android: MediaRecorder start failed

    在某些机型上,MediaRecorder在调用start方法时,会出现start failed的错误,有一种可能是setVideoFrameRate导致的.要解决这个问题,只需要注释掉这条语句就可以了 ...

  9. Android多媒体录制--MediaRecorder视频录制

    Android使用MediaRecorder类进行视频的录制. 需要注意,使用MediaRecorder 录音录像 的设置代码步骤一定要按照API指定的顺序来设置,否则报错 步骤为: 1.设置视频源, ...

  10. 推荐--《Android深入浅出》

    基本信息 书名:Android深入浅出 作者:张旸 著 页数: 661 出版社: 机械工业出版社; 第1版 (2014年4月17日) 语种: 简体中文 ASIN: B00JR3P8X0 品牌: 北京华 ...

随机推荐

  1. Thread类和Runnable接口实现多线程--2019-4-18

    1.通过Thread实现 public class TestThread extends Thread{ public TestThread(String name) { super(name); } ...

  2. 业务线B/C端业务组件总结

    /** * 业务线组件总结 * */ /* B端组件的总结 1.组件cssBase的总结 1像素底部边框 */ @mixin border - 1px - b($background: $gray - ...

  3. Anaconda使用指南

    Anaconda使用指南 Anaconda介绍 什么是 Anaconda Anaconda是专注于数据分析的Python发行版本,包含了conda.Python等190多个科学包及其依赖项.作为好奇宝 ...

  4. hive中left/right join on连接中and与where的使用问题

    很多同学在进行表关联的时候,and和where的使用有时候分不清,在这里实操记录下. 创建人员信息表并写入数据 create table tmp.userinfo(id string,name str ...

  5. 关于resharper激活

    resharper 是一款非常强大的vs辅助开发插件,提供了很多快捷操作功能,本人已经离不开它了,但是resharper总会遇到lincese过期,需要激活的问题,现在提供以下方式,仅供参考 1.打开 ...

  6. 我的 FPGA 学习历程(08)—— 实验:点亮单个数码管

    数码管是一种常见的用于显示的电子器件,根据数码管大致可以分为共阴极和共阳极两种,下图所示的是一个共阳极的数码管的电路图(摘自金沙滩工作室的 51 开发板电路图),我的 AX301 开发板与这张图的情况 ...

  7. [POJ1273][USACO4.2]Drainage Ditches (网络流最大流)

    题意 网络流最大流模板 思路 EK也不会超时 所以说是一个数据比较水的模板题 但是POJ有点坑,多组数据,而且题目没给 哭得我AC率直掉 代码 用的朴素Dinic #include<cstdio ...

  8. JUC

    1.Java JUC简介 在Java5.0提供了java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池.异 ...

  9. SpringBoot几种定时任务的实现方式

    定时任务实现的几种方式: Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行, ...

  10. 2分钟读懂大数据框架Hadoop和Spark的异同

    转自:https://www.cnblogs.com/reed/p/7730313.html 谈到大数据,相信大家对Hadoop和Apache Spark这两个名字并不陌生.但我们往往对它们的理解只是 ...