如何在java中停止音频延迟?

时间:2016-09-05 22:17:24

标签: java audio lag javax.sound.sampled

我正在制作类似skype的程序。我有一个“ VoiceChat ”类来处理语音聊天连接。我有一个“ ClientAudio ”类来处理客户端音频输出。我还有一个“ ClientAudioRec ”来处理从服务器接收音频并播放它。在“ ClientAudio ”类中,我将音频数据存储在缓冲区中,直到它已满,以尝试减少延迟。然后我把它发送到服务器。如果我在呼叫中有两个人,那么除非缓冲区是1000,否则它会滞后。当我在呼叫中添加另一个人时,它会滞后以至于你无法理解任何人。但是我不希望每次有人加入时都扩展缓冲区,因为1000已经是两秒钟的延迟了。如果有人知道如何减少滞后或使其几乎立即真正有用。谢谢你提前!!!

VoiceChat(服务器端

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class VoiceChat extends Thread {
    private Socket s;
    private ObjectOutputStream out;
    private ObjectInputStream in;
    private Thread acceptThread;
    private int VoicePort;
    private int num;

    public VoiceChat(Socket sVoice, int VoicePort, Thread acceptThread) {
        s = sVoice;
        this.VoicePort = VoicePort;
        this.acceptThread = acceptThread;
        num = chat.threads.indexOf(this.acceptThread)+1;
        try {
            out = new ObjectOutputStream(s.getOutputStream());
            in = new ObjectInputStream(s.getInputStream());
            if(VoicePort <= 65511) {
                chat.users1_Voice.add(out);
            }else {
                chat.users2.add(out);
            }
        } catch (IOException e) {
            System.out.println("ERROR2");
            e.printStackTrace();
        }

    }
    public void run() {
            int bytesRead = 0;
            byte[] inBytes = new byte[100];
            while(bytesRead != -1) {
                    try {
                        bytesRead = in.read(inBytes, 0, inBytes.length);
                        }catch (IOException e) {
                        System.out.println("ERROR2");
                        if(VoicePort <= 65511) {
                            chat.users1_Voice.remove(out);
                        }else {
                            chat.users2.remove(out);
                        }
                    }
                    if(bytesRead > 0) {
                        System.out.println(chat.users1_Voice);
                            send(inBytes, bytesRead, out);
                            System.out.println("SENDING DATA");
                    }
              }
        }

    public void send(byte[] soundData, int bytesRead, ObjectOutputStream out) {
        if(VoicePort <= 65511) {
            for(ObjectOutputStream o : chat.users1_Voice) {
                try {
                    if(o != out) {
                        o.write(soundData, 0, bytesRead);
                        o.flush();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }else {
            for(ObjectOutputStream o : chat.users2) {
                try {
                    if(o != out) {
                        o.write(soundData, 0, bytesRead);
                        o.flush();
                    }
                } catch (IOException e) {
                }
            }
        }
    }
}

ClientAudio

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;

public class ClientAudio implements Runnable {
    private ObjectOutputStream out = null;
    private AudioFormat af;
    private TargetDataLine microphone;

ClientAudio(AudioFormat af) {
    this.af = af;
}
public void run() {
    try {
        client.voiceSocket = new Socket("***IP***", client.VoicePort);
        Thread car = new Thread(new ClientAudioRec(af));
        car.start();
        out = new ObjectOutputStream(client.voiceSocket.getOutputStream());
        DataLine.Info info = new DataLine.Info(TargetDataLine.class, af);
        microphone = (TargetDataLine)AudioSystem.getLine(info);
        microphone.open(af);
        microphone.start();
        int bytesRead = 0;
        int offset = 0;
        byte[] soundData = new byte[1000];
        while(bytesRead != -1 && client.callRunning == true) {
            bytesRead = microphone.read(soundData, 0, soundData.length);
            if(bytesRead >= 0) {
                offset += bytesRead;
                if(offset == soundData.length) {
                    out.write(soundData, 0, bytesRead);
                    offset = 0;
                }
            }
        }
        microphone.close();
        try {
            client.voiceSocket.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        System.out.println("Client Audio Stopped Because Client Disconnected From Call");
    } catch (IOException | LineUnavailableException e) {
        microphone.close();
        try {
            client.voiceSocket.close();
        } catch (IOException e1) {
            System.out.println("Plug Microphone In...");
        }
        System.out.println("Client Audio Stopped...");
    }
}
}

ClientAudioRec

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

public class ClientAudioRec implements Runnable {
    private SourceDataLine inSpeaker = null;
    private AudioFormat audioformat;
    private ObjectInputStream in;

ClientAudioRec(AudioFormat af) {
    audioformat = af;
    try {
        in = new ObjectInputStream(client.voiceSocket.getInputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void run() {
    DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioformat);
    try {
        inSpeaker = (SourceDataLine)AudioSystem.getLine(info);
        inSpeaker.open(audioformat);
    } catch (LineUnavailableException e1) {
        System.out.println("ERROR");
        e1.printStackTrace();
    }

    int bytesRead = 0;
    byte[] inSound = new byte[100000];
    inSpeaker.start();
    while(bytesRead != -1 && client.callRunning == true) {
        try{bytesRead = in.read(inSound, 0, inSound.length);} catch (Exception e){
            inSpeaker.close();
            System.out.println("Speaker Closed");
        }
        if(bytesRead >= 0) {
            inSpeaker.write(inSound, 0, bytesRead);
        }
    }
    inSpeaker.close();
    System.out.println("Speaker Closed Because Client Disconneted From Call");
}
}

0 个答案:

没有答案