我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android音频开发录制音频的方法是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android音频开发录制音频的方法是什么

这篇文章主要讲解了“Android音频开发录制音频的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android音频开发录制音频的方法是什么”吧!

首先看下音频录制跟播放效果简图:

Android音频开发录制音频的方法是什么

上面是录音:长按即可录音,支持声波动画,右滑删除等。支持录制pcm、wav、mp3格式音频。

下面是播放:点击左边扬声器icon,开始播放刚录制的本地音频文件【也支持在线音频播放】,支持播放进度,支持切换播放模式(听筒/扬声器/耳机)等。

一、音频录制权限:

无论在做开发任何功能之前,总得先添加及申请相关权限,后续的工作才能正常进行下去。音频录制所需权限如下,而且要在代码中动态申请这些敏感权限,同意后才能正常录制:

<uses-permission android:name="android.permission.RECORD_AUDIO" />    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

二、录音文件的配置:

通过第一节讲到音频的基础概念可知,在录制音频前应先进行录制的相关配置,它直接决定了录音文件的音频质量、文件大小、音频格式等。

    private void initConfig() {        recordConfig = new RecordConfig();        //采样位宽        recordConfig.setEncodingConfig(AudioFormat.ENCODING_PCM_16BIT);        //录音格式        recordConfig.setFormat(RecordConfig.RecordFormat.MP3);        // recordConfig.setFormat(RecordConfig.RecordFormat.WAV);        //采样频率        recordConfig.setSampleRate(16000);        String recordDir = String.format(Locale.getDefault(), "%s/Record/zhongyao/",                Environment.getExternalStorageDirectory().getAbsolutePath());        //存储目录        recordConfig.setRecordDir(recordDir);        AudioRecordManager.getInstance().setCurrentConfig(recordConfig);    }

三、音频录制:

音频录制类主要有两个封装类:分别是AudioRecorder 、AudioRecordManager。

AudioRecorder:主要是使用系统的AudioRecord来进行录音。并把录制好的音频文件进行合并,转码等,生成我们所需的音频文件。该文件是全局单例的,保证音频录制类只有一个实例。

AudioRecordManager:对AudioRecorder的封装管理,与外界交互均通过此类来完成,包括录音的各种生命周期控制调用等。减少了外界与AudioRecorder的直接交互,已达到对录音类的更好的管理,此类也是一个全局单例类。

1、录音对象初始化:

这里主要根据之前的录音配置,生成 bufferSizeInBytes【缓冲区字节大小】,和audioRecord对象。

    public void prepareRecord() {        // 获得缓冲区字节大小        if (bufferSizeInBytes == 0) {            bufferSizeInBytes = AudioRecord.getMinBufferSize(currentConfig.getSampleRate(),                    currentConfig.getChannelConfig(), currentConfig.getEncodingConfig());        }        if (audioRecord == null) {            audioRecord = new AudioRecord(AUDIO_INPUT, currentConfig.getSampleRate(),                    currentConfig.getChannelConfig(), currentConfig.getEncodingConfig(), bufferSizeInBytes);        }         audioRecordStatus = AudioRecordStatus.AUDIO_RECORD_PREPARE;    }

2、录制wav音频文件:

wav音频文件是无损的,所以音质会接近原生,但也正是因为是无损的,所以wav音频文件几乎没有压缩,相对来说会比较大。

录制wav音频得先进行录制采用,获得pcm文件,然后把pcm文件合并,最后再转成wav音频文件。

(1)开始录制pcm文件:

private void startPcmRecorder() {        audioRecordStatus = AudioRecordStatus.AUDIO_RECORD_START;        notifyState();        Logger.d(TAG, "开始录制 Pcm");        FileOutputStream fos = null;        try {            fos = new FileOutputStream(tmpFile);            audioRecord.startRecording();            byte[] byteBuffer = new byte[bufferSizeInBytes];             while (audioRecordStatus == AudioRecordStatus.AUDIO_RECORD_START) {                int end = audioRecord.read(byteBuffer, 0, byteBuffer.length);                notifyData(byteBuffer);                fos.write(byteBuffer, 0, end);                fos.flush();            }            audioRecord.stop();            files.add(tmpFile);            if (audioRecordStatus == AudioRecordStatus.AUDIO_RECORD_STOP) {                makeFile();            } else {                Logger.d(TAG, "取消录制...");            }        } catch (Exception e) {            Logger.e(e, TAG, e.getMessage());            notifyError("录音失败");        } finally {            try {                if (fos != null) {                    fos.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }        if (audioRecordStatus != AudioRecordStatus.AUDIO_RECORD_PAUSE) {            audioRecordStatus = AudioRecordStatus.AUDIO_RECORD_IDLE;            notifyState();            Logger.d(TAG, "录音结束");        }    }

(2)合并生成的多个pcm文件:

    private void mergePcmFile() {        boolean mergeSuccess = mergePcmFiles(resultFile, files);        if (!mergeSuccess) {            notifyError("合并失败");        }    }

(3)将合并好的pcm文件转成wav文件:

    private void makeWav() {        if (!FileUtil.isFile(resultFile) || resultFile.length() == 0) {            return;        }        byte[] header = WavUtils.generateWavFileHeader((int) resultFile.length(), currentConfig.getSampleRate(), currentConfig.getChannelCount(), currentConfig.getEncoding());        WavUtils.writeHeader(resultFile, header);    }

3、录制MP3音频文件

相比WAV音频文件而言,MP3音频文件,就更加常见,商业上使用的也比较多,就是因为MP3音频时经过压缩的,文件大小只有WAV的十二分之一,但是音质上几乎没有较大的差异性。当对音质没有极高要求的情况下,如录音文件,MP3格式是极好的选择。

(1)开始录制音频缓存:

这里有开启一个线程Mp3EncodeThread,将录音产生的字节数组byteBuffer不断的进行编解码生成MP3文件。

private void startMp3Recorder() {        audioRecordStatus = AudioRecordStatus.AUDIO_RECORD_START;        notifyState();         try {            audioRecord.startRecording();            short[] byteBuffer = new short[bufferSizeInBytes];             while (audioRecordStatus == AudioRecordStatus.AUDIO_RECORD_START) {                int end = audioRecord.read(byteBuffer, 0, byteBuffer.length);                if (mp3EncodeThread != null) {                    mp3EncodeThread.addChangeBuffer(new Mp3EncodeThread.ChangeBuffer(byteBuffer, end));                }                notifyData(ByteUtils.toBytes(byteBuffer));            }            audioRecord.stop();        } catch (Exception e) {            Logger.e(e, TAG, e.getMessage());            notifyError("录音失败");        }        if (audioRecordStatus != AudioRecordStatus.AUDIO_RECORD_PAUSE) {            if (audioRecordStatus == AudioRecordStatus.AUDIO_RECORD_CANCEL) {                deleteMp3Encoded();            } else {                stopMp3Encoded();            }        } else {            Logger.d(TAG, "暂停");        }    }

(2)MP3音频编解码:

Android原生的音频录制,支持直接生成WAV文件,但其实是不支持直接生成MP3文件的。这里对应MP3编解码,主要用到了开源的 libmp3lame.so 这个音频编解码库。以下是lame编解码方法及Mp3Encoder类:

MP3编解码方法:

private void lameData(ChangeBuffer changeBuffer) {        if (changeBuffer == null) {            return;        }        short[] buffer = changeBuffer.getData();        int readSize = changeBuffer.getReadSize();        if (readSize > 0) {            int encodedSize = Mp3Encoder.encode(buffer, buffer, readSize, mp3Buffer);            if (encodedSize < 0) {                Logger.e(TAG, "Lame encoded size: " + encodedSize);            }            try {                os.write(mp3Buffer, 0, encodedSize);            } catch (IOException e) {                Logger.e(e, TAG, "Unable to write to file");            }        }    }

Mp3Encoder类:

public class Mp3Encoder {     static {        System.loadLibrary("mp3lame");    }     public native static void close();     public native static int encode(short[] buffer_l, short[] buffer_r, int samples, byte[] mp3buf);     public native static int flush(byte[] mp3buf);     public native static void init(int inSampleRate, int outChannel, int outSampleRate, int outBitrate, int quality);     public static void init(int inSampleRate, int outChannel, int outSampleRate, int outBitrate) {        init(inSampleRate, outChannel, outSampleRate, outBitrate, 7);    }}

(3)生成libmp3lame.so:

本项目提供的源码中有lame的jni源码,如果想生成libmp3lame.so文件,供自己的项目使用,那么需要对Mp3Encoder.c 和Mp3Encoder.h文件进行修改,然后通过ndk build 生成该so文件。

Android音频开发录制音频的方法是什么

修改的内容主要是把文件中的Mp3Encoder路径改成自己项目中的Mp3Encoder的路径,否则会找不到相关的native方法。

Android音频开发录制音频的方法是什么

另外一般情况下,cpu类型支持 armeabi-v7a 、arm64-v8a 两种即可,如果想支持其他的可在Application.mk中添加。

Android音频开发录制音频的方法是什么

上面文件修改完毕,通过ndk-build指令即可编译生成对应的 libmp3lame.so 文件。

将so不同CPU类型的文件放置 jniLibs 下,或者通过sourceSets配置的路径下,如:

sourceSets.main {        jni.class="lazy" data-srcDirs = []//disable automatic ndk-build call        jniLibs.class="lazy" data-srcDirs = ['libs']    }

即可进行MP3音频格式的录制。

四、音频录制管理【AudioRecordManager】:

通过全局单例模式的AudioRecorderManager与业务进行交互,即保证了音频录制实例的单一性,又能较好的对音频生命周期等进行较好的管理。 

public class AudioRecordManager {     private static final String TAG = "AudioRecordManager";     private AudioRecordManager() {    }     public static AudioRecordManager getInstance() {        return AudioRecordManagerHolder.instance;    }     public static class AudioRecordManagerHolder {        public static AudioRecordManager instance = new AudioRecordManager();    }     public void setCurrentConfig(RecordConfig recordConfig) {        AudioRecorder.getInstance().setCurrentConfig(recordConfig);    }     public RecordConfig getCurrentConfig() {        return AudioRecorder.getInstance().getCurrentConfig();    }         public void setRecordStateListener(RecordStateListener listener) {        AudioRecorder.getInstance().setRecordStateListener(listener);    }         public void setRecordDataListener(RecordDataListener listener) {        AudioRecorder.getInstance().setRecordDataListener(listener);    }         public void setRecordFftDataListener(RecordFftDataListener recordFftDataListener) {        AudioRecorder.getInstance().setRecordFftDataListener(recordFftDataListener);    }         public void setRecordResultListener(RecordResultListener listener) {        AudioRecorder.getInstance().setRecordResultListener(listener);    }         public void setRecordSoundSizeListener(RecordSoundSizeListener listener) {        AudioRecorder.getInstance().setRecordSoundSizeListener(listener);    }     public void setStatus(AudioRecordStatus curAudioRecordStatus) {        switch (curAudioRecordStatus) {            case AUDIO_RECORD_IDLE:                 break;             case AUDIO_RECORD_PREPARE:                AudioRecorder.getInstance().prepareRecord();                break;             case AUDIO_RECORD_START:                AudioRecorder.getInstance().startRecord();                break;             case AUDIO_RECORD_PAUSE:                AudioRecorder.getInstance().pauseRecord();                break;             case AUDIO_RECORD_STOP:                AudioRecorder.getInstance().stopRecord();                break;             case AUDIO_RECORD_CANCEL:                AudioRecorder.getInstance().cancelRecord();                break;             case AUDIO_RECORD_RELEASE:                AudioRecorder.getInstance().releaseRecord();                break;             default:                break;        }    }     public AudioRecordStatus getStatus() {        return AudioRecorder.getInstance().getAudioRecordStatus();    }     public String getAudioPath() {        return AudioRecorder.getInstance().getAudioPath();    }}

感谢各位的阅读,以上就是“Android音频开发录制音频的方法是什么”的内容了,经过本文的学习后,相信大家对Android音频开发录制音频的方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android音频开发录制音频的方法是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android音频开发录制音频的方法是什么

这篇文章主要讲解了“Android音频开发录制音频的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android音频开发录制音频的方法是什么”吧!首先看下音频录制跟播放效果简图:上
2023-06-21

Android音视频开发(五)AudioRecord录制音频

简介 AudioRecord是安卓多媒体框架中用于录制音频的工具。它支持录制原始音频数据,即PCM数据,PCM数据不能被播放器直接播放,需要编码压缩成常见音频格式才能被播放器识别。而原生api也提供了AudioTrack播放PCM数据。 谷
2022-06-06

Android中简单调用图片、视频、音频、录音和拍照的方法

本文实例讲述了Android中简单调用图片、视频、音频、录音和拍照的方法。分享给大家供大家参考,具体如下://选择图片 requestCode 返回的标识 Intent innerIntent = new Intent(Intent.ACT
2022-06-06

Android MediaPlayer音频播放器封装的方法是什么

本篇内容介绍了“Android MediaPlayer音频播放器封装的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在 Andro
2023-07-05

potplayer音频输出设置的方法是什么

要设置PotPlayer的音频输出,可以按照以下步骤操作:1. 打开PotPlayer播放器。2. 右键单击播放器窗口中的任何位置,弹出菜单。3. 在菜单中选择“选项”。4. 在弹出的“PotPlayer 首选项”窗口中,选择“音频”选项卡
2023-09-27

win7系统录制屏幕视频和声音的方法

如今,短视频行业正在蓬勃发展。当我们看到计算机有合适的视频材料时,我们不能下载它们。我们只能在录制屏幕后编辑它们。有些朋友仍然不知道如何在win7计算机上录制屏幕视频和声音,因为win7没有自带的屏幕录制工具。win7计算机需要使用第三方工
2023-07-10

为什么我录制的视频没有声音?迅捷屏幕录像工具的详细教程

为什么我录制的视频没有声音?我国最近几天增加了确诊病例,其中有几例还是本土病例。在这种情况下,很多学生仍然需要观看教学视频,在观看途中,相信不少人也会用屏幕录像工具录制教学视频以备回放,那么途中有遇到录制视频后发现没有声音的问题吗?小编专门写了一篇迅捷屏幕录像
为什么我录制的视频没有声音?迅捷屏幕录像工具的详细教程
2020-09-02

Android SeekBar控制视频播放进度实现的方法是什么

这篇“Android SeekBar控制视频播放进度实现的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Andro
2023-07-05

iPhone进行录音转文字的2种方法是什么

iPhone进行录音转文字的2种方法是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。使用过苹果手机的朋友们,应该也不在少数,但是你们使用苹果手机时,是否发现苹果手机也能够进
2023-06-02

Android广播机制原理与开发的方法是什么

今天小编给大家分享一下Android广播机制原理与开发的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。广播机制简介
2023-07-05

android控件开发的方法是什么

Android控件开发的方法主要有以下几种:1. 基于XML布局文件进行控件的开发:可以使用XML布局文件来定义控件的外观和布局,然后在Java代码中通过findViewById()方法获取到控件对象,并进行相关操作。2. 自定义控件:可以
2023-09-14

android组件化开发的方法是什么

Android组件化开发的方法有以下几种:1. 模块化开发:将整个项目拆分为多个独立的模块,每个模块独立开发、编译和运行。每个模块可以是一个功能模块、业务模块或者公共模块,模块之间通过依赖关系进行交互。通过模块化开发可以提高代码的复用性和可
2023-10-10

Android开发导出apk的方法是什么

Android开发导出apk的方法有两种:1. 使用Android Studio:在Android Studio中,选择菜单中的“Build” -> “Build Bundle(s)/APK(s)” -> “Build APK(s)”即可导
2023-10-12

Android开机动画制作的方法是什么

Android开机动画通常是通过修改系统文件来实现的。具体方法如下:获取Root权限:首先需要获取Root权限,以便能够修改系统文件。可以通过Root手机或使用Root工具(如Magisk、SuperSU等)来获取Root权限。查找系统文件
2023-10-26

android人脸识别开发的方法是什么

在Android上进行人脸识别开发有以下几种方法:1. 使用OpenCV库:OpenCV是一个开源的计算机视觉库,可以用于人脸检测和识别。可以通过在Android项目中集成OpenCV库,使用其提供的人脸检测和识别算法进行开发。2. 使用G
2023-10-09

android文件加密开发的方法是什么

Android文件加密开发的方法可以有多种,以下是其中几种常见的方法:1. 使用Android提供的加密API:Android提供了一套加密API,可以用于对文件进行加密。可以使用javax.crypto包中的类,如Cipher、KeyGe
2023-10-18

Scala+Eclipse+Android手机开发的方法是什么

本篇内容介绍了“Scala+Eclipse+Android手机开发的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!众所周知Andr
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录