2009-02-28 58 views
4

我試圖從我的PC上的線路捕獲音頻,爲此我使用AudioSystem類。靜態AudioSystem.write方法有兩種選擇之一:寫入文件或寫入流。我可以把它寫入文件中,但是每當我嘗試寫入流時,都會拋出java.io.IOException(未指定流長度)。至於我的緩衝區,我正在使用ByteArrayOutputStream。是否有另一種我應該使用的流或在其他地方搞亂?Java AudioSystem和TargetDataLine

另外在一個相關的主題,人們可以通過調用read直接採樣音頻線(TargetDataLine)。這是進行音頻採集還是使用AudioSystem的首選方式?

更新被請求 源代碼:

final private TargetDataLine line; 
final private AudioFormat format; 
final private AudioFileFormat.Type fileType; 
final private AudioInputStream audioInputStream; 
final private ByteArrayOutputStream bos; 

// Constructor, etc. 

public void run() 
{ 
    System.out.println("AudioWorker Started"); 
    try 
    { 
     line.open(format); 
     line.start(); 

     // This commented part is regarding the second part 
     // of my question 
     // byte[] buff = new byte[512]; 
     // int bytes = line.read(buff, 0, buff.length); 

     AudioSystem.write(audioInputStream, fileType, bos); 

    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 

    System.out.println("AudioWorker Finished"); 
} 


// Stack trace in console 
AudioWorker Started 
java.io.IOException: stream length not specified 
    at com.sun.media.sound.WaveFileWriter.write(Unknown Source) 
    at javax.sound.sampled.AudioSystem.write(Unknown Source) 
    at AudioWorker.run(AudioWorker.java:41) 
AudioWorker Finished 
+0

你可以發表一些代碼嗎? – 2009-02-28 17:59:44

+0

將堆棧跟蹤(至少是前幾幀)發佈到應用程序。 – erickson 2009-02-28 18:22:55

回答

2

從AudioSystem.write的JavaDoc:

將表示指定的文件類型的音頻文件的輸出的字節流流提供。某些文件類型要求將長度寫入文件頭;除非預先知道長度,否則不能從頭到尾寫入這些文件。如果音頻文件類型的長度爲AudioSystem.NOT_SPECIFIED,則嘗試編寫這種類型的文件將失敗並出現IOException。

+1

這聽起來像寫入文件(儘管文件也是流..)?但是這對於寫入OutputStream有什麼用?這是否意味着它不可能? – yxk 2009-02-28 23:53:16

1

你也可以嘗試尋找使用JMF,這有點毛茸茸的,但工作更好一點,javax.sound.sampled的東西。 JMF頁面上有相當多的教程介紹瞭如何從線路輸入或話筒通道進行錄音。

2

由於Wave格式需要在文件開頭寫入長度,因此作者正在查詢AudioInputStreamgetFrameLength方法。當這返回NOT_SPECIFIED —,因爲您錄製了尚未指定長度的「實時」數據—編寫器會引發異常。

面向對象的File通過將虛擬數據寫入長度字段,然後在寫入完成並覆蓋該文件區域時重新打開文件來解決此問題。

使用預先不需要長度的輸出格式(au),或者使用返回有效幀長度的AudioInputStream,或者使用API​​的File版本。

2

你應該看看Richard Baldwin's關於Java聲音的教程。在文章底部有一個完整的源代碼列表,他使用TargetDataLine的讀取來捕獲音頻。

相關問題