Android 录音的3种方式,1.调用系统录音,2.AudioRecord,3.MediaRecoder_android 录音方式_张雨zy的博客-程序员宅基地

技术标签: Android基础  音视频  

1.调用系统的录音机并返回录制结果

https://blog.csdn.net/yu540135101/article/details/103655058

2.使用AudioRecord返回PCM数据

package com.zhangyu.myopengl.encoder;

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;

public class AudioRecordUtil {
    

    private static final String TAG = "AudioRecordUtil";
    private AudioRecord audioRecord;
    private int bufferSize;
    private int readSize;
    private boolean isStart;

    private int sample_rate = 44100;

    public AudioRecordUtil() {
    
        bufferSize = AudioRecord.getMinBufferSize(
                sample_rate,
                AudioFormat.CHANNEL_IN_STEREO,
                AudioFormat.ENCODING_PCM_16BIT);
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                sample_rate,
                AudioFormat.CHANNEL_IN_STEREO,
                AudioFormat.ENCODING_PCM_16BIT,
                bufferSize);
    }

    private OnRecordListener onRecordListener;

    public void setOnRecordListener(OnRecordListener onRecordListener) {
    
        this.onRecordListener = onRecordListener;
    }

    public interface OnRecordListener {
    
        void isStart();
        void readByte(byte[] audioData, int size);
    }

    /**
     * 开始
     */
    public void startRecord() {
    
        new Thread(new Runnable() {
    
            @Override
            public void run() {
    

                isStart = true;
                audioRecord.startRecording();
                byte[] audioData = new byte[bufferSize];
                if (onRecordListener != null) {
    
                    onRecordListener.isStart();
                }
                while (isStart) {
    
                    readSize = audioRecord.read(audioData, 0, bufferSize);
                    if (onRecordListener != null) {
    
                        onRecordListener.readByte(audioData, readSize);
                    }
                }
                //释放
                audioRecord.stop();
                audioRecord.release();
                audioRecord = null;

            }
        }).start();
    }

    /**
     * 停止
     */
    public void stopRecord() {
    
        isStart = false;
    }
}

3.使用MediaRecorder录制

package com.zhangyu.myopengl.utils;

import android.content.Context;
import android.media.MediaRecorder;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.io.IOException;

public class MediaRecorderUtil {
    

    private static final String TAG = "MediaRecorderUtil";

    private String path;
    private MediaRecorder recorder;

    private Type type = Type.AAC_AAC;

    /**
     * 枚举了两种常用的类型
     */
    public enum Type {
    
        AAC_M4A(".m4a", MediaRecorder.AudioEncoder.AAC, MediaRecorder.OutputFormat.MPEG_4),
        AAC_AAC(".aac", MediaRecorder.AudioEncoder.AAC, MediaRecorder.OutputFormat.AAC_ADTS),
        AMR_AMR(".amr", MediaRecorder.AudioEncoder.AMR_NB, MediaRecorder.OutputFormat.AMR_NB);
        String ext;
        int audioEncoder;
        int outputFormat;
        Type(String ext, int audioEncoder, int outputFormat) {
    
            this.ext = ext;
            this.audioEncoder = audioEncoder;
            this.outputFormat = outputFormat;
        }
    }

    /**
     * 初始化
     * @param context
     */
    public MediaRecorderUtil(Context context) {
    
        String fileName = "recorder_" + System.currentTimeMillis() + type.ext;
        Log.e(TAG, "MediaRecorderUtil: fileName=" + fileName);
//        String fileDir = context.getFilesDir() + "/record";
        String fileDir = Environment.getExternalStorageDirectory() + "/1";
        File file = new File(fileDir);
        //判断文件夹是否存在,如果不存在则创建文件夹
        if (!file.exists()) {
    
            file.mkdirs();
        }
        file = new File(fileDir, fileName);
        path = file.getAbsolutePath();
    }

    /**
     * 开始录制
     */
    public void start() {
    
        try {
    
            recorder = new MediaRecorder();
            recorder.setOutputFile(path);
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            recorder.setOutputFormat(type.outputFormat);
            recorder.setAudioEncoder(type.audioEncoder);
            recorder.prepare();
            recorder.start();
        } catch (IOException e) {
    
            e.printStackTrace();
        }
    }

    /**
     * 停止录制
     */
    public void stop() {
    
        if (recorder != null) {
    
            recorder.stop();
            recorder.release();
            recorder = null;
        }
    }

    /**
     * 获取音频的振幅
     * @return
     */
    public float getVoiceLevel() {
    
        float level = 0.1f;
        try {
    
            if (recorder != null) {
    
//                getMaxAmplitude()的范围是 1-32767
//                mediaRecorder.getMaxAmplitude()/32768 占总量的百分比
//                这里7*mediaRecorder.getMaxAmplitude()/32768 的最大值为6
                level = recorder.getMaxAmplitude() / 32768f;
                return level;
            }
        } catch (Exception e) {
    
            e.printStackTrace();
        }
        return level;
    }
}


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yu540135101/article/details/105589424

智能推荐

GLFW库_MagiChos的博客-程序员宅基地

在进行opengl开发时常用到glut辅助库,但是glut库版本又太老,而且并不免费,于是就有了freeglut作为替代,看到网上说freeglut存在很多bug(目前来说我还没有遇到),于是就又有了GLFW作为替代,下面就是用一个简单的例子演示GLFW的用法。#include #include int main(void){ G

vc如何引入lib库_带动态库的引入lib怎么编码_dbdoing的博客-程序员宅基地

vc引入lib库链接库分为静态链接库和动态链接库,静态链接库只有一个.lib文件,而动态链接库则有一个.lib文件和.dll文件;静态链接库的.lib文件里面有函数真正实现的机器码,而动态链接库的.lib只有函数的符号名,真正的函数的实现在dll文件中。当你使用静态库或者使用隐式的方式加载动态连接库的话,都需要将.lib文件加到vc工程里面去,他们的区别就在于,使用动态库的话,在运行程_带动态库的引入lib怎么编码

解决虚拟机下无法访问web服务器_为什么window物理机部署的web项目,虚拟机访问不到_bing19880122的博客-程序员宅基地

装好了虚拟机的nginx服务器,但是一直无法访问,费解啊。本机能ping通虚拟机 ,虚拟机能访问自己的web但就是本机无法访问虚拟机的web 服务器,google之找到原因默认iptables防火墙将80端口屏蔽了的缘故。对防火墙不太了解,先关了吧查看CentOS防火墙信息:/etc/init.d/iptables status关闭CentOS防火墙服务:/etc/init.d/iptables st_为什么window物理机部署的web项目,虚拟机访问不到

xilinx cordic ip核的使用_Tiger-Li的博客-程序员宅基地

http://blog.163.com/fantasy_sunny/blog/static/1959182122013113152237210/ 本文介绍如何使用xilinx的CORDIC 核生产一个sin和cos波形?cordic的原理就不介绍了,百度一大堆,我们知道原理后,需要去使用它。环境:xilinx ISE 14.5 cordic 4.0 modelsim ..._xilinx cordic ip

随便推点

PAT-乙级-1024. 科学计数法 (20) 测试点456_科学计数法 测试点0 和6_哈希瓜的博客-程序员宅基地

标题测试点4测试样例是+1.23456+035.6是指数不止两位数的情况,我笑了呀题目又给了两个指数两位数的情况还有一个03.好像必须两位数一样,别喷,题目说的9999字节我一时没放在心上_科学计数法 测试点0 和6

CentOS/Ubuntu制作自动安装iso实操_ubuntu.iso 安装脚本_Frank_Abagnale的博客-程序员宅基地

一、目的减少操作系统安装过程中人机交互过程,实现选择光盘安装后,无需其他人机交互过程即可自动完成操作系统的安装。二、环境和软件工具环境:Linux Ubuntu/CentOS操作系统(其他发行版未作尝试)软件:mkisofs,xorriso软件安装:CentOS : yum install mkisofs xorriso -yUbuntu: sudo apt insta_ubuntu.iso 安装脚本

[HNOI2010]弹飞绵羊_dengtun2502的博客-程序员宅基地

洛谷题目链接:弹飞绵羊题目描述某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。...

一张图带你看完图论第一章(包含定义、定理、公式、推导证明和例题)_超立方体边数推导_皎皎如月明的博客-程序员宅基地

1.1 图的基本描述 几种特殊图 有限图 复合图 简单图(无环无重边) 完全图 Kn 边数最多的简单图 同构下 唯一 边数Cn2=n(n-1)/2 补图 H 完全图-原图 把原图不相邻的点全部连起来,擦掉原图就是补图) 自补图 G与H同构 判定:顶点数为4的倍数或除4余1 证判定:同构=边数相同, G、H边数和为完全图边数=n(n-1)..._超立方体边数推导

社会矩阵:云技术如何激活十亿虚拟现实用户【52VR翻译】(附Carmack于OC4的演讲视频)_虚拟现实开发的博客-程序员宅基地

Simon Solotko 是一名卓有成就的VR/AR先锋,他断断续续参加 John Carmack 的脱稿演讲有20年了。

mybatis insert select ORA-00933_fishernemo的博客-程序员宅基地

mybatis insert select ORA-00933 : SQL命令未正确结束需要加 useGeneratedKeys="false"

推荐文章

热门文章

相关标签