Android Studio新手开发第三十二天
目录
利用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.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MultiMedia.MediaRecorderActivity"><Buttonandroid:id="@+id/startRecord"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="StartRecord" /><Buttonandroid:id="@+id/stopRecord"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="StopRecord" /><TextViewandroid: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 AppCompatActivity 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;@Overrideprotected 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默认为8kHZmediaRecorder.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());}}@Overridepublic 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;}}}//信息监听器方法@Overridepublic 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");}}//错误监听器方法@Overridepublic void onError(MediaRecorder mediaRecorder, int i, int i1) {Log.d(TAG, "录制错误: what=" + i + ", extra=" + i1);mediaRecorder.stop();mediaRecorder.release();textView.setText("录制失败!");}
}
效果图如下。录制完后可以按自己保存的位置找到该音频并打开,可以看到音频的长度与预设一样而且音频能够录到声音。



