将连续字节[]数据发送到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 中的位图?

通过Java中的套接字发送字符串而不是字节

iPhone中Objective C中的字节数据类型

Java字节数组到Javascript类型数组

STM8S单片机UART串口通信如何实现连续发送和接收两个8位数据

将html转换为字节数组java中的图像