Java 麦克风流不清晰

Java 麦克风流不清晰,java,udp,streaming,Java,Udp,Streaming,我试图通过UDP传输麦克风,但我的输出太嘈杂,无法理解输入音频。这是我的密码: 服务器端: import java.io.DataOutputStream; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHos

我试图通过UDP传输麦克风,但我的输出太嘈杂,无法理解输入音频。这是我的密码:

服务器端:

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Port;
import javax.sound.sampled.TargetDataLine;

public class MicPlayer {

    private static final String IP_TO_STREAM_TO   = "localhost" ;
    private static final int PORT_TO_STREAM_TO     = 8888 ;

    /** Creates a new instance of MicPlayer */
    public MicPlayer() {

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
    Mixer.Info minfo[] = AudioSystem.getMixerInfo() ;
    for( int i = 0 ; i < minfo.length ; i++ )
    {
     System.out.println( minfo[i] ) ;    
    }


    if (AudioSystem.isLineSupported(Port.Info.MICROPHONE)) {
    try {


      DataLine.Info dataLineInfo = new DataLine.Info(
              TargetDataLine.class , getAudioFormat() ) ;
     final TargetDataLine targetDataLine = (TargetDataLine)AudioSystem.getLine( dataLineInfo  ) ;
      targetDataLine.open( getAudioFormat() );
      targetDataLine.start();
      byte tempBuffer[] = new byte[targetDataLine.getBufferSize() / 5] ;
      int cnt = 0 ;
      while( true )
      {
      targetDataLine.read( tempBuffer , 0 , tempBuffer.length );
      sendThruUDP( tempBuffer ) ;
      }

    }
    catch(Exception e )
    {
    System.out.println(" not correct " ) ;
    System.exit(0) ;
    }
    }



    }


    public static AudioFormat getAudioFormat(){
    float sampleRate = 8000.0F;
    //8000,11025,16000,22050,44100
    int sampleSizeInBits = 16;
    //8,16
    int channels = 1;
    //1,2
    boolean signed = true;
    //true,false
    boolean bigEndian = false;
    //true,false
    return new AudioFormat( sampleRate, sampleSizeInBits, channels, signed, bigEndian );
    }


    public static void sendThruUDP( byte soundpacket[] )
    {
       try
       {
       DatagramSocket sock = new DatagramSocket() ; 
       sock.send( new DatagramPacket( soundpacket , soundpacket.length , InetAddress.getByName( IP_TO_STREAM_TO ) , PORT_TO_STREAM_TO ) ) ; 
       sock.close() ;
       }
       catch( Exception e )
       {
       e.printStackTrace() ;
       System.out.println(" Unable to send soundpacket using UDP " ) ;   
       }

    }

    }

我确信我的连接正常,但我不知道为什么我的输出如此嘈杂。我快发疯了,我要工作一周,请帮帮我。谢谢。

原因可能是您的数据报数据包太小,这会导致您发送大量的数据包,从而产生大量开销。这可能会导致巨大的数据包丢失率,并使它们以错误的顺序到达

因此,请增大缓冲区大小:

byte tempBuffer[] = new byte[8192] ;
这来自JavaDoc:

此方法会一直阻塞,直到收到数据报为止。数据报数据包对象的长度字段包含所接收消息的长度如果消息长度超过数据包长度,则消息将被截断。

这可能也是一个问题。尝试在发送和接收数据包时使用相同的大小

byte soundpacket[] = new byte[8192];

此外,不要连续打开和关闭扬声器的音频线。也不要连续创建DatagramSockets。创建一个,并保留它。

为什么要使用UDP?我想你应该如何使用TCP来实现这种应用。那么,你能告诉我你使用的是哪种API吗?@user2336315,我不知道如何使用TCP:(如果你知道,你能帮我吗?@Touregsys:我建议在这里使用UDP。如果你想学习TCP,请阅读我的回答:@MartijnCourteaux虽然UPD更快,但TCP保证数据包在应用层按顺序到达并且没有错误。此外,许多防火墙和路由器没有配置为允许UDP数据包。但是@Touregsys可以两种方法都试一下,看看哪种方法最合适。事实上,我认为他的问题是,由于UDP不是面向连接的,所以数据包“一起”到达并且没有特定的顺序进行处理,并且可能不同步。因此,我建议也让UDP数据包包含一个序列号,在读取数据时,确保您按顺序读取数据,或者至少在新数据包到达后不读取旧数据包谢谢您的回答,但我仍然无法解决我的问题这是有道理的,我不明白我是否应该在sendThruUDP函数中使用这个“DatagramSocket sock=new DatagramSocket();”。当我使用DatagramSocket作为全局变量时,它工作得更干净。但我仍然有一点杂音。我不明白如何“不要连续打开和关闭扬声器的音频线”第二部分。非常感谢。等待您的答案。您的toSpeaker方法每次调用时都会打开一条新的音频线。将这些变量设置为全局变量。
byte soundpacket[] = new byte[8192];