首页 > 解决方案 > UDP 服务器无法正确发回音频

问题描述

所以我在弄清楚如何正确接收来自服务器的音频时遇到了一些问题。目前客户端录制音频然后将其发送到服务器。在服务器上很好但是当我将它发送回他们的客户端时,每次我对着麦克风说话而不是实际的噪音/声音时,我都会听到一些静态声音。

服务器:

public static void main(String[] args) throws LineUnavailableException {
    new server();
}

public server() {
    Thread t1 = new Thread(this);
    t1.start();
}

@Override
public void run() {
    AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
    SourceDataLine speakers = null;


    ByteArrayOutputStream out = new ByteArrayOutputStream();

    DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
    try {
        speakers = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
    } catch (LineUnavailableException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        speakers.open(format);
    } catch (LineUnavailableException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    speakers.start();


    try {
        InetAddress address = InetAddress.getByName("127.0.0.1");

        DatagramSocket serverSocket = new DatagramSocket(5555);
        
        byte[] buffer = new byte[1024];
        DatagramPacket receive = new DatagramPacket(buffer, buffer.length);
        
        while (true) {
            serverSocket.receive(receive);

            //out.write(receive.getData(), 0, receive.getData().length);
            //speakers.write(receive.getData(), 0, receive.getData().length);
            
            InetAddress ip = receive.getAddress();
            int clientPort = receive.getPort();
            
                DatagramPacket send = new DatagramPacket(receive.getData(), receive.getData().length, ip, clientPort);
                serverSocket.send(send);
            
        }

    } catch (Exception ex) {
        System.out.println("Timeout error: " + ex.getMessage());
        ex.printStackTrace();
    } 
    
}

客户:

public class client {

public static void main(String[] args) throws Exception {
    new client();
}

public client() throws Exception {
    AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);

    DatagramSocket socket = new DatagramSocket();

    try {
        Thread thread = new Thread(new Runnable() {
            
            @Override
            public void run() {
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                
                while (true) {
                    try {
                        socket.receive(packet);
                        System.out.println("received");
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    
                    DataLine.Info dli = new DataLine.Info(SourceDataLine.class, format);
                    SourceDataLine speakers = null;
                    try {
                        speakers = (SourceDataLine)AudioSystem.getLine(dli);
                    } catch (LineUnavailableException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    
                    try {
                        speakers.open();
                        speakers.start();
                    } catch (LineUnavailableException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    
                    speakers.write(packet.getData(), 0, packet.getData().length);//here the client should hear the response back
                                                                                 //but it doesn't work
                }
            }
        });
        thread.start();
        
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
        TargetDataLine microphone = (TargetDataLine) AudioSystem.getLine(info);
        microphone.open(format);

        // for report
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int CHUNK_SIZE = 1024;
        byte[] data = new byte[microphone.getBufferSize() / 5];
        microphone.start();

        try {
            InetAddress address = InetAddress.getByName("127.0.0.1");
            int numBytesRead;

            for (;;) {
                numBytesRead = microphone.read(data, 0, CHUNK_SIZE);
                // bytesRead += numBytesRead;
                // write the mic data to a stream for use later
                out.write(data, 0, numBytesRead);

                DatagramPacket request = new DatagramPacket(data, numBytesRead, address, 5555);
                socket.send(request);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }



    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

标签: javanetworkingaudioudp

解决方案


Client代码中,您将在收到每个数据报后创建一个新SourceDataLine 扬声器。实例化应该在while循环之外,类似于您对TargetDataLine.


推荐阅读