我正在尝试通过服务器将音频发送到我在其中播放(流式传输)的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/

10-12 03:53