首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >音频延迟-Java程序到安卓程序

音频延迟-Java程序到安卓程序
EN

Stack Overflow用户
提问于 2018-07-05 05:23:10
回答 1查看 74关注 0票数 1

我有两个Java线程,一个在我的电脑上,另一个在Android的手机上。我想通过UDP数据包(点对点连接)将从我电脑上的音频线路上获得的音频流式传输到Android的手机上。

一切都很好,除了有时音频延迟和我的主要问题是延迟。我已经尝试了不同的采样频率和不同的缓冲区大小,但我仍然在两个设备之间有延迟(1-2秒)。

那是我的代码。

Java音频发送器

代码语言:javascript
复制
(new Thread(() -> {

            while (true) {
                   System.out.println(">>"+status);
                while (status) {

                    try {

                        int size = tdl.read(buffer, 0, buffer.length);
                        if(size>0){
                        DatagramPacket sendPacket
                                = new DatagramPacket(buffer, size, hostAddress, port);
                        socket.send(sendPacket);
                        }
                    } catch (IOException ex) {
                        Logger.getLogger(AudioSender.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (java.lang.NullPointerException ne) {

                    }
                }
            }

        })).start();

 public static void setUpAudioDriverInput() throws LineUnavailableException {
    if (tdl != null) {
        tdl.close();
    }

    int channels = 1;
    int sampleSize = 16;
    boolean bigEndian = false;

    format = new AudioFormat(rate, sampleSize, channels, true, bigEndian);

    DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);

    Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();

    Mixer mixer = AudioSystem.getMixer(mixerInfoFinal.get(lineIndex));

    tdl = (TargetDataLine) mixer.getLine(info);
    tdl.open(format);
    tdl.start();

}

Java安卓音频接收器

代码语言:javascript
复制
  public void getStreaming(){


       getThread = new Thread(new Runnable() {
        @Override
        public void run() {

            try {

                System.out.println("Thread Streamer is Starting..  status2"+ status2);

                int rate = Integer.parseInt(((Spinner) findViewById(R.id.rateSpinner)).getSelectedItem().toString());
                int bufferSize = Integer.parseInt(((Spinner) findViewById(R.id.bufferSizeSpinner)).getSelectedItem().toString());

                String payload = ((EditText) findViewById(R.id.nameEditText)).getText().toString();
                payload += "#" + rate;
                payload += "#" + bufferSize;
                payload += "#";

                System.out.println(">>>"+payload);

                InetAddress address = InetAddress.getByName(((EditText) findViewById(R.id.ipAddressEditText)).getText().toString());
                DatagramPacket dp = new DatagramPacket(payload.getBytes(),payload.length(),address,8088);
                socket.send(dp);

               byte[] buffer = new byte[bufferSize];

                AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, rate, channelConfigOUT, audioFormat, buffer.length, AudioTrack.MODE_STREAM);
                audioTrack.play();


                DatagramPacket receivedPacket = new DatagramPacket(buffer,buffer.length);

                System.out.println("BufferSize "+ bufferSize);




                boolean skip=false;

                while(status2 && !Thread.currentThread().isInterrupted()){
                    try {
                        socket.receive(receivedPacket);
                    }catch(SocketTimeoutException ste){
                        skip=true;
                        Thread.currentThread().interrupt();
                        stopStreaming();

                    }
                    if(!skip) {
                        buffer = receivedPacket.getData();
                        audioTrack.write(buffer, 0, buffer.length);
                        System.out.println("aaa" + Thread.currentThread().getName());

                    }
                }

            } catch (SocketException e) {
                e.printStackTrace();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }



        }
    });

    getThread.start();

}

谢谢。

更新我发现这是我尝试的网络,它正在超级转发数据包。对于另一个网络,延迟真的减少到不到半秒。昨天,我可以用它看一部电影,延迟达到了极限。如果我会改进这个系统,我会让你知道的。

EN

回答 1

Stack Overflow用户

发布于 2018-07-05 05:31:19

您不应使用TargetDataLine读取大小来创建DatagramPacket。创建的数据包太多。

最好的方法是读取一些千字节的数据(即多个tdl读取),然后在一个“大”DatagramPacket中发送它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51180897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档