【问题标题】:UDP server doesn't send audio properly backUDP 服务器无法正确发回音频
【发布时间】:2021-02-19 20:44:26
【问题描述】:

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

服务器:

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();
    }
}

}

【问题讨论】:

  • 您是否为收到的每个数据包创建一个新的 SourceDataLine?
  • 错了吗?答案是肯定的。
  • 很高兴有帮助!你能写下答案并标记它已解决吗? (如果您愿意,我可以这样做。)主要是不要浪费寻找问题以帮助解决的好人的时间,并使解决方案更容易被有类似问题并遇到此线程的人发现通过搜索。

标签: java networking audio udp


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2012-04-18
    • 2014-06-20
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多