RaspberryPi JavaFX + Sound
Media support is not included in the current JDK8 preview. If you want to play audio files, it's maybe a problem if you think that it's not possible
Don't use JavaFX for the job. Simply use Java Sound API. We successfully used it for our tests with Beagleboard-xm and RaspberryPi (jdk7, jdk8 javafx preview).
Here's the source code of our, old but still good, implementation:
* Copyright 2012 SIB Visions GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*
* History
*
* 15.12.2005 - [JR] - creation
*/
package com.sibvisions.apps.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Vector;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import com.sibvisions.util.type.FileUtil;
/**
* The <code>AudioPlayer</code> plays audio files. Currently only wav, au and midi files are supported.
*
* @author René Jahn
*/
public final class AudioPlayer
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class members
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** thread list for background playback. */
private static Vector<Thread> vThreads = null;
/** list of dataline connections for playback. */
private static Vector<SourceDataLine> vSdl = new Vector<SourceDataLine>();
/** Cached audio files. Reduces resource usage during repatedly playback. */
private static Hashtable<String, byte[]> htAudioCache = new Hashtable<String, byte[]>();
/** sync object. */
private static final Object SYNC = new Object();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Invisible constructor because <code>AudioPlayer</code> is a utility
* class.
*/
private AudioPlayer()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// User-defined methods
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Gets the current player thread count.
*
* @return the number of player threads
*/
public static int getPlayerThreads()
{
if (vThreads != null)
{
return vThreads.size();
}
else
{
return 0;
}
}
/**
* Playback an audio file.
*
* @param pFileName the filename
* @param pBackground <code>true</code> to start playback as background process. The method call returns
* immediately.
*/
public static synchronized void play(final String pFileName, boolean pBackground)
{
AudioPlayer.play(new String[] {pFileName}, 0, pBackground);
}
/**
* Playback multiple audio files.
*
* @param pFileName list of file names
* @param pDelay delay between playback
* @param pBackground <code>true</code> to start playback as background process. The method call returns
* immediately.
*/
public static synchronized void play(final String[] pFileName, final long pDelay, boolean pBackground)
{
Thread thPlay;
Thread th;
if (pBackground)
{
thPlay = new Thread()
{
public void run()
{
if (Thread.currentThread() == this)
{
if (pFileName != null)
{
for (int i = 0, anz = pFileName.length; i < anz; i++)
{
AudioPlayer.play(pFileName[i]);
//Use defined delay between playback, but ignore delay after the last track
if (pDelay > 0 && i + 1 < anz)
{
try
{
Thread.sleep(pDelay);
}
catch (InterruptedException ie)
{
//nothing to be done
}
}
}
}
}
vThreads.remove(this);
}
};
if (vThreads == null)
{
vThreads = new Vector<Thread>();
}
//Clear zombies
for (int i = 0; i < vThreads.size();)
{
th = (Thread)vThreads.get(i);
if (!th.isAlive())
{
th.interrupt();
vThreads.remove(i);
th = null;
}
else
{
i++;
}
}
vThreads.add(thPlay);
thPlay.setPriority(Thread.MAX_PRIORITY);
thPlay.start();
}
else
{
if (pFileName != null)
{
for (int i = 0, anz = pFileName.length; i < anz; i++)
{
AudioPlayer.play(pFileName[i]);
//Use defined delay between playback, but ignore delay after the last track
if (pDelay > 0 && i + 1 < anz)
{
try
{
Thread.sleep(pDelay);
}
catch (InterruptedException ie)
{
//nothing to be done
}
}
}
}
}
}
/**
* Playback a sound file.
*
* @param pFileName the filename
*/
public static void play(String pFileName)
{
AudioInputStream ais = null;
AudioFormat adf;
DataLine.Info dli;
SourceDataLine sdl;
byte[] byData = new byte[128000];
int iData;
try
{
byte[] byCache = (byte[])htAudioCache.get(pFileName);
if (byCache != null)
{
ais = AudioSystem.getAudioInputStream(new ByteArrayInputStream(byCache));
}
else
{
File fiDirect = new File(pFileName);
//use byte array because most InputStreams do not support "seek"
//we avoid Exceptions
if (fiDirect.exists())
{
byCache = FileUtil.getContent(new FileInputStream(fiDirect));
}
else
{
byCache = FileUtil.getContent(AudioPlayer.class.getResourceAsStream(pFileName));
}
if (byCache != null)
{
cacheFile(pFileName, byCache);
ais = AudioSystem.getAudioInputStream(new ByteArrayInputStream(byCache));
}
else
{
throw new IllegalArgumentException("No content found for : " + pFileName);
}
}
byCache = null;
}
catch (Exception e)
{
e.printStackTrace();
return;
}
adf = ais.getFormat();
dli = new DataLine.Info(SourceDataLine.class, adf);
try
{
sdl = (SourceDataLine) AudioSystem.getLine(dli);
sdl.open(adf);
synchronized (SYNC)
{
vSdl.add(sdl);
}
}
catch (Exception e)
{
e.printStackTrace();
return;
}
sdl.start();
try
{
while ((iData = ais.read(byData, 0, byData.length)) != -1)
{
sdl.write(byData, 0, iData);
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
sdl.drain();
synchronized (SYNC)
{
sdl.flush();
sdl.stop();
sdl.close();
vSdl.remove(sdl);
}
try
{
ais.close();
ais = null;
}
catch (IOException ioe)
{
//nothing to be done
}
sdl = null;
adf = null;
}
/**
* Stop playback of all audio files.
*/
public static void stopSound()
{
synchronized (SYNC)
{
if (vSdl != null)
{
//stop all playbacks
for (SourceDataLine sdl : vSdl)
{
try
{
sdl.flush();
sdl.stop();
//Don't call this because it crashes the VM and results in a core dump
//sdl.close();
}
catch (Exception e)
{
//nothing to be done
}
}
vSdl.clear();
}
}
}
/**
* Caches audio data for later use. If the file is already cached the cache won't
* be overwritten.
*
* @param pFileName the filename
* @param pData audio data
*/
public static void cacheFile(String pFileName, byte[] pData)
{
cacheFile(pFileName, pData, false);
}
/**
* Caches audio data for later use.
*
* @param pFileName the filename
* @param pData audio data
* @param bIgnoreCache <code>true</code> to overwrite already cached data, <code>false</code>
* doesn't overwrite cached data
*/
public static void cacheFile(String pFileName, byte[] pData, boolean bIgnoreCache)
{
if (!bIgnoreCache && htAudioCache.containsKey(pFileName))
{
return;
}
if (pFileName != null && pData != null)
{
htAudioCache.put(pFileName, pData);
}
}
/**
* Caches an audio file for later use. The file content will be read automatically.
* If the file is already cached the cache won't be overwritten.
*
* @param pFileName the filename
*/
public static void cacheFile(String pFileName)
{
cacheFile(pFileName, false);
}
/**
* Caches an audio file for later use. The file content will be read automatically.
*
* @param sFileName Dateiname
* @param bIgnoreCache true um bereits gecachte Daten zu überschreiben
*/
public static void cacheFile(String sFileName, boolean bIgnoreCache)
{
//don't overwrite cache, if not specified
if (!bIgnoreCache && htAudioCache.containsKey(sFileName))
{
return;
}
InputStream is = AudioPlayer.class.getResourceAsStream(sFileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] byData = new byte[128000];
int iData;
try
{
while ((iData = is.read(byData, 0, byData.length)) != -1)
{
bos.write(byData, 0, iData);
}
htAudioCache.put(sFileName, bos.toByteArray());
bos.close();
is.close();
}
catch (IOException ioe)
{
//nothing to be done
}
}
} //AudioPlayer
Example wav file.