red*_*c01 5 java sockets tcp audio-recording audio-streaming
我创建了一个从客户端接收声音的服务器应用程序,然后我广播这个存储为字节的声音,并将字节发送回连接到服务器的客户端.现在我只使用一个客户端进行测试,而客户端正在接收语音,但声音一直都是口吃.有人可以告诉我我做错了什么吗?
我想我理解为什么声音播放不顺畅但不明白如何解决问题.
代码是吼叫.
客户端:
public void captureAudio()
{
Runnable runnable = new Runnable(){
public void run()
{
first=true;
try {
final AudioFileFormat.Type fileType = AudioFileFormat.Type.AU;
final AudioFormat format = getFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
line = (TargetDataLine)AudioSystem.getLine(info);
line.open(format);
line.start();
int bufferSize = (int) format.getSampleRate()* format.getFrameSize();
byte buffer[] = new byte[bufferSize];
out = new ByteArrayOutputStream();
objectOutputStream = new BufferedOutputStream(socket.getOutputStream());
running = true;
try {
while (running) {
int count = line.read(buffer, 0, buffer.length);
if (count > 0) {
objectOutputStream.write(buffer, 0, count);
out.write(buffer, 0, count);
InputStream input = new ByteArrayInputStream(buffer);
final AudioInputStream ais = new AudioInputStream(input, format, buffer.length /format.getFrameSize());
}
}
out.close();
objectOutputStream.close();
}
catch (IOException e) {
System.exit(-1);
System.out.println("exit");
}
}
catch(LineUnavailableException e) {
System.err.println("Line Unavailable:"+ e);
e.printStackTrace();
System.exit(-2);
}
catch (Exception e) {
System.out.println("Direct Upload Error");
e.printStackTrace();
}
}
};
Thread t = new Thread(runnable);
t.start();
}
Run Code Online (Sandbox Code Playgroud)
private void playAudio() {
//try{
Runnable runner = new Runnable() {
public void run() {
try {
InputStream in = socket.getInputStream();
Thread playTread = new Thread();
int count;
byte[] buffer = new byte[100000];
while((count = in.read(buffer, 0, buffer.length)) != -1) {
PlaySentSound(buffer,playTread);
}
}
catch(IOException e) {
System.err.println("I/O problems:" + e);
System.exit(-3);
}
}
};
Thread playThread = new Thread(runner);
playThread.start();
//}
//catch(LineUnavailableException e) {
//System.exit(-4);
//}
}//End of PlayAudio method
private void PlaySentSound(final byte buffer[], Thread playThread)
{
synchronized(playThread)
{
Runnable runnable = new Runnable(){
public void run(){
try
{
InputStream input = new ByteArrayInputStream(buffer);
final AudioFormat format = getFormat();
final AudioInputStream ais = new AudioInputStream(input, format, buffer.length /format.getFrameSize());
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
sline = (SourceDataLine)AudioSystem.getLine(info);
sline.open(format);
sline.start();
Float audioLen = (buffer.length / format.getFrameSize()) * format.getFrameRate();
int bufferSize = (int) format.getSampleRate() * format.getFrameSize();
byte buffer2[] = new byte[bufferSize];
int count2;
ais.read( buffer2, 0, buffer2.length);
sline.write(buffer2, 0, buffer2.length);
sline.flush();
sline.drain();
sline.stop();
sline.close();
buffer2 = null;
}
catch(IOException e)
{
}
catch(LineUnavailableException e)
{
}
}
};
playThread = new Thread(runnable);
playThread.start();
}
}
Run Code Online (Sandbox Code Playgroud)
除了 HefferWolf 的回答之外,我还要补充一点,通过发送从麦克风读取的音频样本,您浪费了大量带宽。您不会说您的应用程序是否仅限于本地网络,但如果您通过 Internet 访问,则在发送/接收时压缩/解压缩音频是很常见的。
一种常用的压缩方案是SPEEX 编解码器(此处提供了 Java 实现),如果您不熟悉音频采样/压缩,尽管文档看起来有点吓人,但它相对易于使用。
在客户端,您可以使用org.xiph.speex.SpeexEncoder来进行编码:
SpeexEncoder.init()初始化编码器(这将有相匹配的采样率,声道数和您的字节顺序AudioFormat),然后SpeexEncoder.processData() 对帧进行编码,SpeexEncoder.getProcessedDataByteSize()并SpeexEncoder.getProcessedData()获取编码数据在客户端使用org.xiph.speex.SpeexDecoder解码您收到的帧:
SpeexDecoder.init() 使用与编码器相同的参数初始化解码器,SpeexDecoder.processData() 解码一帧,SpeexDecoder.getProcessedDataByteSize()并SpeexDecoder.getProcessedData()获取编码数据我已经概述了更多涉及的内容。例如,您必须将数据吐出到正确的编码大小,这取决于采样率、通道和每个样本的位数,但是您会看到通过网络。
您将声音数据包相当随机地分成 1000000 字节的片段,并在客户端播放这些片段,而不考虑您在服务器端计算的采样率和帧大小,因此您最终会将声音和平分为属于两个部分一起。
您需要在服务器上解码与在客户端发送的相同块。也许使用 http multipart 发送它们会更容易(其中分割数据非常容易),然后通过套接字以基本方式进行发送。最简单的方法是使用 apache commons http 客户端,看看这里: http: //hc.apache.org/httpclient-3.x/methods/multipartpost.html
| 归档时间: |
|
| 查看次数: |
12710 次 |
| 最近记录: |