1 package tim.prune.function;
3 import java.io.ByteArrayInputStream;
5 import java.io.IOException;
6 import javax.sound.sampled.AudioInputStream;
7 import javax.sound.sampled.AudioSystem;
8 import javax.sound.sampled.Clip;
11 import tim.prune.GenericFunction;
12 import tim.prune.data.AudioClip;
15 * Class to play the current audio clip
17 public class PlayAudioFunction extends GenericFunction implements Runnable
19 /** Audio clip used for playing within java */
20 private Clip _clip = null;
25 * @param inApp app object
27 public PlayAudioFunction(App inApp) {
34 public String getNameKey() {
35 return "function.playaudio";
43 // Launch new thread if clip isn't currently playing
45 new Thread(this).start();
50 * Play the audio in a new thread
54 AudioClip audio = _app.getTrackInfo().getCurrentAudio();
55 File audioFile = audio.getFile();
56 boolean played = false;
57 if (audioFile != null && audioFile.exists() && audioFile.isFile() && audioFile.canRead())
59 // First choice is to play using java
60 played = playClip(audio);
61 // Second choice is to try the Desktop library from java 6, if available
64 Class<?> d = Class.forName("java.awt.Desktop");
65 d.getDeclaredMethod("open", new Class[] {File.class}).invoke(
66 d.getDeclaredMethod("getDesktop").invoke(null), new Object[] {audioFile});
67 //above code mimics: Desktop.getDesktop().open(audioFile);
70 catch (Exception ignore) {
74 // If the Desktop call failed, need to try backup methods
77 // If system looks like a Mac, try open command
78 String osName = System.getProperty("os.name").toLowerCase();
79 boolean isMacOsx = osName.indexOf("mac os") >= 0 || osName.indexOf("darwin") >= 0;
81 String[] command = new String[] {"open", audioFile.getAbsolutePath()};
83 Runtime.getRuntime().exec(command);
86 catch (IOException ioe) {}
90 else if (audioFile == null && audio.getByteData() != null) {
91 // Try to play audio clip using byte array (can't use Desktop or Runtime)
92 played = playClip(audio);
96 // If still not worked, show error message
97 _app.showErrorMessage(getNameKey(), "error.playaudiofailed");
102 * Try to play the sound file using built-in java libraries
103 * @param inAudio audio clip to play
104 * @return true if play was successful
106 private boolean playClip(AudioClip inClip)
108 boolean success = false;
109 AudioInputStream audioInputStream = null;
113 if (inClip.getFile() != null)
114 audioInputStream = AudioSystem.getAudioInputStream(inClip.getFile());
115 else if (inClip.getByteData() != null)
116 audioInputStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(inClip.getByteData()));
118 _clip = AudioSystem.getClip();
119 _clip.open(audioInputStream);
124 } catch (Exception e) {
125 System.err.println(e.getClass().getName() + " - " + e.getMessage());
127 // close the stream to clean up
130 audioInputStream.close();
131 } catch (Exception e) {}
138 * Try to stop a currently playing clip
140 public void stopClip()
142 if (_clip != null && _clip.isActive()) {
147 catch (Exception e) {}
152 * @return percentage of clip currently played, or -1 if not playing
154 public int getPercentage()
157 if (_clip != null && _clip.isActive())
159 long clipLen = _clip.getMicrosecondLength();
161 percent = (int) (_clip.getMicrosecondPosition() * 100.0 / clipLen);