Android音频开发之AudioTrack实时播放

时间:2022-03-12 08:39:14

前言:

其实在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