Android 音视频技术之录音获取实时音量

一、实时音量相关基础知识

说到获取音量,大家首先想到的应该就是分贝(dB),分贝是一个相对单位(是一个比值,是一个数值,是一个纯计数方法)。

在音频领域dB度量的是声音的强度,其计算的公式如下:

在上面的公式中,分子是测量值的声压,分母是参考值的声压(20微帕,人类所能听到的最小声压)。

在Android设备传感器中,我们能获取到的物理值是振幅值,一般使用下面的公式来计算分贝值:

我们从Android SDK中读取了某段音频数据的振幅后,取最大振幅或平均振幅(可以用平方和平均,或绝对值的和平均),代入上述公式的A1。参考的振幅A0取值定为1(这里取1是为了实现方便,如需更加精确建议拿一个标准分贝计做校准参考),作为 Android 麦克风能听到的最小的声音振幅。这样我们就可以计算出分贝值了。

二、Android 获取实时音量

获取音量之前,我们必须先在AndroidManifest.xml文件里面申请相应的权限:

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

在Android SDK提供的API中,我们能获取到音频方式有两个:android.media.MediaRecorderandroid.media.AudioRecord

1. MediaRecorder

MediaRecorder 是用来录制一段完整的音视频并写入到文件系统中的API。通过它,我们能很简单的通过它的无参方法getMaxAmplitude来获取一小段时间内音频源数据中的最大振幅,此方法是很多录音软件计算音量等级所采用的办法。(注:因为是取最大值,所以存在受到极端数据的影响而导致计算的分贝波动值较大的问题)。

使用MediaRecorder.getMaxAmplitude返回的是0到32767范围的16位整型。如果设置参考振幅为1的话,那么计算出来的分贝值域的正常范围应该为 0dB90.3dB

