mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS)
使用 setOutputFile()
设置输出文件名。您必须指定代表实际文件的文件描述符。
使用 setAudioEncoder()
设置音频编码器。
通过调用 prepare()
完成初始化。
通过分别调用 start()
和 stop()
来启动和停止录音功能。
使用完 MediaRecorder
实例后,请尽快调用 release()
来释放其资源。
注意:在搭载 Android 9(API 级别 28)或更高版本的设备上,在后台运行的应用将无法访问麦克风。因此,您的应用只在以下两种情况下才应录制音频:当其位于前台时,或者您在前台服务中添加了 MediaRecorder
实例时。
使用 MediaMuxer 来录制多个声道
从 Android 8.0(API 级别 26)开始,您可以使用 MediaMuxer
来录制多个同步的音频和视频串流。在更低版本的 Android 中,您一次只能录制一个音轨和/或一个视频轨道。
使用 addTrack()
方法可以将多个轨道混录在一起。
您还可以为每个帧添加一个或多个带有自定义信息的元数据轨道,但只能添加到 MP4 容器中。您的应用将定义元数据的格式和内容。
添加元数据
元数据对于离线处理非常有用。例如,从陀螺仪传感器捕获的数据可用于执行视频稳定。
当您添加元数据轨道时,轨道的 MIME 格式必须以前缀 application/
开头。写入元数据与写入视频或音频数据相同,只是数据不是来自 MediaCodec
,而是由应用将带有关联时间戳的 ByteBuffer
传递给 writeSampleData()
方法。该时间戳的时间基准必须与视频和音频轨道的时间基准相同。
生成的 MP4 文件使用 ISO BMFF 规范第 12.3.3.2 节中定义的 TextMetaDataSampleEntry
来指示元数据的 MIME 格式。当您使用 MediaExtractor
来提取包含元数据轨道的文件时,元数据的 MIME 格式会显示为 MediaFormat
的实例。
MediaRecorder 示例说明了如何使用 MediaRecorder 和 Camera API 进行视频录制。
以下 Activity 示例展示了如何使用 MediaRecorder
录制音频文件。它还使用 MediaPlayer
来播放音频。
KotlinJava
package com.android.audiorecordtest
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.MediaPlayer
import android.media.MediaRecorder
import android.os.Bundle
import android.support.annotation.NonNull
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import java.io.IOException
public class AudioRecordTest extends AppCompatActivity {
private static final String LOG_TAG = "AudioRecordTest"
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200
private static String fileName = null
private RecordButton recordButton = null
private MediaRecorder recorder = null
private PlayButton playButton = null
private MediaPlayer player = null
// Requesting permission to RECORD_AUDIO
private boolean permissionToRecordAccepted = false
private String [] permissions = {Manifest.permission.RECORD_AUDIO}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
switch (requestCode){
case REQUEST_RECORD_AUDIO_PERMISSION:
permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED
break
if (!permissionToRecordAccepted ) finish()
private void onRecord(boolean start) {
if (start) {
startRecording()
} else {
stopRecording()
private void onPlay(boolean start) {
if (start) {
startPlaying()
} else {
stopPlaying()
private void startPlaying() {
player = new MediaPlayer()
try {
player.setDataSource(fileName)
player.prepare()
player.start()
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed")
private void stopPlaying() {
player.release()
player = null
private void startRecording() {
recorder = new MediaRecorder()
recorder.setAudioSource(MediaRecorder.AudioSource.MIC)
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
recorder.setOutputFile(fileName)
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
try {
recorder.prepare()
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed")
recorder.start()
private void stopRecording() {
recorder.stop()
recorder.release()
recorder = null
class RecordButton extends Button {
boolean mStartRecording = true
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onRecord(mStartRecording)
if (mStartRecording) {
setText("Stop recording")
} else {
setText("Start recording")
mStartRecording = !mStartRecording
public RecordButton(Context ctx) {
super(ctx)
setText("Start recording")
setOnClickListener(clicker)
class PlayButton extends Button {
boolean mStartPlaying = true
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onPlay(mStartPlaying)
if (mStartPlaying) {
setText("Stop playing")
} else {
setText("Start playing")
mStartPlaying = !mStartPlaying
public PlayButton(Context ctx) {
super(ctx)
setText("Start playing")
setOnClickListener(clicker)
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle)
// Record to the external cache directory for visibility
fileName = getExternalCacheDir().getAbsolutePath()
fileName += "/audiorecordtest.3gp"
ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION)
LinearLayout ll = new LinearLayout(this)
recordButton = new RecordButton(this)
ll.addView(recordButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0))
playButton = new PlayButton(this)
ll.addView(playButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0))
setContentView(ll)
@Override
public void onStop() {
super.onStop()
if (recorder != null) {
recorder.release()
recorder = null
if (player != null) {
player.release()
player = null
复制代码