目录
利用MediaRecorder录制音频
setOutputFormat参数取值说明表
setAudioEncoder参数取值说明表
利用MediaRecorder录制音频
之前介绍过媒体播放器MediaPlayer,与之对应的媒体录制器MediaRecorder是Android系统中一个强大的多媒体录制工具,它可以录制音频也可以录制视频,能够通过相对简单的API调用来实现录制任务。它的常用方法说明如下:
1.reset:重置录制器。
2.prepare:准备录制。
3.start:开始录制。
4.pause:暂停录制。
5.stop:停止录制。
6.release:释放录制器。
7.setMaxDuration:设置最大可录制时长,单位为毫秒ms。
8.setMaxFileSize:设置最大可录制文件大小,单位为字节B。它与setMaxDuration方法设置其中一个即可。
9.setOutputFile:设置输出文件的保存路径。
10.setAudioSource:设置音频来源,一般使用麦克风AudioSource.MIC。
11.setOutputFormat:设置媒体输出格式。输出格式说明表如下。
| 输出格式参数 | 常见文件扩展名 | 简要说明与常用编码器搭配 |
|---|---|---|
AAC_ADTS |
.aac | ADTS(音频数据传输流)格式的AAC音频流。通常与MediaRecorder.AudioEncoder.AAC搭配使用。 |
AMR_NB |
.3gp,.amr | 适用于窄带AMR(自适应多速率)音频。通常与MediaRecorder.AudioEncoder.AMR_NB搭配使用。 |
AMR_WB |
.3gp | 适用于宽带AMR音频。通常与MediaRecorder.AudioEncoder.AMR_WB搭配使用。 |
DEFAULT |
由系统决定 | 默认输出格式,具体取决于设备。 |
MPEG_2_TS |
.ts | MPEG-2传输流格式。在Android 3.0+中支持,通常不可定位(seekable)。 |
MPEG_4 |
.mp4, .m4a | MPEG-4容器格式。可包含音频和视频轨道,常与AAC音频编码器及H.264等视频编码器搭配。 |
RAW_AMR |
.3gp | 原始AMR数据。注意:此常数在API Level 16中已被弃用。 |
THREE_GPP |
.3gp | 3GPP容器格式。常用于存储AMR-NB、AMR-WB音频及H.263等视频。 |
WEBM |
.webm | WebM开放媒体格式。从Android 4.0开始支持,常与Vorbis音频编码器及VP8等视频编码器搭配。 |
12.setAudioEncoder:设置音频编码器,参数取值说明表如下。该方法需要再setOutputFormat方法后执行,否则会抛出异常。
| 编码器参数 | 核心特点与说明 | 常见输出格式/文件扩展名 | 典型应用场景 |
|---|---|---|---|
MediaRecorder.AudioEncoder.AAC |
通用且音质较好,采用AAC-LC(低复杂度)规格,在保证音质的同时有效控制文件大小。 | MP4 (.mp4, .m4a), 3GP (.3gp) |
对音质有一定要求的通用音频或视频录制 |
MediaRecorder.AudioEncoder.AMR_NB |
窄带语音编码,专为语音优化,文件小,音质一般,采样率通常为8kHz。 | 3GP (.3gp) |
纯语音录制,如电话录音 |
MediaRecorder.AudioEncoder.AMR_WB |
宽带语音编码,相较于AMR-NB,音频带宽更广(50-7000Hz),语音更自然,采样率通常为16kHz。 | 3GP (.3gp) |
对语音质量要求较高的场景 |
MediaRecorder.AudioEncoder.HE_AAC |
高效率AAC,在较低码率下能提供较好的音质,适合网络传输-2。编码器支持从Android 4.1开始。 | MP4 (.mp4, .m4a), 3GP (.3gp) |
低比特率音频流,如网络广播 |
MediaRecorder.AudioEncoder.AAC_ELD |
增强型低延迟AAC,专为实时通信设计,能提供高质量、低延迟的音频。编码器支持从Android 4.1开始。 | MP4 (.mp4, .m4a), 3GP (.3gp) |
视频会议、实时语音通话 |
MediaRecorder.AudioEncoder.VORBIS |
开放且无专利限制,支持多声道,可以在更低的码率下获得较好的音质。 | Ogg (.ogg), Matroska (.mkv) |
需要免版权费用或特定格式的音频录制 |
MediaRecorder.AudioEncoder.DEFAULT |
由系统决定默认的音频编码器。 | 由系统决定 | 无特殊编码要求,使用系统默认设置 |
13.setAudioSamplingRate:设置音频的采样率,单位为千赫兹kHz。AMR_NB格式默认为8kHz,AMR_WB格式默认18kHz。
14.setAudioChannels:设置音频的声道数。1表示单声道,2表示双声道。
15.setAudioEncodingBitRate:设置音频每秒录制的字节数,数值越大音频越清晰。
示例代码如下,在布局文件中添加两个按钮以及一个文本视图。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.***/apk/res/android"
xmlns:app="http://schemas.android.***/apk/res-auto"
xmlns:tools="http://schemas.android.***/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MultiMedia.MediaRecorderActivity">
<Button
android:id="@+id/startRecord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="StartRecord" />
<Button
android:id="@+id/stopRecord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="StopRecord" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
</LinearLayout>
部分Java代码如下,在运行前先在AndroidManifest.xml中添加麦克风权限并在Java代码中查看是否获取权限,若无麦克风权限则无法录制。音频的保存路径有两个,一个为公共一个为私有,下面为私有路径,可自行修改路径。主要看startView方法中的代码,需注意不要在onCreate方法中调用该方法,可能无法录制音频。作者在学的时候出现这个问题,不建议这样做。
public class MediaRecorderActivity extends App***patActivity implements MediaRecorder.OnInfoListener, MediaRecorder.OnErrorListener, View.OnClickListener {
private final String public_url = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
private String private_url;
private Button startRecord, stopRecord;
private TextView textView;
private MediaRecorder mediaRecorder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media_recorder);
initView();
}
//初始化页面
private void initView() {
startRecord = findViewById(R.id.startRecord);
stopRecord = findViewById(R.id.stopRecord);
textView = findViewById(R.id.textView);
private_url = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString();
File recordFile = new File(private_url + "/audioRecord/");
if (!recordFile.exists()) {
boolean i = recordFile.mkdirs();
if (!i) {
textView.setText("文件创建失败!");
}
}
startRecord.setOnClickListener(this);
stopRecord.setOnClickListener(this);
}
//录制音频
private void startRecord() {
mediaRecorder = new MediaRecorder();
Calendar calendar = Calendar.getInstance();
String path = String.format("%s/audioRecord/%s%s%s%s%s.amr", private_url, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE));
mediaRecorder.reset();//重置录制器
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置音频来源为麦克风
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);//设置输出音频类型
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置音频编码器
mediaRecorder.setMaxDuration(5000);//设置音频最大时长
mediaRecorder.setAudioSamplingRate(8);//设置音频采样率为8kHz,AMR_NB默认为8kHZ
mediaRecorder.setAudioChannels(2);//设置为双声道
mediaRecorder.setOutputFile(path);//设置音频保存路径
//添加信息事件
mediaRecorder.setOnInfoListener(MediaRecorderActivity.this);
// 添加错误监听
mediaRecorder.setOnErrorListener(MediaRecorderActivity.this);
try {
mediaRecorder.prepare();//准备录制
mediaRecorder.start();//开始录制
} catch (Exception e) {
Log.d(TAG, "ERROR:" + e.getMessage());
}
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.startRecord) {
startRecord();
textView.setText("开始录制...");
} else if (view.getId() == R.id.stopRecord) {
if (mediaRecorder != null) {
mediaRecorder.release();
mediaRecorder = null;
}
}
}
//信息监听器方法
@Override
public void onInfo(MediaRecorder mediaRecorder, int i, int i1) {
if (MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED == i) {
mediaRecorder.stop();
textView.setText("音频录制完毕!");
Log.d(TAG, "onInfo: stop");
}
}
//错误监听器方法
@Override
public void onError(MediaRecorder mediaRecorder, int i, int i1) {
Log.d(TAG, "录制错误: what=" + i + ", extra=" + i1);
mediaRecorder.stop();
mediaRecorder.release();
textView.setText("录制失败!");
}
}
效果图如下。录制完后可以按自己保存的位置找到该音频并打开,可以看到音频的长度与预设一样而且音频能够录到声音。