Android MediaRecorder 使用详解
1、MediaRecorder 概述
1.1、什么是 MediaRecorder
MediaRecorder 是 Android 提供的一个用于录制音频和视频的类,它可以从设备的麦克风和摄像头获取数据,并将其编码为各种格式的媒体文件。
1.2、MediaRecorder 的功能
- 录制音频
- 录制视频
- 录制屏幕
- 支持多种编码格式
- 支持多种输出格式
1.3、MediaRecorder 的适用场景
- 视频录制应用
- 语音记录应用
- 屏幕录制应用
- 视频通话应用
- 安全监控应用
1.4、权限要求
使用 MediaRecorder 需要在 AndroidManifest.xml 中添加以下权限:
<!-- 录制音频权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 录制视频权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Android 6.0 及以上版本需要动态申请权限 -->
2、MediaRecorder 基本使用
2.1、录制音频
步骤:
1. 申请权限
2. 初始化 MediaRecorder
3. 配置 MediaRecorder
4. 开始录制
5. 停止录制
6. 释放资源
代码示例:
private MediaRecorder mediaRecorder;
private String outputFile;
private void startAudioRecording() {
// 检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION);
return;
}
try {
// 创建输出文件
outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/audio_" + System.currentTimeMillis() + ".3gp";
// 初始化 MediaRecorder
mediaRecorder = new MediaRecorder();
// 配置 MediaRecorder
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置音频源为麦克风
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // 设置输出格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 设置音频编码器
mediaRecorder.setOutputFile(outputFile); // 设置输出文件
// 准备
mediaRecorder.prepare();
// 开始录制
mediaRecorder.start();
Toast.makeText(this, "开始录制音频", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "录制失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void stopAudioRecording() {
if (mediaRecorder != null) {
try {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
Toast.makeText(this, "录制完成,文件保存至:" + outputFile, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.2、录制视频
步骤:
1. 申请权限
2. 初始化 Camera
3. 初始化 MediaRecorder
4. 配置 MediaRecorder
5. 开始录制
6. 停止录制
7. 释放资源
代码示例:
private Camera camera;
private MediaRecorder mediaRecorder;
private String outputFile;
private SurfaceHolder surfaceHolder;
private void startVideoRecording() {
// 检查权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION);
return;
}
try {
// 打开相机
camera = Camera.open();
camera.setDisplayOrientation(90); // 设置相机方向
// 获取 SurfaceHolder
SurfaceView surfaceView = findViewById(R.id.surface_view);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// 创建输出文件
outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/video_" + System.currentTimeMillis() + ".mp4";
// 初始化 MediaRecorder
mediaRecorder = new MediaRecorder();
// 解锁相机
camera.unlock();
mediaRecorder.setCamera(camera);
// 配置 MediaRecorder
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); // 设置音频源
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 设置视频源
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 设置输出格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); // 设置音频编码器
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 设置视频编码器
mediaRecorder.setVideoSize(1280, 720); // 设置视频尺寸
mediaRecorder.setVideoFrameRate(30); // 设置视频帧率
mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024); // 设置视频编码比特率
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); // 设置预览
mediaRecorder.setOutputFile(outputFile); // 设置输出文件
// 准备
mediaRecorder.prepare();
// 开始录制
mediaRecorder.start();
Toast.makeText(this, "开始录制视频", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "录制失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
// 释放资源
if (camera != null) {
camera.lock();
camera.release();
camera = null;
}
if (mediaRecorder != null) {
mediaRecorder.release();
mediaRecorder = null;
}
}
}
private void stopVideoRecording() {
if (mediaRecorder != null) {
try {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
if (camera != null) {
camera.lock();
camera.release();
camera = null;
}
Toast.makeText(this, "录制完成,文件保存至:" + outputFile, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、MediaRecorder 配置选项
3.1、音频源
MediaRecorder.AudioSource.MIC:麦克风
MediaRecorder.AudioSource.VOICE_CALL:通话声音
MediaRecorder.AudioSource.VOICE_RECOGNITION:语音识别
MediaRecorder.AudioSource.CAMCORDER:相机麦克风
3.2、视频源
MediaRecorder.VideoSource.CAMERA:相机
MediaRecorder.VideoSource.SURFACE:表面(用于屏幕录制)
3.3、输出格式
MediaRecorder.OutputFormat.DEFAULT:默认格式
MediaRecorder.OutputFormat.THREE_GPP:3GP格式
MediaRecorder.OutputFormat.MPEG_4:MP4格式
MediaRecorder.OutputFormat.AAC_ADTS:AAC格式
MediaRecorder.OutputFormat.AM_RB:AMR格式
3.4、音频编码器
MediaRecorder.AudioEncoder.DEFAULT:默认编码器
MediaRecorder.AudioEncoder.AMR_NB:AMR窄带
MediaRecorder.AudioEncoder.AMR_WB:AMR宽带
MediaRecorder.AudioEncoder.AAC:AAC编码器
MediaRecorder.AudioEncoder.VORBIS:Vorbis编码器
3.5、视频编码器
MediaRecorder.VideoEncoder.DEFAULT:默认编码器
MediaRecorder.VideoEncoder.H263:H.263编码器
MediaRecorder.VideoEncoder.H264:H.264编码器
MediaRecorder.VideoEncoder.MPEG_4_SP:MPEG-4 SP编码器
3.6、其他配置
设置视频尺寸:
mediaRecorder.setVideoSize(width, height);
设置视频帧率:
mediaRecorder.setVideoFrameRate(frameRate);
设置视频编码比特率:
mediaRecorder.setVideoEncodingBitRate(bitRate);
设置音频编码比特率:
mediaRecorder.setAudioEncodingBitRate(bitRate);
设置音频采样率:
mediaRecorder.setAudioSamplingRate(sampleRate);
设置音频通道数:
mediaRecorder.setAudioChannels(channels);
4、MediaRecorder 高级应用
4.1、录制屏幕
步骤:
1. 申请屏幕录制权限
2. 创建 MediaProjectionManager
3. 初始化 MediaRecorder
4. 配置 MediaRecorder
5. 开始录制
6. 停止录制
7. 释放资源
代码示例:
private MediaProjectionManager mediaProjectionManager;
private MediaProjection mediaProjection;
private MediaRecorder mediaRecorder;
private String outputFile;
private static final int REQUEST_CODE_SCREEN_RECORD = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_record);
mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
}
private void startScreenRecording() {
// 检查存储权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION);
return;
}
// 启动屏幕录制权限请求
Intent intent = mediaProjectionManager.createScreenCaptureIntent();
startActivityForResult(intent, REQUEST_CODE_SCREEN_RECORD);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SCREEN_RECORD && resultCode == RESULT_OK) {
// 获取 MediaProjection
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
try {
// 创建输出文件
outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/screen_" + System.currentTimeMillis() + ".mp4";
// 初始化 MediaRecorder
mediaRecorder = new MediaRecorder();
// 配置 MediaRecorder
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置音频源
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); // 设置视频源为表面
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 设置输出格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); // 设置音频编码器
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 设置视频编码器
mediaRecorder.setVideoSize(1920, 1080); // 设置视频尺寸
mediaRecorder.setVideoFrameRate(30); // 设置视频帧率
mediaRecorder.setVideoEncodingBitRate(8 * 1024 * 1024); // 设置视频编码比特率
mediaRecorder.setOutputFile(outputFile); // 设置输出文件
// 准备
mediaRecorder.prepare();
// 创建虚拟显示
Surface surface = mediaRecorder.getSurface();
mediaProjection.createVirtualDisplay("ScreenRecord", 1920, 1080, getResources().getDisplayMetrics().densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null);
// 开始录制
mediaRecorder.start();
Toast.makeText(this, "开始录制屏幕", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "录制失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
private void stopScreenRecording() {
if (mediaRecorder != null) {
try {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
if (mediaProjection != null) {
mediaProjection.stop();
mediaProjection = null;
}
Toast.makeText(this, "录制完成,文件保存至:" + outputFile, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.2、录制视频并添加水印
步骤:
1. 创建带水印的 SurfaceView
2. 配置 MediaRecorder 使用该 SurfaceView
3. 开始录制
代码示例:
private class WatermarkSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private Paint paint;
public WatermarkSurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setTextSize(30);
paint.setAntiAlias(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas canvas = holder.lockCanvas();
if (canvas != null) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawText("水印文字", 50, 50, paint);
holder.unlockCanvasAndPost(canvas);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
// 使用带水印的 SurfaceView
WatermarkSurfaceView surfaceView = new WatermarkSurfaceView(this);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
5、MediaRecorder 最佳实践
5.1、权限处理
- 在 Android 6.0 及以上版本,需要动态申请权限
- 处理权限拒绝的情况
- 提供友好的权限提示
5.2、错误处理
- 捕获并处理 MediaRecorder 的异常
- 检查设备是否支持录制功能
- 处理存储空间不足的情况
5.3、性能优化
- 合理设置视频尺寸和帧率
- 合理设置编码比特率
- 避免在主线程执行耗时操作
- 及时释放资源
5.4、存储管理
- 使用应用私有目录存储录制文件
- 定期清理旧的录制文件
- 检查存储空间是否充足
5.5、用户体验
- 提供录制状态反馈
- 显示录制时长
- 提供暂停/继续功能
- 处理后台录制的情况
5.6、兼容性
- 测试不同设备的兼容性
- 处理不同 Android 版本的差异
- 检查设备是否支持特定的编码格式
6、常见问题与解决方案
6.1、录制失败
- 检查权限是否正确
- 检查设备是否支持录制功能
- 检查存储空间是否充足
- 检查编码格式是否支持
6.2、录制的视频没有声音
- 检查是否添加了 RECORD_AUDIO 权限
- 检查音频源设置是否正确
- 检查音频编码器设置是否正确
6.3、录制的视频画面颠倒
- 设置相机方向:camera.setDisplayOrientation(90);
- 调整录制的视频尺寸
6.4、录制的视频文件过大
- 降低视频尺寸
- 降低视频帧率
- 降低视频编码比特率
- 使用更高效的编码格式
6.5、后台录制被系统终止
- 使用前台服务进行录制
- 申请 WakeLock 防止设备休眠
MediaRecorder 是 Android 中用于录制音频和视频的强大工具,通过合理配置和使用,可以实现各种录制功能。在实际开发中,需要注意权限处理、错误处理、性能优化和用户体验等方面,以确保录制功能的稳定和可靠。
通过掌握 MediaRecorder 的使用方法和最佳实践,可以开发出功能丰富、性能优秀的录制应用,满足用户的各种录制需求。