那就可能是格式設定有錯,或者sample長度給的不對,
但如果是播播停停,尤其是遇到類似以下的錯誤訊息
W/AudioTrack(..): releaseBuffer() track 0x6eaf04d0 name=0x1 disabled, restarting
該怎麼處理呢?
會遇到上面的訊息,表示資料給的太慢,
如果是local的檔案,通常不會有問題,
但如果是網路streaming,因為資料來的速率不一,
有時可能會有buffer underflow的問題,
有二個作法,一個是在前端網路接收端加buffer,
一個是在後端要進AudioTrack時加buffer,
底下示範的方法就是第二個方法,
private static void queueAudioData(byte[] buf, int size) { if((audioPcmBufferDataCount + size)> audioBufferSize) { return; } if((audioPcmBufferFront + size) > audioBufferSize) { //rewind System.arraycopy(buf, 0, audioPCMData, audioPcmBufferFront, audioBufferSize - audioPcmBufferFront); audioPcmBufferDataCount += (audioBufferSize - audioPcmBufferFront); size -= (audioBufferSize - audioPcmBufferFront); audioPcmBufferFront = 0; } System.arraycopy(buf, 0, audioPCMData, audioPcmBufferFront, size); audioPcmBufferFront += size; audioPcmBufferDataCount += size; }
audio decoder解出來的PCM data,
先透過queueAudioData()存到一個queue buffer,
之後再穩定的將資料write到AudioTrack
private class playAudio extends Thread { @Override public void run() { super.run(); int len = 512; while(!isInterrupted()) { try { if(audioPcmBufferDataCount < len) { Thread.sleep(10); continue; } if((audioPcmBufferEnd + len) > audioBufferSize) writeSize = audioBufferSize - audioPcmBufferEnd; else writeSize = len; playAudioTrack.write(audioPCMData, audioPcmBufferEnd, writeSize); Thread.sleep(1); audioPcmBufferDataCount -= writeSize; audioPcmBufferEnd += writeSize; if(audioPcmBufferEnd >= audioBufferSize) audioPcmBufferEnd=0; if(playAudioTrack.getPlayState()!=AudioTrack.PLAYSTATE_PLAYING) { playAudioTrack.play(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
沒有留言:
張貼留言