package smp.player;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import javazoom.jlgui.basicplayer.BasicPlayerException;
import org.tritonus.share.sampled.file.TAudioFileFormat;
import smp.exception.MediaPlayerException;
import smp.listener.MediaPlayerListener;
public class MediaPlayer implements MediaPlayerListener{
private final String MP3 = "mp3";
private Mp3Player mp3player = null;
private String curplayer = null;
private ArrayList<MediaPlayerListener> listener = null;
private float volume = 0.3F;
private long songLength = 0;
private long songSize = 0;
private long curLength = 0;
/**
* Construct a new MediaPlayer
*/
public MediaPlayer() {
listener = new ArrayList<MediaPlayerListener>();
mp3player = new Mp3Player();
mp3player.addMediaPlayerListener(this);
}
/**
* Add a MediaPlayerListener to this MediaPlayer
* @param mpl - The MediaPlayerListener
*/
public void addMediaPlayerListener(MediaPlayerListener mpl) {
listener.add(mpl);
}
/**
* Remove a MediaPlayerListener from this MediaPlayer
* @param mpl - The MediaPlayerListener
*/
public void removeMediaPlayerListener(MediaPlayerListener mpl) {
listener.remove(mpl);
}
/**
* Notifie the listener, that the song has been finished
*/
protected void songFinished() {
for (MediaPlayerListener mpl : listener) {
mpl.songEnded();
}
}
/**
* Play a musicfile. At the moment only mp3 is supported.
* @param f - The file to play.
* @throws MediaPlayerException
* @see play(File f, long startPosition)
* @see getSongSize(File f)
*/
public void play(File f) throws MediaPlayerException{
play(f, 0);
}
/**
* Play a musicfile, starting at the given position.
* @param f - The file to play.
* @param startPosition - The start position in microseconds
* @throws MediaPlayerException
* @see play(File f)
* @see getSongSize(File f);
*/
public void play(File f, long startPosition) throws MediaPlayerException{
stop();
if (f.getName().toLowerCase().endsWith(".mp3")) {
playMp3(f, startPosition);
setVolume(volume);
}
}
/**
* Stop the current playback
* @throws MediaPlayerException
*/
public void stop() throws MediaPlayerException {
if (MP3.equals(curplayer)) {
try {
mp3player.setStopped(true);
mp3player.stop();
}
catch (BasicPlayerException e) {
throw new MediaPlayerException("Can't stop playing mp3 file", e);
}
}
curplayer = null;
}
/**
* Get the song duration in microseconds
* @param f - The musicfile to be read
* @return Song size in microseconds
* @throws ClassCastException
* @throws IOException
* @throws UnsupportedAudioFileException
*/
public long getSongSize(File f) throws ClassCastException, IOException, UnsupportedAudioFileException {
if (f.getName().toLowerCase().endsWith(".mp3")) {
Map properties = ((TAudioFileFormat)AudioSystem.getAudioFileFormat(f)).properties();
songLength = Long.parseLong(properties.get("duration").toString());
songSize = f.length();
return songLength;
}
return -1;
}
/**
* Set the position to the given microseconds
* @param position - New position in microseconds
* @throws MediaPlayerException
*/
public void setPosition(long position) throws MediaPlayerException {
try {
curLength = position;
mp3player.setPosition((long)(songSize * ((double)position / (double)songLength)));
}
catch (BasicPlayerException e) {
throw new MediaPlayerException("Can't seek in mp3 file", e);
}
}
/**
* Set the volume
* @param volume - The volume
* @throws MediaPlayerException
*/
public void setVolume(float volume) throws MediaPlayerException {
this.volume = volume;
if (mp3player != null) {
try {
mp3player.setVolume(volume);
}
catch (BasicPlayerException e) {
throw new MediaPlayerException("Can't set volume from mp3 file", e);
}
}
}
/**
* Get the current volume as float
* @return The volume
*/
public float getVolume() {
return volume;
}
/**
* Get the current positon in microseconds
* @return The position
*/
public long getPosition() {
if (MP3.equals(curplayer)) {
return mp3player.getPosition() + curLength;
}
return -1;
}
/**
* Get the state from the current Player
* @return The state
*/
public int getState() {
if (MP3.equals(curplayer)) {
return mp3player.getState();
}
return -1;
}
// play mp3 files
private void playMp3(File f, long startPosition) throws MediaPlayerException {
try {
curplayer = MP3;
setPosition(startPosition);
mp3player.setStopped(false);
mp3player.play(f, startPosition);
}
catch (BasicPlayerException e) {
throw new MediaPlayerException("Can't play mp3 file", e);
}
}
/**
* Called by the MediaPlayerListener if a song has been finished
*/
public void songEnded() {
songFinished();
}
}