why this code doesn't play the sound file

后端 未结 3 1510
别那么骄傲
别那么骄傲 2020-12-19 22:34

The code

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

public class Tester {
static Thread th;


public static void main(String[] args) {
    sta         


        
相关标签:
3条回答
  • 2020-12-19 23:06

    The problem is that Clip already launches a background daemon thread to play the wave file.

    So, the execution flow of your code is as follows:

    • the main thread launches a secondary (useless) thread
    • the secondary thread launches a daemon thread (which will play the sound)
    • in the mean time, the main thread keeps printing something while the secondary thread is alive
    • When the secondary thread finishes launching the playback thread, it will end, so the secondary thread will not be in the active state anymore
    • the main thread will notice that the secondary thread is not active and will end as well
    • Since the playback thread is a daemon thread, the JVM will exit (because the only threads left are daemon threads)

    The final result is precisely what you see: some text get printed by the main thread while the secondary thread is launching the playback thread, and when the playback thread would start playing, boom, the JVM finishes. Sometimes you might even be able to listen some "clicking" from the headphones (as the sound starts to play) before the JVM exits.

    The easiest fix is to make the secondary thread (ie, a non-daemon thread) sleep while the sound is playing.

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

    One important thing to notice: about 1 year ago, when I worked with that java API, I noticed that the method getMicrosecondLength() is buggy. I was coding both in Windows and Linux, and in one platform I'd get the correct value, but in the other, the very same method would return the length in milliseconds!

    I found that the most reliable way to get the real length of the sound is to use the getFrameLength() method, and calculate the length from that.

    I couldn't locate the code I wrote back then in this notebook. I will check later in another PC, and if I find it I will post a complete example (that works reliably on both Windows with Sun JVM and Linux with either OpenJDK or Sun).

    0 讨论(0)
  • 2020-12-19 23:14
    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());           
     }
    }
    
    0 讨论(0)
  • 2020-12-19 23:26
    while(clip.isRunning()){} 
    

    is better

    0 讨论(0)
提交回复
热议问题