簡體   English   中英

為什么這段代碼不播放聲音文件

[英]why this code doesn't play the sound file

代碼

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

public class Tester {
static Thread th;


public static void main(String[] args) {
    startNewThread();   
   while( th.isAlive() == true) {
       System.out.println("sound thread is working");
   }
}

public static void startNewThread() {
   Runnable r = new Runnable() {
       public void run() {
           startPlaying();
       }
   };
   th =new Thread(r);
   th.start();
} 
public static void startPlaying() {
   try {            
        AudioInputStream ais = AudioSystem.getAudioInputStream(new File("d:/UnderTest/wavtester.wav"));
        Clip clip = AudioSystem.getClip();
        clip.open(ais);
        clip.loop(-1); // keep playing the sound                  
   } catch(Exception exc) {
       System.out.println(exc);
     }       
 }
}

此代碼確實使輸出聲音線程正常工作 ,但不播放任何內容。 在這段代碼中,我已經啟動了一個單獨的線程來播放聲音,程序不應該終止,直到聲音線程完成它的工作。但程序在打印一系列聲音線程工作后終止。

這是什么原因(程序終止和聲音沒有播放)

問題是Clip已經啟動了一個后台守護程序 線程來播放wave文件。

因此,代碼的執行流程如下:

  • 主線程啟動一個輔助(無用)線程
  • 輔助線程啟動守護程序線程(將播放聲音)
  • 同時,主線程在輔助線程處於活動狀態時繼續打印
  • 當輔助線程完成啟動回放線程時,它將結束,因此輔助線程將不再處於活動狀態
  • 主線程將注意到輔助線程未處於活動狀態並且也將結束
  • 由於回放線程是一個守護程序線程 ,JVM將退出(因為只有剩下的線程是守護進程線程)

最后的結果正是你所看到的:當輔助線程啟動播放線程時,主線程會打印一些文本,當播放線程開始播放時,JVM就會完成。 有時你甚至可以在JVM退出之前從耳機中聽到一些“點擊”(當聲音開始播放時)。

最簡單的解決方法是在播放聲音時使輔助線程(即非守護程序線程)休眠。

...
  clip.open(ais);
  clip.loop(-1);
  Thread.sleep(amountToSleep);
...

需要注意的一件重要事情 :大約1年前,當我使用java API時,我注意到方法getMicrosecondLength()是錯誤的。 我在Windows和Linux上都進行了編碼,在一個平台上我得到了正確的值,但在另一個平台上,同樣的方法會以毫秒為單位返回長度!

我發現獲得聲音實際長度的最可靠方法是使用getFrameLength()方法,並從中計算長度。

我找不到我在這個筆記本上寫的代碼。 我將在稍后的另一台PC上查看,如果我發現它,我將發布一個完整的示例(在帶有SunJVM和Linux的Windows上使用OpenJDK或Sun可靠地運行)。

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

public class Tester {
static Thread th;


public static void main(String[] args) throws Exception {
     Clip clip = AudioSystem.getClip();
     AudioInputStream ais = AudioSystem.getAudioInputStream(new File("d:/UnderTest/wavtester.wav"));
     clip.open(ais);
     clip.loop(0);
     // Calculate totalFrames
     long totalFrames = (long)(clip.getFrameLength() * clip.getFormat().getFrameRate());
     Thread.sleep( ( totalFrames* 1000 )); // pause the thread till the sound plays

     System.out.println(clip.getFrameLength());
     System.out.println(clip.getFormat().getFrameRate());           
 }
}
while(clip.isRunning()){} 

更好

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM