/*
* Copyright 2008-2013, ETH Zürich, Samuel Welten, Michael Kuhn, Tobias Langner,
* Sandro Affentranger, Lukas Bossard, Michael Grob, Rahul Jain,
* Dominic Langenegger, Sonia Mayor Alonso, Roger Odermatt, Tobias Schlueter,
* Yannick Stucki, Sebastian Wendland, Samuel Zehnder, Samuel Zihlmann,
* Samuel Zweifel
*
* This file is part of Jukefox.
*
* Jukefox is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or any later version. Jukefox is
* distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Jukefox. If not, see <http://www.gnu.org/licenses/>.
*/
package ch.ethz.dcg.miniplayer;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.UnsupportedAudioFileException;
import javazoom.jl.player.advanced.PlaybackEvent;
import javazoom.jl.player.advanced.PlaybackListener;
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
public class MiniPlayer implements PlaybackListener, IPositionListener {
private static final int MS_PER_FRAMES = 26;
private PlayThread playThread;
private PreparePlayerThread preparePlayerThread;
private File file;
private int positionFrame;
private PlayerEventListener listener;
public MiniPlayer(File file) {
this.file = file;
this.positionFrame = 0;
}
public void preparePlayer() {
if (preparePlayerThread != null) {
preparePlayerThread.exit();
}
preparePlayerThread = new PreparePlayerThread(file);
preparePlayerThread.start();
}
public void play() {
// Wait for preparePlayerThread to complete loading
try {
preparePlayerThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (playThread != null) {
playThread.exit();
}
preparePlayerThread.getPlayer().setPlayBackListener(this);
preparePlayerThread.getPlayer().setPlayBackPositionListener(this);
playThread = new PlayThread(preparePlayerThread.getPlayer(), positionFrame);
playThread.start();
}
/**
* Stops the playback of the player and resets the current position to frame 0.
*/
public void stop() {
stopPlayback();
positionFrame = 0;
}
/**
* Stops the playback and stores the current position of the playback so it will be resumed when calling {@link #play()}.
*/
public void pause() {
setPositionFrame(playThread.getPlayer().getPosition());
stopPlayback();
}
/**
* Stops the playback but does not reset the current position.
*/
protected void stopPlayback() {
if (playThread != null) {
playThread.exit();
preparePlayer();
}
}
public void setPositionMs(int position) {
setPositionFrame((int) Math.round(((double) position) / MS_PER_FRAMES));
}
public int getPositionMs() {
return getPositionFrame() * 26;
}
public void setPositionFrame(int frame) {
this.positionFrame = frame;
}
public int getPositionFrame() {
return positionFrame;
}
public void close() {
if (preparePlayerThread != null) {
preparePlayerThread.exit();
}
if (playThread != null) {
playThread.exit();
}
}
protected void fireOnSongCompletedEvent() {
if (listener != null)
listener.onSongCompleted();
}
@Override
public void playbackStarted(PlaybackEvent evt) {
}
@Override
public void playbackStopped(PlaybackEvent evt) {
}
@Override
public void playbackCompleted(PlaybackEvent evt) {
fireOnSongCompletedEvent();
}
public void setPlayerEventListener(PlayerEventListener listener) {
this.listener = listener;
}
/**
* Returns the duration of the song in milliseconds.
*
* @return the duration of the song in milliseconds.
*/
public int getDuration() {
AudioFileFormat baseFileFormat;
try {
baseFileFormat = new MpegAudioFileReader().getAudioFileFormat(file);
} catch (UnsupportedAudioFileException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
Map<String, Object> properties = baseFileFormat.properties();
long duration = (Long) properties.get("duration");
int d = (int) Math.round(duration / 1000.0);
return d;
}
@Override
public void onNewPosition(int position) {
positionFrame = position;
}
}