那就可能是格式設定有錯,或者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();
}
}
}
}

沒有留言:
張貼留言