将连续字节[]数据发送到Java中的DatagramSocket,DatagramPacket
Posted
技术标签:
【中文标题】将连续字节[]数据发送到Java中的DatagramSocket,DatagramPacket【英文标题】:send continous bytes[] data into DatagramSocket,DatagramPacket in java 【发布时间】:2013-06-18 16:31:21 【问题描述】:我正在制作一个 java 桌面应用程序,我正在从麦克风录制语音,并且在 LAN 中实时希望将此语音数据发送到另一台计算机系统,反之亦然。
我可以通过麦克风录制声音并输出到系统中的扬声器。现在使用 UDP 数据报套接字也想这样做,但是 UDPServer 没有接收到数据流(字节 [])。
这里是代码:VUClient.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.sound.sampled.*;
public class VUClient extends JFrame
boolean stopaudioCapture = false;
ByteArrayOutputStream byteOutputStream;
AudioFormat adFormat;
TargetDataLine targetDataLine;
AudioInputStream InputStream;
SourceDataLine sourceLine;
Graphics g;
public static void main(String args[])
new VUClient();
public VUClient()
final JButton capture =
new JButton("Capture");
final JButton stop =
new JButton("Stop");
final JButton play =
new JButton("Playback");
capture.setEnabled(true);
stop.setEnabled(false);
play.setEnabled(false);
capture.addActionListener(
new ActionListener()
public void actionPerformed(
ActionEvent e)
capture.setEnabled(false);
stop.setEnabled(true);
play.setEnabled(false);
captureAudio();
);
getContentPane().add(capture);
stop.addActionListener(
new ActionListener()
public void actionPerformed(
ActionEvent e)
capture.setEnabled(true);
stop.setEnabled(false);
play.setEnabled(true);
stopaudioCapture = true;
targetDataLine.close();
);
getContentPane().add(stop);
play.addActionListener(
new ActionListener()
@Override
public void actionPerformed(
ActionEvent e)
playAudio();
);
getContentPane().add(play);
getContentPane().setLayout(new FlowLayout());
setTitle("Capture/Playback Demo");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 100);
getContentPane().setBackground(Color.white);
setVisible(true);
g = (Graphics) this.getGraphics();
private void captureAudio()
try
adFormat = getAudioFormat();
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, adFormat);
targetDataLine = (TargetDataLine) Audiosystem.getLine(dataLineInfo);
targetDataLine.open(adFormat);
targetDataLine.start();
Thread captureThread = new Thread(new CaptureThread());
captureThread.start();
catch (Exception e)
StackTraceElement stackEle[] = e.getStackTrace();
for (StackTraceElement val : stackEle)
System.out.println(val);
System.exit(0);
private void playAudio()
try
byte audioData[] = byteOutputStream.toByteArray();
// System.out.println("byte auto "+byteOutputStream.toString());
InputStream byteInputStream = new ByteArrayInputStream(audioData);
AudioFormat adFormat = getAudioFormat();
InputStream = new AudioInputStream(byteInputStream, adFormat, audioData.length / adFormat.getFrameSize());
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, adFormat);
sourceLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceLine.open(adFormat);
sourceLine.start();
Thread playThread = new Thread(new PlayThread());
playThread.start();
catch (Exception e)
System.out.println(e);
System.exit(0);
private AudioFormat getAudioFormat()
float sampleRate = 8000.0F;
int sampleInbits = 16;
int channels = 1;
boolean signed = true;
boolean bigEndian = false;
return new AudioFormat(sampleRate, sampleInbits, channels, signed, bigEndian);
class CaptureThread extends Thread
byte tempBuffer[] = new byte[10000];
public void run()
byteOutputStream = new ByteArrayOutputStream();
stopaudioCapture = false;
try
DatagramSocket clientSocket = new DatagramSocket();
// InetAddress IPAddress = InetAddress.getByName("192.168.64.142");
InetAddress IPAddress = InetAddress.getByName("localhost");
while (!stopaudioCapture)
int cnt = targetDataLine.read(tempBuffer, 0, tempBuffer.length);
if (cnt > 0)
DatagramPacket sendPacket = new DatagramPacket(tempBuffer, tempBuffer.length, IPAddress, 9876);
clientSocket.send(sendPacket);
byteOutputStream.write(tempBuffer, 0, cnt);
// System.out.print(cnt);
// DatagramPacket sendPacket = new DatagramPacket(byteOutputStream, 10000, IPAddress, 9876);
// clientSocket.send(sendPacket);
byteOutputStream.close();
catch (Exception e)
System.out.println("CaptureThread::run()" + e);
System.exit(0);
class PlayThread extends Thread
byte tempBuffer[] = new byte[10000];
public void run()
try
// DatagramSocket clientSocket = new DatagramSocket();
// InetAddress IPAddress = InetAddress.getByName("192.168.64.142");
// InetAddress IPAddress = InetAddress.getByName("localhost");
int cnt;
while ((cnt = InputStream.read(tempBuffer, 0,tempBuffer.length)) != -1)
if (cnt > 0)
// DatagramPacket sendPacket = new DatagramPacket(tempBuffer, tempBuffer.length, IPAddress, 9876);
// clientSocket.send(sendPacket);
// sourceLine.write(tempBuffer, 0, cnt);
// sourceLine.drain();
// sourceLine.close();
catch (Exception e)
System.out.println(e);
System.exit(0);
// Class End
VUServer.java
import java.io.*;
import java.net.*;
import javax.sound.sampled.*;
public class VUServer
ByteArrayOutputStream byteOutputStream;
AudioFormat adFormat;
TargetDataLine targetDataLine;
AudioInputStream InputStream;
SourceDataLine sourceLine;
private AudioFormat getAudioFormat()
float sampleRate = 8000.0F;
int sampleInbits = 16;
int channels = 1;
boolean signed = true;
boolean bigEndian = false;
return new AudioFormat(sampleRate, sampleInbits, channels, signed, bigEndian);
public static void main(String args[])
new VUServer().runVOIP();
public void runVOIP()
try
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[10000];
while (true)
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
// String sentence = new String(receivePacket.getData());
System.out.println("RECEIVED: ");// + sentence);
try
byte audioData[] = receivePacket.getData();//byteOutputStream.toByteArray();
// System.out.println("byte auto "+byteOutputStream.toString());
InputStream byteInputStream = new ByteArrayInputStream(audioData);
AudioFormat adFormat = getAudioFormat();
InputStream = new AudioInputStream(byteInputStream, adFormat, audioData.length / adFormat.getFrameSize());
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, adFormat);
sourceLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceLine.open(adFormat);
sourceLine.start();
Thread playThread = new Thread(new PlayThread());
playThread.start();
catch (Exception e)
System.out.println(e);
System.exit(0);
catch (Exception e)
e.printStackTrace();
class PlayThread extends Thread
byte tempBuffer[] = new byte[10000];
public void run()
try
int cnt;
while ((cnt = InputStream.read(tempBuffer, 0,tempBuffer.length)) != -1)
if (cnt > 0)
sourceLine.write(tempBuffer, 0, cnt);
sourceLine.drain();
sourceLine.close();
catch (Exception e)
System.out.println(e);
System.exit(0);
【问题讨论】:
我运行了代码......它工作正常......有什么问题??虽然我改变了端口号 你点击播放按钮??当我通过麦克风说话时,应该会收到语音包。是这样工作的吗? 【参考方案1】:你在这一行有问题(
byte[] receiveData = 新字节[10000];
)
使尺寸比这个大... 我成功了
byte[] receiveData = new byte[90000];
效果不错....
【讨论】:
以上是关于将连续字节[]数据发送到Java中的DatagramSocket,DatagramPacket的主要内容,如果未能解决你的问题,请参考以下文章
如何将从 C++ 发送的 cv::MAT 字节数组转换为 Java 中的位图?