X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Ffunction%2FPlayAudioFunction.java;h=2ac71e93b6e38bbbaab727aa1a6d7d421c4a117a;hb=4d5796d02a15808311c09448d79e6e7d1de9d636;hp=7e7a34a8ab56d05af8140f75d4e6def27d6f1c35;hpb=f35b6d628f68e3b5ef19965ad8988d0dd1eb8efa;p=GpsPrune.git diff --git a/tim/prune/function/PlayAudioFunction.java b/tim/prune/function/PlayAudioFunction.java index 7e7a34a..2ac71e9 100644 --- a/tim/prune/function/PlayAudioFunction.java +++ b/tim/prune/function/PlayAudioFunction.java @@ -1,16 +1,22 @@ package tim.prune.function; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import tim.prune.App; import tim.prune.GenericFunction; +import tim.prune.data.AudioClip; /** - * Class to play the current audio file + * Class to play the current audio clip */ public class PlayAudioFunction extends GenericFunction implements Runnable { @@ -49,38 +55,38 @@ public class PlayAudioFunction extends GenericFunction implements Runnable */ public void run() { - File audioFile = _app.getTrackInfo().getCurrentAudio().getFile(); + AudioClip audio = _app.getTrackInfo().getCurrentAudio(); + File audioFile = audio.getFile(); boolean played = false; - if (audioFile.exists() && audioFile.isFile() && audioFile.canRead()) + if (audioFile != null && audioFile.exists() && audioFile.isFile() && audioFile.canRead()) { // First choice is to play using java - played = playClip(audioFile); - // Second choice is to try the Desktop library from java 6, if available + played = playClip(audio); + // If this didn't work, then try to play the file another way if (!played) { - try { - Class d = Class.forName("java.awt.Desktop"); - d.getDeclaredMethod("open", new Class[] {File.class}).invoke( - d.getDeclaredMethod("getDesktop").invoke(null), new Object[] {audioFile}); - //above code mimics: Desktop.getDesktop().open(audioFile); - played = true; - } - catch (Exception ignore) { - played = false; - } + played = playAudioFile(audioFile); } - // If the Desktop call failed, need to try backup methods + } + else if (audioFile == null && audio.getByteData() != null) + { + // Try to play audio clip using byte array + played = playClip(audio); + // If this didn't work, then need to copy the byte data to a file and play it from there if (!played) { - // If system looks like a Mac, try open command - String osName = System.getProperty("os.name").toLowerCase(); - boolean isMacOsx = osName.indexOf("mac os") >= 0 || osName.indexOf("darwin") >= 0; - if (isMacOsx) { - String[] command = new String[] {"open", audioFile.getAbsolutePath()}; - try { - Runtime.getRuntime().exec(command); - played = true; - } - catch (IOException ioe) {} + try + { + String suffix = getSuffix(audio.getName()); + File tempFile = File.createTempFile("gpsaudio", suffix); + tempFile.deleteOnExit(); + // Copy byte data to this file + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tempFile)); + bos.write(audio.getByteData(), 0, audio.getByteData().length); + bos.close(); + played = playAudioFile(tempFile); + } + catch (IOException ignore) { + System.err.println("Error: " + ignore.getClass().getName() + " - " + ignore.getMessage()); } } } @@ -93,16 +99,21 @@ public class PlayAudioFunction extends GenericFunction implements Runnable /** * Try to play the sound file using built-in java libraries + * @param inAudio audio clip to play * @return true if play was successful */ - private boolean playClip(File inFile) + private boolean playClip(AudioClip inClip) { boolean success = false; AudioInputStream audioInputStream = null; _clip = null; try { - audioInputStream = AudioSystem.getAudioInputStream(inFile); + if (inClip.getFile() != null) + audioInputStream = AudioSystem.getAudioInputStream(inClip.getFile()); + else if (inClip.getByteData() != null) + audioInputStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(inClip.getByteData())); + else return false; _clip = AudioSystem.getClip(); _clip.open(audioInputStream); // play the clip @@ -110,6 +121,7 @@ public class PlayAudioFunction extends GenericFunction implements Runnable _clip.drain(); success = true; } catch (Exception e) { + System.err.println(e.getClass().getName() + " - " + e.getMessage()); } finally { // close the stream to clean up try { @@ -121,6 +133,54 @@ public class PlayAudioFunction extends GenericFunction implements Runnable return success; } + /** + * Try to play the specified audio file + * @param inFile file to play + * @return true if play was successful + */ + private boolean playAudioFile(File inFile) + { + boolean played = false; + // Try the Desktop library from java 6, if available + if (!played) + { + try + { + Class d = Class.forName("java.awt.Desktop"); + d.getDeclaredMethod("open", new Class[] {File.class}).invoke( + d.getDeclaredMethod("getDesktop").invoke(null), new Object[] {inFile}); + //above code mimics: Desktop.getDesktop().open(audioFile); + played = true; + } + catch (InvocationTargetException e) { + System.err.println("ITE: " + e.getCause().getClass().getName() + " - " + e.getCause().getMessage()); + played = false; + } + catch (Exception ignore) { + System.err.println(ignore.getClass().getName() + " - " + ignore.getMessage()); + played = false; + } + } + + // If the Desktop call failed, need to try backup methods + if (!played) + { + // If system looks like a Mac, try the open command + String osName = System.getProperty("os.name").toLowerCase(); + boolean isMacOsx = osName.indexOf("mac os") >= 0 || osName.indexOf("darwin") >= 0; + if (isMacOsx) + { + String[] command = new String[] {"open", inFile.getAbsolutePath()}; + try { + Runtime.getRuntime().exec(command); + played = true; + } + catch (IOException ioe) {} + } + } + return played; + } + /** * Try to stop a currently playing clip */ @@ -150,4 +210,16 @@ public class PlayAudioFunction extends GenericFunction implements Runnable } return percent; } + + /** + * @param inName name of audio file + * @return suffix (rest of name after the dot) - expect mp3, wav, ogg + */ + private static final String getSuffix(String inName) + { + if (inName == null || inName.equals("")) {return ".tmp";} + final int dotPos = inName.lastIndexOf('.'); + if (dotPos < 0) {return inName;} // no dot found + return inName.substring(dotPos); + } }