58. 【Android教程】音频录制:MediaRecord

在第 57 节我们使用 MediaPlayer 实现了一个 mp3 播放器,除了播放 Android 还提供了 MediaRecorder 用于录音。Android 设备基本都会有一个麦克风,通过 MediaRecorder 可以打开麦克风进行语音采集,这一节我们就来学习如何在 Android 系统上实现一个录音功能。

1. MediaRecorder 常用接口

  • setAudioSource():
    设置录制的音频源
  • setVideoSource():
    设置录制的视频源
  • setOutputFormat():
    设置输出格式
  • setAudioEncoder():
    设置音频编码器
  • setOutputFile():
    配置录制的音频存储文件路径
  • stop():
    停止录制
  • release():
    释放 MediaRecorder 实例,回收其所占资源

2. MediaRecorder 的使用步骤

  1. 创建 MediaRecorder
    直接通过无参构造器创建即可:
MediaRecorder myAudioRecorder = new MediaRecorder();
  1. 配置录音参数
    创建好之后,再对 MediaRecorder 实例进行参数配置,配置项有很多,一般需要设置音频输入源、音频输出格式、音频编码方式以及输出文件目录,如下:
myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myAudioRecorder.setOutputFile(outputFile);
  1. 开始录音
    在确定了录音配置和输出目录之后,我们就可以调用一下两个方法开始录音了:
myAudioRecorder.prepare();
myAudioRecorder.start();
  1. 停止录音
    录音结束调用stop()停止录制,如果不再使用还要记得调用release()释放 MediaRecorder 所占用的资源

3. 录音示例

本节使用 MediaRecorder 实现一个录音机:

3.1 MediaRecorder 控制逻辑

作为一个完整的录音功能,当然在录音结束之后也得要能回放录音。所以整个的控制要分为录音控制和播放控制,我们按照上一小节讲述的步骤用 MediaRecorder 完成录音,然后调用 MediaPlayer 来完成录音回放:


package com.emercy.myapplication;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.IOException;
import java.util.Random;

import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;

public class MainActivity extends Activity {

    Button buttonStart, buttonStop, buttonPlayLastRecordAudio,
            buttonStopPlayingRecording;
    String AudioSavePathInDevice = null;
    MediaRecorder mediaRecorder;
    Random random;
    String RandomAudioFileName = "emercy";
    public static final int RequestPermissionCode = 1;
    MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buttonStart = findViewById(R.id.button);
        buttonStop = findViewById(R.id.button2);
        buttonPlayLastRecordAudio = findViewById(R.id.button3);
        buttonStopPlayingRecording = findViewById(R.id.button4);

        buttonStop.setEnabled(false);
        buttonPlayLastRecordAudio.setEnabled(false);
        buttonStopPlayingRecording.setEnabled(false);

        random = new Random();

        buttonStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (checkPermission()) {

                    AudioSavePathInDevice =
                            Environment.getExternalStorageDirectory().getAbsolutePath() + "/" +
                                    CreateRandomAudioFileName(5) + "AudioRecording.3gp";

                    MediaRecorderReady();

                    try {
                        mediaRecorder.prepare();
                        mediaRecorder.start();
                    } catch (IllegalStateException | IOException e) {
                        e.printStackTrace();
                    }

                    buttonStart.setEnabled(false);
                    buttonStop.setEnabled(true);

                    Toast.makeText(MainActivity.this, "Recording started",
                            Toast.LENGTH_LONG).show();
                } else {
                    requestPermission();
                }

            }
        });

        buttonStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mediaRecorder.stop();
                buttonStop.setEnabled(false);
                buttonPlayLastRecordAudio.setEnabled(true);
                buttonStart.setEnabled(true);
                buttonStopPlayingRecording.setEnabled(false);

                Toast.makeText(MainActivity.this, "Recording Completed", Toast.LENGTH_LONG).show();
            }
        });

        buttonPlayLastRecordAudio.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) throws IllegalArgumentException,
                    SecurityException, IllegalStateException {

                buttonStop.setEnabled(false);
                buttonStart.setEnabled(false);
                buttonStopPlayingRecording.setEnabled(true);

                mediaPlayer = new MediaPlayer();
                try {
                    mediaPlayer.setDataSource(AudioSavePathInDevice);
                    mediaPlayer.prepare();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                mediaPlayer.start();
                Toast.makeText(MainActivity.this, "录音完毕", Toast.LENGTH_LONG).show();
            }
        });

        buttonStopPlayingRecording.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                buttonStop.setEnabled(false);
                buttonStart.setEnabled(true);
                buttonStopPlayingRecording.setEnabled(false);
                buttonPlayLastRecordAudio.setEnabled(true);

                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                    mediaPlayer.release();
                    MediaRecorderReady();
                }
            }
        });

    }

    public void MediaRecorderReady() {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        mediaRecorder.setOutputFile(AudioSavePathInDevice);
    }

    public String CreateRandomAudioFileName(int string) {
        StringBuilder stringBuilder = new StringBuilder(string);
        int i = 0;
        while (i < string) {
            stringBuilder.append(RandomAudioFileName.
                    charAt(random.nextInt(RandomAudioFileName.length())));

            i++;
        }
        return stringBuilder.toString();
    }

    private void requestPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE, RECORD_AUDIO}, RequestPermissionCode);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == RequestPermissionCode) {
            if (grantResults.length > 0) {
                boolean StoragePermission = grantResults[0] ==
                        PackageManager.PERMISSION_GRANTED;
                boolean RecordPermission = grantResults[1] ==
                        PackageManager.PERMISSION_GRANTED;

                if (StoragePermission && RecordPermission) {
                    Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_LONG).show();
                }
            }
        }
    }

    public boolean checkPermission() {
        int storagePermission = 0;
        int recordPermission = 0;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            storagePermission = checkSelfPermission(WRITE_EXTERNAL_STORAGE);
            recordPermission = checkSelfPermission(RECORD_AUDIO);
        }

        return storagePermission == PackageManager.PERMISSION_GRANTED &&
                recordPermission == PackageManager.PERMISSION_GRANTED;
    }
}

和拍照一样,录音也需要获取权限(注意 Android 6.0 以上还需要动态获取权限),除此之外只需要按照步骤进行录音就可以实现功能了。

3.2 录音布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="30dp">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_marginTop="37dp"
        android:text="录音" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/button"
        android:layout_centerHorizontal="true"
        android:text="停止" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/button2"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:text="回放" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button2"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="结束回放" />
</RelativeLayout>

对于两大功能:“录音”和“回放”,各提供两个按键控制,分别对应开始和结束。

最终编译效果:

4. 小结

MediaRecorder 很多时候都是配合 MediaPlayer 或者其他播放器一起使用,而两者之间也有很多相似之处。当然本节提到的只是最基本的录音及音频输出功能,如果需要进一步研究音视频相关的内容就得深入到底层编解码原理。不过对于大多数非专业音视频制作 App 而言已经足够。

  • 23
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
AndroidMediaRecord类可以用来录制音频,包括通过蓝牙设备进行录音。 要使用蓝牙设备录音,首先需要确保设备已经正确配对并连接了蓝牙耳机或扬声器。可以使用BluetoothAdapter类来管理蓝牙连接,以及使用BluetoothDevice类来获取已配对的蓝牙设备。 在开始录音之前,需要先创建一个MediaRecord对象,并设置音频的采样率、编码格式、音频源等参数。可以使用setAudioSource()方法来指定音频源为蓝牙耳机,例如MediaRecorder.AudioSource.MIC。 然后,使用setOutputFile()方法指定音频文件的保存路径和格式。可以使用getFileDescriptor()方法将蓝牙耳机连接的文件描述符作为录音文件的输出。 接下来,需要调用prepare()方法进行准备工作,并使用start()方法开始录音。录音过程中,可以使用stop()方法停止录音,并使用release()方法释放MediaRecord对象。 在录音完成后,可以使用MediaPlayer类来播放录音文件,或者使用其他处理方式对录音进行编辑和处理。 需要注意的是,蓝牙耳机的音质和录音效果可能会受到设备和耳机本身的限制,因此可能会在使用过程中遇到问题。在录音过程中,可以使用onErrorListener来处理录音出错的情况,并给出相应的提示。 总体而言,使用AndroidMediaRecord类进行蓝牙录音是很方便的。只需注意正确设置参数和处理录音异常的情况,就可以顺利实现蓝牙录音功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

红薯不甜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值