【发布时间】:2023-11-15 14:35:01
【问题描述】:
我正在尝试通过服务器将音频发送到我播放它的安卓手机(流式传输)。 服务器每 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 数据包?我应该尝试在服务中进行接收吗???
【问题讨论】:
-
你在这 50 毫秒内处理了多少?也许你消耗的太少了?还有哪些质量方面?
-
不,我不这么认为,50 毫秒的缓冲区大小为 1600 字节。编码格式为 PCM 16 位,采样率为 16000 Hz。
标签: android audio android-asynctask audiotrack