前言:

其实在Android中录音可以用MediaRecord录音,操作比较简单。但是不能对音频进行处理。考虑到项目中做的是实时语音只能选择AudioRecord进行录音。然后实时播放也只能采用AudioTrack进行播放。

下文为具体实现:

public class AudioTrackManager {
public static final String TAG = "AudioTrackManager";
private AudioTrack audioTrack;
private DataInputStream dis;
private Thread recordThread;
private boolean isStart = false;
private static AudioTrackManager mInstance;
private int bufferSize; public AudioTrackManager() {
bufferSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize * 2, AudioTrack.MODE_STREAM);
} /**
* 获取单例引用
*
* @return
*/
public static AudioTrackManager getInstance() {
if (mInstance == null) {
synchronized (AudioTrackManager.class) {
if (mInstance == null) {
mInstance = new AudioTrackManager();
}
}
}
return mInstance;
} /**
* 销毁线程方法
*/
private void destroyThread() {
try {
isStart = false;
if (null != recordThread && Thread.State.RUNNABLE == recordThread.getState()) {
try {
Thread.sleep(500);
recordThread.interrupt();
} catch (Exception e) {
recordThread = null;
}
}
recordThread = null;
} catch (Exception e) {
e.printStackTrace();
} finally {
recordThread = null;
}
} /**
* 启动播放线程
*/
private void startThread() {
destroyThread();
isStart = true;
if (recordThread == null) {
recordThread = new Thread(recordRunnable);
recordThread.start();
}
} /**
* 播放线程
*/
Runnable recordRunnable = new Runnable() {
@Override
public void run() {
try {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
byte[] tempBuffer = new byte[bufferSize];
int readCount = 0;
while (dis.available() > 0) {
readCount= dis.read(tempBuffer);
if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {
continue;
}
if (readCount != 0 && readCount != -1) {
audioTrack.play();
audioTrack.write(tempBuffer, 0, readCount);
}
}
stopPlay();
} catch (Exception e) {
e.printStackTrace();
}
} }; /**
* 播放文件
*
* @param path
* @throws Exception
*/
private void setPath(String path) throws Exception {
File file = new File(path);
dis = new DataInputStream(new FileInputStream(file));
} /**
* 启动播放
*
* @param path
*/
public void startPlay(String path) {
try {
setPath(path);
startThread();
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 停止播放
*/
public void stopPlay() {
try {
destroyThread();
if (audioTrack != null) {
if (audioTrack.getState() == AudioRecord.STATE_INITIALIZED) {
audioTrack.stop();
}
if (audioTrack != null) {
audioTrack.release();
}
}
if (dis != null) {
dis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} }

使用前要添加如下权限:

<!-- 录音权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

相关音频知识链接:

http://ticktick.blog.51cto.com/823160/1748506

Android音频开发之AudioTrack实时播放的更多相关文章

  1. Android音频开发之AudioRecord录音实现

    前言: 其实在Android中录音可以用MediaRecord录音,操作比较简单.但是不能对音频进行处理.考虑到项目中做的是实时语音只能选择AudioRecord进行录音. 本文算是对AudioRec ...

  2. Android音频开发之MediaRecorder/MediaPlayer

    前言: 上次我们介绍了实时采集音频数据以及播放,今天我们来认识一下直接录制文件的方式. 直接上代码:录制管理类 public class MediaRecorderManager { public s ...

  3. Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值

    Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值 题外话:一个问题研究到最后,那边记录文档的前半部分基本上都是没用的,甚至是错误的. 重点在最后,前边不过一些假想猜測. ht ...

  4. Android混合开发之WebViewJavascriptBridge实现JS与java安全交互

    前言: 为了加快开发效率,目前公司一些功能使用H5开发,这里难免会用到Js与Java函数互相调用的问题,这个Android是提供了原生支持的,不过存在安全隐患,今天我们来学习一种安全方式来满足Js与j ...

  5. Android混合开发之WebView与Javascript交互

    前言: 最近公司的App为了加快开发效率选择了一部分功能采用H5开发,从目前市面的大部分App来讲,大致分成Native App.Web App.Hybrid App三种方式,个人觉得目前以Hybri ...

  6. Android混合开发之WebView使用总结

    前言: 今天修改项目中一个有关WebView使用的bug,激起了我总结WebView的动机,今天抽空做个总结. 混合开发相关博客: Android混合开发之WebView使用总结 Android混合开 ...

  7. Android安全开发之ZIP文件目录遍历

    1.ZIP文件目录遍历简介 因为ZIP压缩包文件中允许存在“../”的字符串,攻击者可以利用多个“../”在解压时改变ZIP包中某个文件的存放位置,覆盖掉应用原有的文件.如果被覆盖掉的文件是动态链接s ...

  8. Android驱动开发之Hello实例

    Android驱动开发之Hello实例:   驱动部分 modified:   kernel/arch/arm/configs/msm8909-1gb_w100_hd720p-perf_defconf ...

  9. Android安全开发之WebView中的地雷

    Android安全开发之WebView中的地雷 0X01 About WebView 在Android开发中,经常会使用WebView来实现WEB页面的展示,在Activiry中启动自己的浏览器,或者 ...

随机推荐

  1. 【签名之坑】Decmail.GetBits()

    decimal类型有GetBits()方法 可以获取到值的int[4]值,进而获取到byte[16]值 在c#里,0m和0.00m获取到的byte[]是不一样的(具体为何不一样,自己百度) 在sql里 ...

  2. weex image

    weex 的image用来渲染图片, 可以使用img作为它的别名. 需要注意的是,他的长度可宽度必须指定, 不然它是不会工作的. 它没有任何的子组件. 有两个属性: src 用来指定图片的地址图片. ...

  3. 谈BFC和haslayout

    今天提到BFC和haslayout,就顺带在网上查查资料,总结一下它们. CSS2我们再熟悉不过,当然它里面我们需要掌握的,就是CSS2的选择器和布局,选择器总共31种.避开这个不说,我们说布局. 布 ...

  4. ajax教程

    本文来自w3school 简介: AJAX = Asynchronous JavaScript and XML 异步的javascript和xml ajax不是新的编程语言,而是一种使用现有标准的新方 ...

  5. CentOS7 SWAP 设置 (实测 笔记)

    首先查看当前的内存及swap情况(参数 -h,-m ) [root@centos ~]# free -h 查看swap信息,包括文件和分区的详细信息 [root@centos ~]# swapon - ...

  6. Python之路第一课Day8--随堂笔记(socket 承接上节---网络编程)

    本节内容 Socket介绍 Socket参数介绍 基本Socket实例 Socket实现多连接处理 通过Socket实现简单SSH 通过Socket实现文件传送 作业:开发一个支持多用户在线的FTP程 ...

  7. Usaco*Brownie Slicing

    Description Bessie烘焙了一块巧克力蛋糕.这块蛋糕是由R*C(1 <= R,C <= 500)个小的巧克力蛋糕组成的. 第i行,第j列的蛋糕有N_ij(1 <= N_ ...

  8. MVC辅助方法

    我相信很多人虽然经常用mvc去做一些东西,但是可能很少使用mvcHtml辅助方法 首先我们要创建一个mvc项目 二创建一个HtmlHelper文件夹 三编写文件 四调用辅助方法 调用辅助方法 和使用其 ...

  9. 非域环境下搭建自动故障转移镜像无法将 ALTER DATABASE 命令发送到远程服务器实例的解决办法

    非域环境下搭建自动故障转移镜像无法将 ALTER DATABASE 命令发送到远程服务器实例的解决办法 环境:非域环境 因为是自动故障转移,需要加入见证,事务安全模式是,强安全FULL模式 做到最后一 ...

  10. CYQ.Data+EasyUI开发:几个相关的问题CheckBox、Tree、TreeGrid

    前言: 话说到新的公司已经呆了三个星期了,从上班的第二天开始就一直在写项目文档和给开发人员培训,以至于我的QQ签名从"我不是来搞培训的“到最后直接换成”我是来搞培训的“. 虽然挂名开发经理, ...