核心代码:

    /**
     * 开始录音 使用amr格式
     */
    public void startRecord() {
        // 开始录音
        /* ①Initial:实例化MediaRecorder对象 */
        if (mMediaRecorder == null)
            mMediaRecorder = new MediaRecorder();
        try {
            /* ②setAudioSource/setVedioSource */
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置麦克风
            /* ②设置音频文件的编码:AAC/AMR_NB/AMR_MB/Default 声音的(波形)的采样 */
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
            /*
             * ②设置输出文件的格式:THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
             * ,H263视频/ARM音频编码)、MPEG-4、RAW_AMR(只支持音频且音频编码要求为AMR_NB)
             */
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            /* ③准备 */
            mMediaRecorder.setOutputFile(Environment.getExternalStorageDirectory().getPath() + File.separator + "111.amr");
            mMediaRecorder.setMaxDuration(MAX_LENGTH);
            mMediaRecorder.prepare();
            /* ④开始 */
            mMediaRecorder.start();
            updateMicStatus();
        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止录音
     */
    private void stopRecord() {
        if (mMediaRecorder == null) {
            return;
        }
        mMediaRecorder.stop();
        mMediaRecorder.reset();
        mMediaRecorder.release();
        mMediaRecorder = null;
    }

2. AudioRecord

此API相对MediaRecorder来说更偏底层一点,我们可以使用AudioRecord获得具体的音频数据。

音源数据通过read(byte[] audioData, int offsetInBytes, int sizeInBytes)方法从缓冲区读取到我们传入的字节数组audioData后,我们便可以对其进行操作,如求平方和或绝对值的平均值。这样可以避免个别极端值的影响,使计算的结果更加稳定。求得平均值之后,如果是平方和则代入常数系数为10的公式中,如果是绝对值的则代入常数系数为20的公式中,算出分贝值。

核心代码:

public void getNoiseLevel() {

    mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_IN_HZ,
            AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT, BUFFER_SIZE);

    new Thread(new Runnable() {
        @Override
        public void run() {
            mAudioRecord.startRecording();
            short[] buffer = new short[BUFFER_SIZE];
            while (isGetVoiceRun) {
                //r是实际读取的数据长度,一般而言r会小于buffersize
                int r = mAudioRecord.read(buffer, 0, BUFFER_SIZE);
                long v = 0;
                // 将 buffer 内容取出,进行平方和运算
                for (short value : buffer) {
                    v += value * value;
                }
                // 平方和除以数据总长度,得到音量大小。
                double mean = v / (double) r;
                double volume = 10 * Math.log10(mean);
                Log.d(TAG, "分贝值 = " + volume + "dB");
                synchronized (mLock) {
                    try {
                        mLock.wait(100); // 一秒十次
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            mAudioRecord.stop();
            mAudioRecord.release();
            mAudioRecord = null;
        }
    }).start();
}

github地址:https://github.com/renhui/RHAudioVolume/tree/master

原文地址:https://www.cnblogs.com/renhui/p/11704635.html

时间: 2024-10-07 11:18:41

Android 音视频技术之录音获取实时音量的相关文章

Android 音视频深入 十七 FFmpeg 获取RTMP流保存为flv (附源码下载)

项目地址https://github.com/979451341/RtmpSave 这个项目主要代码我是从雷神那弄过来的,不愧是雷神,我就配个环境搞个界面就可以用代码了. 这一次说的是将RTMP流媒体保存成为一个本地的FLV文件.因为播放视频本身占有很多技术难点,我先不做边获取RTMP流边播放了,这一次主要说如何获取RTMP流. 说说代码 初始化组件和网络环境 av_register_all(); //Network avformat_network_init(); 打开RTMP流,获取RTMP

Android IOS WebRTC 音视频开发总结(七十)-- 移动端音视频技术优化的七个方向

最近直播很火,很多朋友对背后的技术比较感兴趣,所以今天我们整理一篇关于移动端视频优化的文章,这篇文章是我朋友在一个技术大会上分享过的,更多内容请关注我们的微信公众号:rtcblacker 视频直播为什么会这么火? 首先,音视频直播.点播的需求一直大量存在,包括各种行业应用,比如视频门户.娱乐直播.游戏直播.在线教育.远程医疗,远程监控,企业协作,社交应用等等.“以前之所以没有全面爆发,是因为硬件条件不满足,比如网络的带宽有限”,目前网速仍在不断提升,光纤普及到小区,有线网络的上下行带宽已经达到要

android音视频点/直播模块开发

前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及如何技术选型,如何解决遇到的坑,本文抛砖引玉,欢迎大咖交流. 一. 音视频的基础知识 1.1 基本概念 视频是什么 静止的画面叫图像(picture).连续的图像变化每秒超过24帧(frame)画面以上时,根椐视觉暂留原理, 人眼无法辨别每付单独的静态画面,看上去是平滑连续的视觉效果.这样的连

Android音视频点/直播模块开发实践总结-zz

随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能.那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及如何技术选型,如何解决遇到的坑. 一. 音视频的基础知识 1.1 基本概念 视频是什么 静止的画面叫图像(picture).连续的图像变化每秒超过24帧(frame)画面以上时,根椐视觉暂留原理,人眼无法辨别每付单独的静态画面,看上去是平滑连续的视觉效果.这样的连续画面叫视频.当连续图像变化每秒低于

手机Android音视频采集与直播推送,实现单兵、移动监控类应用

恰逢2014 Google I/O大会,不难看出安卓在Google的推进以及本身的开放性作用下,已经快延生到生活的各个方面了,从安卓智能手机.平板,到可穿戴的Android Ware.眼镜.手表.再到Android汽车.智能家居.电视,甚至最近看新闻,日本出的几款机器人都是Android系统的,再把目光放回监控行业,传统监控中的移动终端设备,例如:单兵设备.手持设备.车载终端设备,包括家庭监控中用到的智能设备,都可以用Android系统替代了,不仅开发容易,而且易扩展,设备也更加智能了. 图 -

Android音视频即时通讯软件怎样通过JNI快速实现

Android音视频即时通讯软件怎样通过JNI快速实现 音视频通信 作为独立开发者或想缩短音视频开发周期的公司来说,想要在Android平台下实现音视频通信,最快捷的方法是寻找开源项目或调用其他公司API.之所以这么说是因为音视频通信技术涉及到底层音视频采集.解码. FFmpeg(音视频处理解决方案).媒体流传输协议等太多太多相关技术知识点.试了几个开源项目,视频差强人意,语音与视频不同步等不稳定因素.因此我把目光放到其他公司的API上(点击下载demo程序).demo程序API提供了一系列纯J

快速探索,音视频技术不再神秘

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由goo发表于云+社区专栏 与生活紧密相连的音视频,为何有那么多格式?直播.点播以及即时视频其中又有怎样的机制支撑?面对纷繁复杂的音视频知识,应该如何学起?快速探索,音视频技术不再神秘. 前言 面对一门技术,我们熟悉而陌生,我们能够熟练的基于平台的API完成各种各样的需求,掌握平台特性.框架与原理.但随着技术点不断深入,却发现自己存在基础性与深度性的知识盲区. 局限于平台API开发,并不能使我们走的很远.突破技术成长必经的瓶颈期,关

Android 音视频开发入门指南

最近收到很多网友通过邮件或者留言说想学习音视频开发,该如何入门,我今天专门写篇文章统一回复下吧. 音视频这块,目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的,希望我后面能挤出时间整一个专题详细讲一讲--目前的话,我先给出一个大的方向性的学习指南,希望对初学者有所帮助. 我一直相信带着 "任务" 去学习和实践,效率会高很多,因此我列出了一系列音视频相关的 "开发任务",从简单到困难(当然,不一定非常严格和完美,部分任务先后可调整),大家在完成任务的

远程医疗 音视频技术解决方案

临床医学院承担医.教.研的任务,接待实习学员,培训进修人员,教学任务繁重.手术教学过程,需现场教学,但手术室空间有限,学员多,教学效果差,而且影响手术工作.随着医学领域的不断发展,外科手术技术也在日新月异,利用高端计算机科学技术,对各种手术全程画面影像的实时记录,使之用于研究.教学和病例存档,已经得到非常的重视.有些具有争议的手术,也可以利用这些视频资料作为科学的判断依据.手术后对照这些影像资料进行学术探讨,对于提高手术的成功率能够起到很大的帮助.并可通过网络,得到异地专家手术中的远程指导.这样