我成功地通过TCP套接字发送和读取文本和图像数据 . 但我无法发送和读取音频流数据 .
服务器上的示例代码:
public class ServerAudio {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
ServerSocket serverSocker = new ServerSocket();
Socket client = null;
serverSocker.bind(new InetSocketAddress(6666));
if (serverSocker.isBound()) {
client = serverSocker.accept();
OutputStream out = client.getOutputStream();
while (true) {
AudioInputStream ain = testPlay("C:/Users/Public/Music/Sample Music/adios.wav");
if (ain != null) {
AudioSystem.write(ain, AudioFileFormat.Type.WAVE, out);
}
}
}
serverSocker.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static AudioInputStream testPlay(String filename) {
AudioInputStream din = null;
try {
File file = new File(filename);
AudioInputStream in = AudioSystem.getAudioInputStream(file);
System.out.println("Before :: " + in.available());
AudioFormat baseFormat = in.getFormat();
AudioFormat decodedFormat =
new AudioFormat(AudioFormat.Encoding.PCM_UNSIGNED, baseFormat.getSampleRate(),
8, baseFormat.getChannels(), baseFormat.getChannels(),
baseFormat.getSampleRate(), false);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
System.out.println("After :: " + din.available());
return din;
} catch (Exception e) {
// Handle exception.
e.printStackTrace();
}
return din;
}
}
客户端的示例代码:
public class RDPPlayAudioBytes {
private static Socket socket;
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// SocketAddress socketAddress = new InetSocketAddress("172.19.1.50", 4444);
try {
Socket socket = new Socket("172.19.0.109", 6666);
// socket.connect(socketAddress, 10000);
if (socket != null && socket.isConnected()) {
InputStream inputStream = socket.getInputStream();
// DataInputStream din=new DataInputStream(inputStream);
while (inputStream != null) {
if (inputStream.available() > 0) {
System.out.println(inputStream.available());
InputStream bufferedIn = new BufferedInputStream(inputStream);
System.out.println("********** Buffred *********" + bufferedIn.available());
AudioInputStream ais = AudioSystem.getAudioInputStream(bufferedIn);
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} /*
* catch (LineUnavailableException e) { // TODO Auto-generated catch block
* e.printStackTrace(); }
*/catch (UnsupportedAudioFileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我在哪里得到例外
javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input stream
at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
我观察到服务器正在向客户端发送35394字节数据,但在客户端,我们正在接收8192字节数据 . 我无法理解为什么客户端缺少字节 .
请帮我如何通过TCP套接字发送音频流 .
2 回答
The Server: 服务器只是流式传输声音文件的字节 . 没有涉及AudioSytem . 将声音文件作为参数传递:
AudioServer类的代码:
The client: 客户端可以播放通过命令行传递的声音文件,以便测试是否有效:
在没有参数的情况下调用它连接到服务器并播放通过Socket接收的文件:
码:
AudioServer和AudioClient使用的实用程序类:
TCP可靠时将完全接收字节 . 还有一个小问题 . 您需要播放音频流中接收的音频,只创建音频输入流不会播放 . 可以存在用于播放所接收的音频的不同可能技术 . 您可以使用 Java Sound API 中的 Clip 或 SourceDataLine . 另外,不要多次创建AudioInputStream . 只需创建一次并使用它 .
这是您可以用来播放接收音频的可能解决方案之一 .
您可能需要根据您的要求实施不同的实施方案 . 这只是一个演示如何使用 AudioInputStream 使用 Clip 播放音频 . 您可能会注意到我发布的代码中有很多更改 . 我希望你能理解这一点 .
您可以参考Java Sound API文档以深入了解playing audio的基础知识 .
NOTE :
为了您的知识,您可能需要 implement a listener ,以便在音频剪辑播放完毕之前程序不会关闭 . 在当前的实现中,由于使用了循环,它不会发生 . 但是最好使用一个监听器 . 你可以参考this post .
您还可以将音频数据读入byte [],然后在收到后立即播放 . 实施将略有改变 .