Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过TCP发送音频流,不支持DaudioFileException_Java_Sockets_Tcp_Audio Streaming - Fatal编程技术网

Java 通过TCP发送音频流,不支持DaudioFileException

Java 通过TCP发送音频流,不支持DaudioFileException,java,sockets,tcp,audio-streaming,Java,Sockets,Tcp,Audio Streaming,我已成功通过TCP套接字发送和读取文本和图像数据。但我无法发送和读取音频流数据 服务器上的示例代码: public class ServerAudio { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { ServerSocket serverSoc

我已成功通过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套接字发送音频流。

由于TCP是可靠的,因此将完全接收字节。还有一个小问题。您需要播放从音频流接收的音频,仅创建音频输入流不会播放它。 播放接收到的音频可能有不同的技术。您可以使用Java声音API中的剪辑源数据行。另外,不要多次创建AudioInputStream。只需创建一次并使用它

这里有一个可能的解决方案,你可以用来播放接收到的音频

public class RDPPlayAudioBytes {

private static Socket socket;
private static BufferedInputStream inputStream;

/**
 * @param args
 * @throws javax.sound.sampled.LineUnavailableException
 */
public static void main(String[] args) throws LineUnavailableException {
    // TODO Auto-generated method stub
    // SocketAddress socketAddress = new InetSocketAddress("172.19.1.50", 4444);
    try {
        socket = new Socket("127.0.0.1", 6666);

        if (socket.isConnected()) {

            inputStream = new BufferedInputStream(socket.getInputStream());

            Clip clip = AudioSystem.getClip();
            AudioInputStream ais = AudioSystem.getAudioInputStream(inputStream);
            clip.open(ais);
            clip.start();

            while (inputStream != null) {
                if (clip.isActive()) {

                    System.out.println("********** Buffred *********" + inputStream.available());

                }
            }

        }

    } catch (IOException | UnsupportedAudioFileException e) {
        System.err.println(e);
    }
}
}
根据您的需求,您可能需要不同的实现。这只是演示如何使用音频输入流使用剪辑播放音频。您可能会注意到我发布的代码中有很多更改。我希望你能理解这一点

您可以参考Java Sound API文档来深入了解Java的基础知识

注意

  • 仅就您所知,您可能需要实现一个侦听器,以便在音频剪辑播放结束之前不会关闭程序。在当前的实现中,由于使用了循环,因此不会发生这种情况。但是最好使用一个监听器。你可以参考

  • 您还可以将音频数据读入字节[],然后在收到音频数据后立即播放。实施情况将略有变化


  • 服务器:服务器只对声音文件的字节进行流式传输。没有涉及音响系统。将声音文件作为参数传递:

    java AudioServer "C:/Users/Public/Music/Sample Music/adios.wav"
    
    AudioServer类的代码:

    import java.io.*;
    import java.net.*;
    
    public class AudioServer {
        public static void main(String[] args) throws IOException {
            if (args.length == 0)
                throw new IllegalArgumentException("expected sound file arg");
            File soundFile = AudioUtil.getSoundFile(args[0]);
    
            System.out.println("server: " + soundFile);
    
            try (ServerSocket serverSocker = new ServerSocket(6666); 
                FileInputStream in = new FileInputStream(soundFile)) {
                if (serverSocker.isBound()) {
                    Socket client = serverSocker.accept();
                    OutputStream out = client.getOutputStream();
    
                    byte buffer[] = new byte[2048];
                    int count;
                    while ((count = in.read(buffer)) != -1)
                        out.write(buffer, 0, count);
                }
            }
    
            System.out.println("server: shutdown");
        }
    }
    

    客户端:客户端可以播放通过命令行传递的声音文件,以测试其是否工作:

    java AudioClient "C:/Users/Public/Music/Sample Music/adios.wav"
    
    调用时不带任何参数,它连接到服务器并播放通过套接字接收的文件:

    java AudioClient
    
    代码:


    AudioServer和AudioClient使用的实用程序类:

    import java.io.File;
    
    public class AudioUtil {
        public static File getSoundFile(String fileName) {
            File soundFile = new File(fileName);
            if (!soundFile.exists() || !soundFile.isFile())
                throw new IllegalArgumentException("not a file: " + soundFile);
            return soundFile;
        }
    }
    

    提示:不要使用
    available()
    。在大多数情况下,它不是您所期望的。请尝试使用此AudioInputStream ain=testPlay(“C:\\Users\\Public\\Music\\Sample Music\\adios.wav”);看看这一次,有两件事需要检查。在testplay中,在创建
    文件后,打印
    文件.exists()
    文件.canRead()
    、和
    文件.getCanonicalPath()
    的值。如果一切正常,请尝试打印
    AudioSystem.getAudioFileFormat(file)
    的值。如果失败,请仔细查看您的文件,确保它确实是WAV文件。这将永远不会终止:
    inputStream
    将永远不会为空。同样,这个循环和
    clip.isActive()
    检查将消耗所有的CPU周期。我同意,但我的目的只是展示如何使用媒体播放问题中发布的代码的声音。我同意代码可以改进。
    import java.io.File;
    
    public class AudioUtil {
        public static File getSoundFile(String fileName) {
            File soundFile = new File(fileName);
            if (!soundFile.exists() || !soundFile.isFile())
                throw new IllegalArgumentException("not a file: " + soundFile);
            return soundFile;
        }
    }