我正在尝试通过服务器将音频发送到我在其中播放(流式传输)的android手机。
服务器每50毫秒发送一次音频字节。
此解决方案有效,但不合适(在同一循环中接收和写入音轨(需要花费一些时间))
private class SoundTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
[...]
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 16000,4, AudioFormat.ENCODING_PCM_16BIT, BUF_SIZE, AudioTrack.MODE_STREAM);
[...]
byte[] output;
at.play();
byte[] buf = new byte[BUF_SIZE];
//Here is the loop
while(true)
{
DatagramPacket pack = new DatagramPacket(buf, BUF_SIZE);
socket.receive(pack);
at.write(pack.getData(), 0, pack.getLength());
}
}
}
因此,我尝试将接收和写入分为两个线程,但是它不起作用,几秒钟后声音震荡!
我的两个线程(使用ArrayBlockingQueue)
制片人:
public void run() {
[...]
byte[] buf = new byte[bufferSize];
while(true)
{
DatagramPacket pack = new DatagramPacket(buf, bufferSize);
socket.receive(pack);
queueAudio.put(pack);
}
}
消费者:
public void run() {
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, 4, AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM);
audioTrack.play();
while(true)
{
DatagramPacket packet;
try
{
packet = queueAudio.take();
audioTrack.write(packet.getData(), 0, packet.getData().length);
}
我注意到当队列的大小等于1时,声音是正常的;而当队列的大小大于1(2-3秒后)时,声音就断断续续。
有人可以向我解释为什么我的音轨不起作用吗?
提前致谢 !
编辑:
好的,我了解这个问题。问题来自UDP数据包的接收,通常我应该每50毫秒接收一次我的数据包。
我计算了接收两个数据包之间的时间间隔,看来有时这个间隔优于100毫秒,而在此之后它小于1毫秒!
发生这种情况时,声音会变得断断续续。我简单地解决了这个问题:当时间间隔小于1毫秒时,我不会将数据放入队列中。
这样可以正常工作,声音并不震荡,但有时几乎没有声音。
我该如何解决?有没有办法定期接收我的UDP数据包?我应该尝试在服务中进行接收吗?
最佳答案
您对AudioTrack使用的缓冲区大小应比写入它的块的大小大。从AudioTrack类的文档中:
使用更大的缓冲区创建AudioTrack:
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC,
16000, 4,
AudioFormat.ENCODING_PCM_16BIT,
BUF_SIZE * 2, // use a buffer twice the size of
// the chunks you will write to it
AudioTrack.MODE_STREAM);
但是,请继续写相同大小的块。希望双缓冲可以消除抖动。如果这样不起作用,您也可以尝试增加
BUF_SIZE
。关于android - AudioTrack流不连贯,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28957474/