【问题标题】:Read / Write streamed audio via TCP socket Java通过 TCP 套接字 Java 读取/写入流式音频
【发布时间】:2015-08-12 05:11:55
【问题描述】:

我是 Java 和套接字编程的新手,我正在寻找更多的起点/正确方向的点/验证我的思路。

总的来说,我想要实现的想法是:

  1. 捕获我录制为 .wav 的音频
  2. 通过 TCP 发送到我的服务器
  3. 决定是要播放录制的音频(在我的 tcp 服务器中处理和播放)还是通过 TCP 将音频发送到其他服务器以进行处理(如转录器或类似的东西)。

我遇到的麻烦是服务器端,老实说,这是因为我并不完全了解套接字编程。我想将音频作为原始音频接收到我的服务器(将字节/二进制数组作为参数传递)。对于我发现的大多数文档,基本上他们说打开套接字、打开输入/输出流、读/写、关闭流、关闭套接字。这适用于常规文本,但不适用于音频。我相信这可以通过音频来完成。对音频 .wav 执行此操作的一般想法是什么?是否有一个我不知道的 API 涵盖了这一点?




更新:2015 年 8 月 30 日
这是我目前拥有的 TCP 客户端/服务器代码。目前,我使用的“捕获的音频”只是我读入客户端输出流的现有 .wav 文件。我现在面临的问题是创建的 .wav 听起来不像原来的。这听起来像噪音,而且时间要短得多。

TCP 客户端代码:

Socket serverSocket = null;
DataOutputStream out = null;
BufferedReader in = null;

try {
    serverSocket = new Socket(serverHostname, port);
    out = new DataOutputStream(serverSocket.getOutputStream());
    in = new BufferedReader(
              new InputStreamReader(serverSocket.getInputStream()));
} catch (UnknownHostException e) {
    System.err.println("Don't know about host: " + serverHostname);
    System.exit(1);
} catch (IOException e) {
    System.err.println("Couldn't get I/O for the connection to: " + serverHostname);
    System.exit(1);
}

DataInputStream stdIn = new DataInputStream( 
                              new FileInputStream(".wav location"));

int readBytes;
byte[] temp = new byte[1024];

while( (readBytes = stdIn.read(temp, 0, temp.length)) != -1){
    out.write(temp, 0, readBytes);
}

out.flush();
out.close();
in.close();
stdIn.close();
serverSocket.close();
}

到目前为止,这是我的服务器代码:

public void clientConnect(int socketPort) {
        ServerSocket s_Socket = null; 

        try {
             s_Socket = new ServerSocket(socketPort);

             System.out.println ("SERVER Connection Socket Created");
             try {

                 System.out.println ("Waiting for CLIENT Connection");
                  while (true){
                      new TcpAudioStreaming (c_Socket = s_Socket.accept());
                      System.out.println("CLIENT: " + c_Socket.getInetAddress());
                      System.out.println("PORT: " + c_Socket.getPort());
                      System.out.println("LOCAL PORT: " + c_Socket.getLocalPort());
                  }
             }     
             catch (IOException e) { 
                  System.err.println("Accept failed."); 
                  System.exit(1); 
             }
        }

        catch (IOException e){
             System.err.println("Could not listen on port: " + socketPort); 
             System.exit(1); 
        }      
        finally {

             try {
                 s_Socket.close(); 
             }
             catch (IOException e){
                  System.err.println("Could not close port: " + socketPort); 
                  System.exit(1); 
             }
        }
    }


    public void run() {

        boolean end = false;
        System.out.println ("New Communication Thread Started");

        try {
            //DataOutputStream outStream = new DataOutputStream(c_Socket.getOutputStream()); 
            ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 
            DataInputStream inStream = new DataInputStream(c_Socket.getInputStream()); 

            int read;
            byte[] temp = new byte[1024];

            while( (read = inStream.read(temp, 0, temp.length)) != -1){
                outStream.write(temp, 0, read);
            }

            outStream.flush();
            byte[] audioBytes = outStream.toByteArray();

            writeWave(audioBytes);

            outStream.close(); 
            inStream.close(); 
            c_Socket.close();


        } 
        catch (IOException e) {
              System.err.println("Problem with Communication Server");
              System.exit(1); 
        } 

    }

    public void writeWave(byte[] audioArry) {

        String filePath = "new .wav path";

        AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, false);

        try {

            ByteArrayInputStream inStream = new ByteArrayInputStream(audioArry);
            long length = (long)(audioArry.length / audioFormat.getFrameSize());
            AudioInputStream audioInputStreamTemp = new AudioInputStream(inStream, audioFormat, length);


            File fileOut = new File(filePath);

            if (AudioSystem.isFileTypeSupported(AudioFileFormat.Type.WAVE, audioInputStreamTemp)) {
                System.out.println("Trying to write");
                AudioSystem.write(audioInputStreamTemp, AudioFileFormat.Type.WAVE, fileOut);
                System.out.println("Written successfully");
            }       
        }
        catch(Exception e) {
            e.printStackTrace();
        }

    }

【问题讨论】:

  • '不用于音频'为什么不呢?你从哪里得到这个想法的?这是假的。
  • ^^^ 是的....当然它适用于音频(和视频,假设您的 ISP 足够好)。我现在正在听流媒体音乐。计算机数据都是二进制的,如果它适用于文本,它将适用于音频等。
  • 我的意思是,我的工作示例是文本,而不是音频
  • 你根本没有使用BufferedReader,所以你应该删除它,服务器中的ByteArrayOutputStreamByteArrayInputStream都是多余的:你应该写下你从客户端目录到音频流。 "Couldn't get I/O for the connection to: " + serverHostname 不是一个足够的错误消息,无论 Java 教程可能包含什么。您必须打印异常本身。

标签: java sockets tcp audio-streaming


【解决方案1】:

Java 套接字或 TCP 不区分 ASCII 和二进制数据。解释是应用程序。

从一个简单的客户端/服务器应用程序开始,然后继续前进。有关介绍,您可以查看https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html

【讨论】:

  • 感谢 KDM 的建议。我实际上是从那里开始的,但是对于这方面的新手来说,我需要一点时间才能掌握。诚然,由于暑期课程,我没有机会做那么多工作,但我想我快到了。稍后我会在这里发布我到目前为止的代码。
猜你喜欢
  • 2011-02-14
  • 1970-01-01
  • 2016-04-24
  • 2014-10-19
  • 2014-07-23
  • 2022-01-25
  • 2013-04-27
  • 2015-08-29
  • 1970-01-01
相关资源
最近更新 更多