音视频开发进阶指南(第六章)-Android平台的音频采集-AudioRecord

简介: 笔记

Android SDK提供了两套音频采集的API,分别是:MediaRecorderAudioRecord。前者是一个更加上层的API,它可以直接对手机麦克风录入的音频数据进行编码压缩(如AMR,MP3等),并存储为文件;后者更加接近底层,能够更加灵活地控制,其可以让开发者得到内存中的PCM音频流数据。如果想做一个简单的录音机,输出音频文件,则推荐使用MediaRecorder;如果需要对音频做进一步的算法处理,或者需要采用第三方的编码库进行编码压缩,又或者需要用到网络传输等场景中,那么只能使用AudioRecord或者OpenSL ES,其实MediaRecorder底层也是调用了AudioRecord与Android Framework层的AudioFlinger进行交互的。至于OpenSL ES,请参考另一篇文章音视频开发进阶指南(第四章)-OpenSL-ES播放PCM音频

本章讲解如何使用AudioRecord录音音频,并使用AudioTrack播放


播放步骤


1. 初始化AudioRecord

private static final int SAMPLE_RATE = 44100;//采样率
private static final int CHANNEL_CONFIG_IN = AudioFormat.CHANNEL_IN_MONO;//通道配置
private static final int CHANNEL_CONFIG_OUT = AudioFormat.CHANNEL_OUT_MONO;//通道配置
private static final int ENCODING_FORMAT = AudioFormat.ENCODING_PCM_16BIT;//编码配置
private static final String PCM_FILE = "/mnt/sdcard/test.pcm";
private static final String TAG = "MainActivity";
int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG_IN, ENCODING_FO
mAudioRecord = new AudioRecord(
        MediaRecorder.AudioSource.DEFAULT,//默认音频源
        SAMPLE_RATE,    //采样率
        CHANNEL_CONFIG_IN, //通道
        ENCODING_FORMAT,    //表示格式
        minBufferSize); //最小缓存
//开启录音
mAudioRecord.startRecording();

读取音频数据并写入文件

/**
 * 读取音频数据并写入文件
 */
private void startReadThread() {
    Log.d(TAG, "startReadThread");
    new Thread() {
        @Override
        public void run() {
            super.run();
            short[] buf = new short[1024];//一次读取的音频数据大小
            BufferedOutputStream bos = null;
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(PCM_FILE);
                bos = new BufferedOutputStream(fos);
                while (mAudioRecord.read(buf, 0, buf.length) > 0) {
                    //把short转为字节数组
                    byte[] bytes = ArrayUtil.toByteArraySmallEnd(buf);
                    bos.write(bytes);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    bos.close();
                    fos.close();
                    if (mAudioRecord != null) {
                        mAudioRecord.stop();
                        mAudioRecord.release();
                        mAudioRecord = null;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}

使用AudioTrack进行播放

private void play() {
    File file = new File(PCM_FILE);
    if (!file.exists()) {
        Toast.makeText(this, "请先开始录音", Toast.LENGTH_SHORT).show();
        return;
    }
    int minBufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG_OUT, ENCODI
    mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            SAMPLE_RATE,
            CHANNEL_CONFIG_OUT,
            ENCODING_FORMAT,
            minBufferSize,
            AudioTrack.MODE_STREAM);
    mAudioTrack.play();
    new Thread() {
        @Override
        public void run() {
            super.run();
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            byte[] buf = new byte[1024];
            try {
                fis = new FileInputStream(PCM_FILE);
                bis = new BufferedInputStream(fis);
                int read = 0;
                while ((read = bis.read(buf)) > 0) {
                    mAudioTrack.write(buf, 0, read);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    bis.close();
                    fis.close();
                    if (mAudioTrack != null) {
                        mAudioTrack.stop();
                        mAudioTrack.release();
                        mAudioTrack = null;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}


目录
相关文章
|
16天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
40 19
|
16天前
|
IDE 开发工具 Android开发
移动应用开发之旅:探索Android和iOS平台
在这篇文章中,我们将深入探讨移动应用开发的两个主要平台——Android和iOS。我们将了解它们的操作系统、开发环境和工具,并通过代码示例展示如何在这两个平台上创建一个简单的“Hello World”应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧,帮助你更好地理解和掌握移动应用开发。
40 17
|
16天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
41 14
|
16天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
|
17天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
17天前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
17天前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
24 0
|
存储 编解码 Android开发
【Android FFMPEG 开发】FFMPEG 读取音视频流中的数据到 AVPacket ( 初始化 AVPacket 数据 | 读取 AVPacket )
【Android FFMPEG 开发】FFMPEG 读取音视频流中的数据到 AVPacket ( 初始化 AVPacket 数据 | 读取 AVPacket )
253 0
|
Android开发
【Android FFMPEG 开发】FFMPEG 初始化 ( 网络初始化 | 打开音视频 | 查找音视频流 )
【Android FFMPEG 开发】FFMPEG 初始化 ( 网络初始化 | 打开音视频 | 查找音视频流 )
392 0