繁体   English   中英

JAVA(在同一台计算机上发送音频流一台服务器四个客户端)

[英]JAVA (sending audio streaming One Server Four Clients in the same machine)

我之前问过: https : //stackoverflow.com/questions/35344535/dcom-alternative-for-java-sending-audio-streaming-in-the-same-machine

我想使用一台服务器从麦克风捕获音频并发送给客户端(0或4)...

PD:我正在检查以下问题: 通过TCP发送音频流,UnsupportedAudioFileException,但面向具有One Client解决方案的一台服务器。 其他问题: Java-通过Java套接字广播语音,使用Java 从麦克 风流式 传输音频

我当时想使用TCP(服务器/客户端模型),但是服务器和4个客户端将接收数据(音频流),我不知道是否有可能实现此替代方案(我担心端口管理)....

这里是我的初稿(仍然无法正常工作,因为我有疑问,我正在考虑如何解决我的问题)

变量:

static boolean bThreadCapture = false;
static boolean bThreadServer = false;
static ByteArrayOutputStream myByteArrayOutStream;
ExecutorService myServerPool = Executors.newFixedThreadPool(4);
static Thread myThreadServer = null;

现在我头疼

  final int iServerPort = 2370;
  final AudioFormat myAudioFormat = new AudioFormat(8000,8,1,false, true);
  final DataLine.Info myDataLineInfo = new DataLine.Info(TargetDataLine.class, myAudioFormat);
  if (!AudioSystem.isLineSupported(myDataLineInfo)) {
    System.out.println("Line not supported");
    System.exit(0);
  }
  try {
    final TargetDataLine myTargetDataLine = (TargetDataLine) AudioSystem.getLine(myDataLineInfo);
    myTargetDataLine.open(myAudioFormat);
    myByteArrayOutStream = null;

    //BEGIN definition Thread for CAPTURING AUDIO FROM MIC
    Runnable runnAudioCapture = new Runnable() {
      int bufferSize = (int) myAudioFormat.getSampleRate()* myAudioFormat.getFrameSize();
      byte buffer[] = new byte[bufferSize];
      public void run() {
        myByteArrayOutStream = new ByteArrayOutputStream();
        bThreadCapture = true;
        while (bThreadCapture) {
          try {
            int count = myTargetDataLine.read(buffer, 0, buffer.length);
            if (count > 0) {
              myByteArrayOutStream.write(buffer, 0, count);
              //  HERE: I need to send the bytes of Sound to all active Threads Client (from 1 until 4)
              //  But, How to know what (how much and which) are active threads client?
              //  How to access to each Executor?
            }
          } catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
            System.err.println("TargetDataLine problems: " + e);
          }
        }
        try {
          if (myByteArrayOutStream != null) myByteArrayOutStream.close();
        } catch (IOException e) {  }
      }
    };
    //END definition Thread for CAPTURING AUDIO FROM MIC


    //BEGIN definition Thread for ATTENDANT SERVER CLIENT (Still not defined) 
    myThreadServer = new Thread() {
      @Override
      public void run() {
        try {
          SrvrSocketProducer = new ServerSocket(iServerPort);
          System.out.println("Server Listening on port number: "+iServerPort);
        } catch (IOException e) {
          System.out.println("Could not listen on port: "+iServerPort);
        }
        new Thread(runnAudioCapture).start();  //BEGIN AUDIO CAPTURE
        while(bThreadServer) {
          Socket clientSocket = null;
          try {
            clientSocket = SrvrSocketProducer.accept(); 
          } catch (IOException e) {
            if(!bThreadServer) {
              System.out.println("Server Stopped.") ;
              break;
            }
            throw new RuntimeException("Error accepting client connection", e);
          }
          myServerPool.execute(new runnWorkerListener(clientSocket,myAudioFormat));
        }
        myServerPool.shutdown();
        bThreadCapture = false;  //STOP AUDIO CAPTURE
      }
    };
    //END definition Thread for ATTENDANT SERVER CLIENT (Still not defined) 
    myThreadServer.start();
  } catch (LineUnavailableException ex) {
    System.out.println(ex.toString());
  }

问题:

(与runnAudioCapture代码合并以找到帮助)

1. HERE: I need to send the bytes of Sound to all ACTIVE Threads Client (from 1 until 4)
2. But, How to know what (how much and which) are active threads client?
3. How to access to each Executor?

现在工作人员线程-

  class runnWorkerListener implements Runnable {
    Socket innerClientSocket = null;
    AudioFormat innerAdfmt = null;
    public runnWorkerListener(Socket clientSocket, AudioFormat audioFormat) {
      innerClientSocket = clientSocket;
      innerAdfmt = audioFormat;
    }
    public void run() {
      try {
        InputStream input  = innerClientSocket.getInputStream();
        OutputStream output = innerClientSocket.getOutputStream();
        // Now How Can I to Comunicate with runnAudioCapture?
        while (RunningClientAttender /*This variable still is not defined*/) {
          // I need to send (thread client here Not defined) EACH bytes from runnAudioCapture
        }
        output.close();
        input.close();
        System.out.println("Request processed: ");
      } catch (IOException e) {
        //report exception somewhere.
        e.printStackTrace();
      }
    }
  }

问题:

(合并到runnWorkerListener代码中以找到帮助)

1. Now How Can I to Comunicate with runnAudioCapture?
2. I need to send (thread client here Not defined) EACH bytes from runnAudioCapture

我的怀疑与以下方面有关:一个专用于音频捕获的线程一个专用于使用Pool接收客户端(1、2、3或4)并创建线程工作程序的线程(一个线程工作程序与“远程”客户端进行通信)

我不知道句柄使Capturer线程Capturer与每个Worker线程同步...

谢谢...

不幸的是,在Java中,流只能一次由一个人使用。 您有一个流myByteArrayOutStream ,并且想要在4个TCP连接之间共享它。

我建议您将音频数据写入文件。 每次客户端连接时,都将文件的所有内容流式传输到该客户端(您可以打开文件,跳到最后,并且仅在需要时流式传输新内容)。 您将需要为每个客户端创建一个新线程。

如果您希望用Java构建像Skype音频之类的东西,那么这比仅使用TCP还要复杂一些。 TCP是可靠地从A到B获取数据的一种方法。 对于音频,通常希望它是从A到B,但是是实时的。 如果在此过程中丢失了数据包,则您不希望返回并重新传输它,因为这样会给通话带来延迟。 UDP是TCP的替代方案,可能更适合您的方案。 它发送单个数据包,并且不保证它们将按顺序到达,甚至根本不到达。 但是它不会停止并等待丢失的数据包。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM