代码之家  ›  专栏  ›  技术社区  ›  Robert J. Walker

在Java中将音频流转换为WAV字节数组而不使用临时文件

  •  7
  • Robert J. Walker  · 技术社区  · 16 年前

    给予 InputStream 打电话 in byte 包含输入数据的WAV转换的数组。不幸的是,如果您尝试这样做,JavaSound会给您带来以下错误:

    java.io.IOException: stream length not specified
    

    我将wav写入一个临时文件,然后将其读回,从而使其正常工作,如下所示:

    AudioInputStream source = AudioSystem.getAudioInputStream(new BufferedInputStream(in, 1024));
    AudioInputStream pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source);
    AudioInputStream ulaw = AudioSystem.getAudioInputStream(AudioFormat.Encoding.ULAW, pcm);
    File tempFile = File.createTempFile("wav", "tmp");
    AudioSystem.write(ulaw, AudioFileFormat.Type.WAVE, tempFile);
    // The fileToByteArray() method reads the file
    // into a byte array; omitted for brevity
    byte[] bytes = fileToByteArray(tempFile);
    tempFile.delete();
    return bytes;
    

    5 回复  |  直到 16 年前
        1
  •  7
  •   Simon Lehmann    16 年前

    问题是,大多数音频文件编写器在写入输出流时需要提前知道文件大小。因为你不能提供这个,它总是失败。不幸的是,默认的JavaSoundAPI实现没有任何替代方案。

    但您可以尝试使用Tritonus插件中的AudioOutputStream体系结构(Tritonus是Java声音API的开源实现): http://tritonus.org/plugins.html

        2
  •  2
  •   Community basarat    7 年前

    我注意到这个问题很久以前就被问到了。如果有任何新人(使用Java 7及以上版本)发现此线程,请注意,有一种更好的新方法可以通过Files.readAllBytes API实现。见: How to convert .wav file into byte array?

        3
  •  2
  •   HolloW    9 年前

    太晚了,我知道,但我需要这个,所以这是我在这个话题上的两分钱。

    public void UploadFiles(String fileName, byte[] bFile)
    {
        String uploadedFileLocation = "c:\\";
    
        AudioInputStream source;
        AudioInputStream pcm;
        InputStream b_in = new ByteArrayInputStream(bFile);
        source = AudioSystem.getAudioInputStream(new BufferedInputStream(b_in));
        pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source);
        File newFile = new File(uploadedFileLocation + fileName);
        AudioSystem.write(pcm, Type.WAVE, newFile);
    
        source.close();
        pcm.close();
    }
    
        4
  •  -1
  •   Kanaris007    8 年前

    这个问题很容易解决,如果你准备了一个能为你创建正确标题的类。以我为例 Example how to read audio input in wav buffer 数据进入某个缓冲区,然后我创建头文件并在缓冲区中创建wav文件。不需要额外的图书馆。只需从我的示例中复制代码。

    示例如何使用在缓冲区数组中创建正确标头的类:

    public void run() {    
        try {    
            writer = new NewWaveWriter(44100);  
    
            byte[]buffer = new byte[256];  
            int res = 0;  
            while((res = m_audioInputStream.read(buffer)) > 0) {  
                writer.write(buffer, 0, res);  
            }  
        } catch (IOException e) {  
            System.out.println("Error: " + e.getMessage());  
        }    
    }    
    
    public byte[]getResult() throws IOException {  
        return writer.getByteBuffer();  
    }  
    

        5
  •  -2
  •   B770    11 年前

    这很简单。。。

    File f = new File(exportFileName+".tmp");
    File f2 = new File(exportFileName);
    long l = f.length();
    FileInputStream fi = new FileInputStream(f);
    AudioInputStream ai = new AudioInputStream(fi,mainFormat,l/4);
    AudioSystem.write(ai, Type.WAVE, f2);
    fi.close();
    f.delete();
    

    .tmp文件是一个原始音频文件,结果是一个带头的WAV文件。