【发布时间】:2015-08-12 05:11:55
【问题描述】:
我是 Java 和套接字编程的新手,我正在寻找更多的起点/正确方向的点/验证我的思路。
总的来说,我想要实现的想法是:
- 捕获我录制为 .wav 的音频
- 通过 TCP 发送到我的服务器
- 决定是要播放录制的音频(在我的 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,所以你应该删除它,服务器中的ByteArrayOutputStream和ByteArrayInputStream都是多余的:你应该写下你从客户端目录到音频流。"Couldn't get I/O for the connection to: " + serverHostname不是一个足够的错误消息,无论 Java 教程可能包含什么。您必须打印异常本身。
标签: java sockets tcp audio-streaming