Java 从字节[]数组播放声音

Java 从字节[]数组播放声音,java,client-server,javasound,audio,Java,Client Server,Javasound,Audio,我从服务器收到了一个字节数组,我知道它可以完美地连接和发送。当我尝试播放字节数组中的声音时 这是我要播放的声音 SourceDataLine speaker = null; try { DataLine.Info speakerInfo = new DataLine.Info(SourceDataLine.class, getAudioFormat(samplerate)); speaker = (SourceDataLine) AudioSystem.getLine(speak

我从服务器收到了一个字节数组,我知道它可以完美地连接和发送。当我尝试播放字节数组中的声音时

这是我要播放的声音

SourceDataLine speaker = null;
try {
    DataLine.Info speakerInfo = new DataLine.Info(SourceDataLine.class, getAudioFormat(samplerate));
    speaker = (SourceDataLine) AudioSystem.getLine(speakerInfo);
} catch (LineUnavailableException e) {
    e.printStackTrace();
}
int nBytesRead = 0;
    while (nBytesRead != -1) {
    if (nBytesRead >= 0) {
         speaker.write(bytes, 0, nBytesRead);
    }
}
getAudioFormat:

private AudioFormat getAudioFormat(float sample) {
    int sampleSizeBits = 16;
    int channels = 1;
    boolean signed = true;
    boolean bigEndian = false;
    return new AudioFormat(sample, sampleSizeBits, channels, signed, bigEndian);
}

如何播放来自
字节[]
的音乐?

不久前,我编写了一个小型服务器,通过http传输音乐:

转到那里,按照播放的方式,您只需转到指定的链接,即:www.localhost:8080/test在我的例子中,浏览器将播放音乐

也许你们可以把我的一些结果和你们的结果结合起来,找到解决办法


实际上,无论哪个链接返回bytearray,都将由浏览器根据数据类型等进行流式处理。

我看不出您在while循环中从声音字节数组中读取的内容。按照你的设置方式,可能应该有以下几点:

while (nBytesRead = soundDataArray.read(bytes) != 1)
…假设已设置读取方法,以便名为“bytes”的缓冲区从读取命令接收数据。然后write()方法将重复填充“bytes”以发送

当然,“bytes”只是一个仅在while循环中使用的缓冲区,而不是源声音的字节数组

有时read方法有两个输入,如:
.read(bufferArray,bytesToRead)
其中,一个k或几个k范围内的值是常见的。(bufferArray.length==bytesToRead)

这样,您可以播放字节[]中的声音。 希望它能帮助别人

import javax.sound.sampled.*;
import java.io.*;

public class PlaySoundFromByteArr {

  public static void main(String[] args) throws IOException, UnsupportedAudioFileException {
    String FILE_PATH = "resources/wav-1.wav";

    byte[] byteArr = getByte(FILE_PATH);
    AudioFormat format = getFormat(FILE_PATH);
    playAudioUsingByteArray(byteArr, format);
  }

  private static byte[] getByte(String FILE_PATH) {
    byte[] byteArr = new byte[0];

    try {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      AudioInputStream in =  AudioSystem.getAudioInputStream(new File(FILE_PATH));

      int numOfBytes;
      byte[] buffer = new byte[1024];

      while( (numOfBytes = in.read(buffer)) > 0 ){
        out.write(buffer, 0,numOfBytes);
      }
      out.flush();
      byteArr = out.toByteArray();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (UnsupportedAudioFileException e) {
      e.printStackTrace();
    }

    return byteArr;
  }

  private static AudioFormat getFormat(String FILE_PATH) throws IOException, UnsupportedAudioFileException {
    AudioInputStream in =  AudioSystem.getAudioInputStream(new File(FILE_PATH));
    return in.getFormat();
  }

  private static void playAudioUsingByteArray(byte[] byteArr, AudioFormat format) {
    try (Clip clip = AudioSystem.getClip()) {
      clip.open(format, byteArr, 0, byteArr.length);
      clip.start();
      clip.drain();
      Thread.sleep(clip.getMicrosecondLength());
    }
    catch (LineUnavailableException | InterruptedException e) {
      e.printStackTrace();
    }
  }

}

你是说
Byte[]
还是
Byte[]
?它们相对来说是一样的。。。但我指的是字节[]。不,它们不一样
Byte[]
是一个类型为
java.lang.Byte
的引用数组,而
Byte[]
是一个基本的8位带符号整数值数组。为了更快地获得更好的帮助,请发布一个。它是否可以像缺少的
speaker.start()
调用一样简单?什么类是“soundDataArray”?另外,如果它是“AudioInputStream”,我不能,因为它是从服务器接收字节的(如第一行所述),嗯。也许我的答案不太清楚。主要的一点是,您需要逐步获取输入数组的块并将它们交给write()方法,是吗?因此,也许您编写了一个读取字节的方法(通常在游标或索引的帮助下完成,以跟踪对read()方法的调用之间的进度)。也许整个过程就是一个字节的包装器。这样,索引可以是read()方法之外的实例变量。在这个场景中,SoundDataArray将是新的对象定义(包装您收到的字节文件)。。。那么soundDataArray是一个cast对象?So(Object)bytes.read(bytes,0,bytes.length);?很抱歉,我对术语的理解很糟糕。最后一句应该是“在这个场景中,SoundDataArray将是新的类定义”。不涉及“物体”,不需要铸造。您还可以查看TargetDataLine以了解渐进式读取的示例。如果您可以创建一个TDL来处理传入(来自服务器)的声音,那么您可以在while循环中使用它。