安卓使用MediaRecorder(1)录制音频的详细使用

本文首发地址 https://blog.csdn.net/CSqingchen/article/details/134599828
最新更新地址 https://gitee.com/chenjim/chenjimblog

引言

在Android开发过程中,我们经常需要处理音频或视频相关的功能。比如,我们要做一个简单的录音机或者录像机。
在Android中录制音频有两种方式:MediaRecorderAudioRecord。两者的主要区别在于:

  • MediaRecorder提供了一种更高级别的API,能够直接录制并保存为特定的媒体文件格式(如MP3、AAC、AMR等)。其底层实际也使用了AudioRecord
  • AudioRecord提供了更底层的API,可以让我们自定义更多关于音频采样率、通道数等参数。但使用起来会比较复杂。
    本文主要介绍如何在Android中使用MediaRecorder进行录音,并附带一些常见的问题及其解决方案。

使用 MediaRecorder 的步骤

使用MediaRecorder进行录音和录像,主要有以下几个步骤:

  1. 创建一个MediaRecorder对象。
  2. 设置MediaRecorder的各种参数,包括音视频源、输出文件、编码格式等等。
  3. 调用prepare()方法,让MediaRecorder做好开始录制的准备。
  4. 调用start()方法,开始录制。
  5. 在合适的时间调用stop()方法,结束录制。
  6. 最后别忘了调用release()方法,释放资源。

下面是一个简单的录音示例:

import android.media.MediaRecorder;
import android.os.Environment;

public class RecorderAudio {
    public static final int RECORDER_SAMPLERATE = 44100;
    public static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";

    public static MediaRecorder getRecorder() {
        File dir = new File(Environment.getExternalStorageDirectory(), AUDIO_RECORDER_FOLDER);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File file = new File(dir, System.currentTimeMillis() + ".amr");

        // 创建一个MediaRecorder对象
        MediaRecorder recorder = new MediaRecorder();

        // 设置音频源为麦克风
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        // 设置音频输出格式
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        // 设置音频编码格式
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        // 设置输出文件路径
        recorder.setOutputFile(file.getAbsolutePath());

        return recorder;
    }

    public static void prepare(MediaRecorder recorder) {
        try {
            // 准备录制,初始化 MediaRecorder 的各种状态,并根据配置的信息创建一个 MediaCodec 对象。
            recorder.prepare();
        } catch (IOException e) {
            Log.e("MediaRecorder", "prepare() failed");
        }
    }

    public static void start(MediaRecorder recorder) {
        try {
            // 开始录制,开始真正的录音工作。它会启动一个循环来从 MediaCodec 对象中取出编码后的音频数据,然后写入到指定的文件中。
            recorder.start();
        } catch (RuntimeException e) {
            Log.e("MediaRecorder", "start() failed");
        }
    }

    public static void stop(MediaRecorder recorder) {
        // 停止录制,会让循环停止,并等待剩余的数据全部写入文件
        recorder.stop();
        // 释放掉所有的资源,包括`MediaRecorder`对象自身。
        recorder.release();
        recorder = null;
    }
}

注意:要确保所有的操作都在同一个线程中执行,否则可能会导致崩溃或异常。

如果想要在录制过程中,查看音量大小,可以通过调用getMaxAmplitude()方法来获取一小段时间内音频源数据中的最大振幅。
例如,每秒调用一次,可以得到近似音量值:
int maxAmplitude = recorder.getMaxAmplitude();

常见问题及解决思路

在实际使用MediaRecorder的过程中,可能会遇到各种各样的问题。这里列举一些常见的问题以及解决思路:

无法访问存储卡目录

原因:Android 6.0及以上版本要求用户明确授予应用读取外部存储的权限。

解决:在运行以上代码之前,需要动态申请权限:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) 
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, 
        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_STORAGE);
}

并在onRequestPermissionsResult回调方法中处理结果:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_WRITE_STORAGE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        startRecording();
    } else {
        Toast.makeText(this, "No storage permission", Toast.LENGTH_SHORT).show();
    }
}

录制的音频文件没有声音

原因:这可能是由于设置的音频源或编码器不正确导致的。

解决:确认已经设置了正确的音频源和编码器,并且麦克风功能正常。

录制过程中出现异常

原因:这可能是由于在多线程环境下操作MediaRecorder导致的。

解决:确保所有对MediaRecorder的操作都在同一个线程中执行。

MediaRecorder无法正常启动

这是最常见的问题。如果MediaRecorder无法正常启动,可能是由于参数设置错误,或者是设备不支持某种格式。
解决这个问题的方法是检查所有的参数设置,确保它们都是正确的,并且符合设备的要求。

录制的音质或者画质很差

这可能是因为采样率或者比特率设置得太低。解决这个问题的方法是提高采样率或者比特率,但是这样会增加文件的大小。

录制的文件无法播放

这可能是因为编码格式设置得不正确,或者设备不支持这种格式。解决这个问题的方法是更换编码格式,选择一种设备支持的格式。

结语

以上就是关于Android中MediaRecorder录制音频的详细使用的一些介绍。希望对你有所帮助。
如果你在使用MediaRecorder的过程中遇到了其他问题,欢迎留言讨论。
如果你觉得本文还不错,可以点赞+收藏。


相关文章
安卓MediaRecorder(1)录制音频的详细使用
安卓MediaRecorder(2)录制源码分析
安卓MediaRecorder(3)音频采集编码写入源码分析
安卓MediaRecorder(4)视频采集编码写入源码分析

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是一个简单的录制 WAV 音频文件的示例代码: ```java import android.media.AudioFormat; import android.media.AudioRecord; import android.media.MediaRecorder; import android.os.Environment; import android.util.Log; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class AudioRecorder { private static final String TAG = "AudioRecorder"; private static final int SAMPLE_RATE_IN_HZ = 44100; private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO; private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; private AudioRecord audioRecord; private boolean isRecording; public void startRecording() { int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ, CHANNEL_CONFIG, AUDIO_FORMAT); audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_IN_HZ, CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize); isRecording = true; audioRecord.startRecording(); new Thread(new Runnable() { @Override public void run() { writeDataToFile(); } }).start(); } public void stopRecording() { isRecording = false; audioRecord.stop(); audioRecord.release(); } private void writeDataToFile() { byte[] buffer = new byte[1024]; String filename = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.wav"; File file = new File(filename); if (file.exists()) { file.delete(); } try { FileOutputStream fos = new FileOutputStream(file); while (isRecording) { int read = audioRecord.read(buffer, 0, buffer.length); fos.write(buffer, 0, read); } fos.close(); } catch (IOException e) { Log.e(TAG, "writeDataToFile: ", e); } } } ``` 将上述代码保存到名为 `AudioRecorder.java` 的文件中,然后在你的 Android 项目中引入该文件。 在你的 Activity 或 Fragment 中,你可以通过以下方法来使用上述代码: ```java private AudioRecorder audioRecorder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); audioRecorder = new AudioRecorder(); } public void startRecording(View view) { audioRecorder.startRecording(); } public void stopRecording(View view) { audioRecorder.stopRecording(); } ``` 这里我们假设你在布局文件中创建了两个按钮,分别用于启动和停止录制。在 `startRecording()` 方法中,我们创建了一个新的线程来执行音频数据写入文件的操作。在 `stopRecording()` 方法中,我们停止录制并释放相关资源。 请注意,上述代码中的文件路径是 `/sdcard/recording.wav`。如果你的设备没有 SD 卡或者你的应用程序没有 SD 卡写入权限,那么你需要修改文件路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清霜辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值