【问题标题】:Playing sound from a byte[] array从 byte[] 数组播放声音
【发布时间】:2013-02-18 21:02:36
【问题描述】:

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

这是我必须播放的声音。

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);
    }
}

获取音频格式:

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);
}

如何从byte[] 播放音乐?

【问题讨论】:

  • 你的意思是Byte[]还是byte[]
  • 它们是相对相同的......但我的意思是字节[]。
  • 不,它们不一样。 Byte[]java.lang.Byte 类型的引用数组,byte[] 是原始 8 位有符号整数值数组。
  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 会不会像缺少speaker.start() 电话一样简单?

标签: java client-server javasound audio


【解决方案1】:

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

while (nBytesRead = soundDataArray.read(bytes) != 1)

...假设您设置了 read 方法,以便名为“bytes”的缓冲区接收来自 read 命令的数据。然后 write() 方法将重复填充“字节”以发送。

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

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

【讨论】:

  • “soundDataArray”是什么类?另外,如果它是“AudioInputStream”,我不能,因为它是从服务器接收到的字节(如第一行所述)
  • 嗯。可能我的回答不是很清楚。要点是您需要逐步抓取输入数组的块并将它们提供给 write() 方法,是吗?因此,也许您编写了一个读取字节的方法(通常在游标或索引的帮助下完成,以跟踪对 read() 方法的调用之间的进度)。也许整个事情都是你的字节的包装器。这样,索引可以是 read() 方法之外的实例变量。在这种情况下,SoundDataArray 将是新的 Object 定义(包装您收到的字节文件)。
  • 对...所以 soundDataArray 是一个强制转换对象?所以 (Object) bytes.read(bytes, 0, bytes.length);?
  • 我的术语很糟糕,我很抱歉。最后一句应为“在这种情况下,SoundDataArray 将是新的类定义”。不涉及“对象”,不需要铸造。您还可以查看 TargetDataLine 以获取渐进式读取的示例。如果你可以创建一个 TDL 来处理传入(来自服务器)的声音,你可以在你的 while 循环中使用它。
【解决方案2】:

前段时间我写了一个小型服务器来通过 http:Stream music in loop over http using java 流式传输音乐

去那里,它的播放方式,你只需转到指定的链接,即:www.localhost:8080/test 在我的例子中,浏览器会播放音乐。

也许您可以将我的一些结果与您的结果结合起来找到解决方案。

实际上,无论链接返回字节数组,浏览器都会根据数据类型等进行流式传输。

【讨论】:

    【解决方案3】:

    这样你就可以从 Byte[] 播放声音。

    希望对其他人有所帮助。

    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();
        }
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-05
      • 2020-01-04
      • 2020-09-14
      相关资源
      最近更新 更多