前言:
其實在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