Android录音amr实时转成MP3格式

文章目录

  • MP3 录音使用说明
    • 步骤一:下载NDK,并配置(Mac)
    • 步骤二:修改C代码相关路径,编译成so库
    • 步骤三:应用层代码代码调用系统AudioRecord类开始录音
      • 开始录音 start()
    • 步骤四:在录音过程中实时转成MP3格式
    • 步骤五:停止录音

MP3 录音使用说明

资源信息下载

链接:https://pan.baidu.com/s/1m-HqA88udn-N_kNgOtoA_Q

提取码:8x3e

jni:音频转成MP3格式的C库,将类名或者路径名改成自己项目路径,通过NDK生成so库。(建议把jni文件夹同时也拷贝至 mp3library 模块下面)

mp3library:录音、格式转换的Library,包括so库和工具类。

步骤一:下载NDK,并配置(Mac)

1.下载地址:http://tools.android-studio.org/

2.解压后,配置环境变量

步骤二:修改C代码相关路径,编译成so库

将jni目录拷贝至 mp3library 依赖模块中的根目录下

将C代码中路径改成自己库(so库所在的位置)的路径,cd进入jni目录下,运行ndk-build 命令生成so库,之后将编译成功的libs文件下面的so库拷贝到自己的项目中。

步骤三:应用层代码代码调用系统AudioRecord类开始录音

try {
        String path = recAudioDir(recordFilePath).getAbsolutePath();
        recFile = new File(path, System.currentTimeMillis() + ".mp3");

    // 初始化录音工具类(mp3library库中),传入录音保存的路径
        mRecorder = new MP3Recorder(recFile);
    // 开始录音
        mRecorder.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
 }

AndioRecord 类的主要功能是让各种JAVA应用能够管理音频资源,以便它们通过此类能够录制平台的声音输入硬件所收集的声音。此功能的实现就是通过 “pulling同步AudioRecord对象的声音数据来完成的。在录音过程中,应用所需要做的就是通过 read 方法去及时地获取 AudioRecord 对象的录音数据. AudioRecord 类提供的三个获取声音数据的方法分别是read(byte[], int, int), read(short[], int, int), read(ByteBuffer, int). 无论选择使用那一个方法都必须事先设定方便用户的声音数据的存储格式。

开始录音的时候,一个 AudioRecord 需要初始化一个相关联的声音 buffer, 这个 buffer 主要是用来保存新的声音数据。这个buffer 的大小,我们可以在对象构造期间去指定。它表明一个 AudioRecord 对象还没有被读取(同步)声音数据前能录多长的音(即一次可以录制的声音容量)。一般情况下录音实现的简单流程如下:

  • 创建一个数据流
  • 构造一个 AudioRecord 对象,其中需要的最小录音缓存 buffer 大小可以通过 getMinBufferSize 方法得到。如果 buffer 容量过小,将导致对象构造的失败
  • 初始化一个buffer,该buffer大于等于 AudioRecord 对象用于写声音数据的 buffer 大小
  • 开始录音
  • AudioRecord 中读取声音数据到初始化 buffer ,将 buffer 中数据导入数据流
  • 停止录音
  • 关闭数据流

开始录音 start()

public void start() throws IOException {

   //以地址的方式获取frameCount的值。最小缓冲区的大小
    mBufferSize = AudioRecord.getMinBufferSize(DEFAULT_SAMPLING_RATE,
    DEFAULT_CHANNEL_CONFIG, DEFAULT_AUDIO_FORMAT.getAudioFormat());

 /** 初始化 AudioRecord
   * DEFAULT_AUDIO_SOURCE:  音源  MediaRecorder.AudioSource.MIC  本机的声音
   * DEFAULT_SAMPLING_RATE: 采样率 44100,模拟器仅支持从麦克风输入8kHz采样率
   * DEFAULT_CHANNEL_CONFIG:录音的声道数,当前设置的 16
   * DEFAULT_AUDIO_FORMAT:  录音的比特数,当前设置的 PCMFormat.PCM_16BIT
   * mBufferSize:           期望录音时系统为其提供的缓冲区大小
   */

    mAudioRecord = new AudioRecord(DEFAULT_AUDIO_SOURCE,
    DEFAULT_SAMPLING_RATE, DEFAULT_CHANNEL_CONFIG, DEFAULT_AUDIO_FORMAT.getAudioFormat(),mBufferSize);
    mPCMBuffer = new short[mBufferSize];
    mAudioRecord.startRecording();
		new Thread() {
			@Override
			public void run() {
				//设置线程权限
				android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
				while (mIsRecording) {
					int readSize = mAudioRecord.read(mPCMBuffer, 0, mBufferSize);
					if (readSize > 0) {
						mEncodeThread.addTask(mPCMBuffer, readSize);
						calculateRealVolume(mPCMBuffer, readSize);
					}
				}
				mAudioRecord.stop();
				mAudioRecord.release();
				mAudioRecord = null;
			}
	}
}

因为Android录音完成保存的音频格式默认为 amr,这是个体积较小,播放效果较差的音频格式,所以我们需要将 amr 格式的音频转成 mp3 格式。这个时候就需要使用我们刚刚编译的so库了。

步骤四:在录音过程中实时转成MP3格式

/**
  * 实现AudioRecord.OnRecordPositionUpdateListener
  * 从缓冲区中读取并处理数据,使用lame编码MP3
  * @return  从缓冲区中读取的数据的长度,缓冲区中没有数据时返回0
  */
@Override
public void onPeriodicNotification(AudioRecord recorder){
     if (mTasks.size() > 0) {
	Task task = mTasks.remove(0);
	short[] buffer = task.getData();
	int readSize = task.getReadSize();
	// 调用so库转成mp3
	int encodedSize = LameUtil.encode(buffer, buffer, readSize, mMp3Buffer);
	if (encodedSize > 0){
	   try {
		mFileOutputStream.write(mMp3Buffer, 0, encodedSize);
		} catch (IOException e) {
                    e.printStackTrace();
		  }
		}
		  return readSize;
		}
		return 0;
    }
}

步骤五:停止录音

 private void stopRecorder() {
        try {
            if (mRecorder != null) {
                mRecorder.stop();
                mRecorder = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

你可能感兴趣的:(Android)