GStreamerPlayer no longer proxies via PlayerGUI to interact with a playlist.

This commit is contained in:
neviyn 2016-03-19 23:06:28 +00:00
parent 974ff2c8c1
commit 41e7de065e
5 changed files with 99 additions and 106 deletions

View File

@ -47,18 +47,6 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
this.playlist = playlist;
this.library = library;
createUI();
Thread seekBarUpdater = new Thread(() -> {
boolean running = true;
while (running) {
try {
Thread.sleep(1000);
setSeekBarPosition(player.currentSongPosition());
} catch (InterruptedException e) {
running = false;
}
}
}, "seekbar");
seekBarUpdater.start();
try {
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);
@ -107,41 +95,6 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
});
}
/**
* Set the highlighted song in the playlist to this song.
*
* @param playingSong Song to be highlighted in the playlist.
*/
@Override
public void setSongHighlighting(Song playingSong) {
playlist.setPlayingSong(playingSong);
}
private void playSong(Optional<Song> song){
try {
player.playSong(song);
} catch (StartPlayingException e) {
JOptionPane.showMessageDialog(this, "Failed to play " + song.get().toString() + ".\n" +
"If file path contains non-ASCII characters, please restart the application with UTF-8 encoding.");
}
}
/**
* Get the next song in the playlist and dispatch it to the Player to be played.
*/
public void playNextSong() {
SwingUtilities.invokeLater(() -> seekBar.setValue(0));
playSong(playlist.getNext(player.getCurrentSong()));
}
/**
* Get the previous song in the playlist and dispatch it to the Player to be played.
*/
public void playPreviousSong() {
SwingUtilities.invokeLater(() -> seekBar.setValue(0));
playSong(playlist.getPrevious(player.getCurrentSong()));
}
/**
* Set the maximum value of the seekBar.
*
@ -151,14 +104,9 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
SwingUtilities.invokeLater(() -> seekBar.setMaximum(seconds));
}
@Override
public void removeInvalidSong(Song invalidSong) {
playlist.delete(invalidSong);
}
public void playerStopped(){
setSongHighlighting(player.getCurrentSong());
playlist.setPlayingSong(null);
private void showError(StartPlayingException ex){
JOptionPane.showMessageDialog(this, "Failed to play " + ex.getSong().toString() + ".\n" +
"If file path contains non-ASCII characters, please restart the application with UTF-8 encoding.");
}
/*
@ -204,15 +152,18 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
playButton.setName("playButton");
playButton.setIcon(Icons.playIcon);
playButton.setMnemonic('P');
playButton.addActionListener(e -> playSong(playlist.getActive()));
playButton.addActionListener(e -> {
try {
player.play();
} catch (StartPlayingException e1) {
showError(e1);
}
});
controlBar.add(playButton);
JButton pauseButton = new JButton();
pauseButton.setIcon(Icons.pauseIcon);
pauseButton.setMnemonic('E');
pauseButton.addActionListener(e -> {
player.pause();
setSongHighlighting(player.getCurrentSong()); // Resume won't function if a different song is selected.
});
pauseButton.addActionListener(e -> player.pause());
controlBar.add(pauseButton);
JButton stopButton = new JButton();
stopButton.setIcon(Icons.stopIcon);
@ -222,12 +173,24 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
JButton previousButton = new JButton();
previousButton.setIcon(Icons.prevIcon);
previousButton.setMnemonic('R');
previousButton.addActionListener(e -> playPreviousSong());
previousButton.addActionListener(e -> {
try {
player.previous();
} catch (StartPlayingException e1) {
showError(e1);
}
});
controlBar.add(previousButton);
JButton nextButton = new JButton();
nextButton.setIcon(Icons.nextIcon);
nextButton.setMnemonic('N');
nextButton.addActionListener(e -> playNextSong());
nextButton.addActionListener(e -> {
try {
player.next();
} catch (StartPlayingException e1) {
showError(e1);
}
});
controlBar.add(nextButton);
toolBar.add(controlBar);
toolBar.add(createVolumeControls());
@ -399,22 +362,27 @@ public class PlayerGUI extends JPanel implements PlayerCallbackInterface {
@Override
public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {
if(modified){
switch(nativeKeyEvent.getRawCode()){
case playPause:
if(player.isPlaying()){
player.pause();
setSongHighlighting(player.getCurrentSong()); // Resume won't function if a different song is selected.
}
else{
playSong(playlist.getActive());
}
break;
case stop:
player.stop(); break;
case previous:
playPreviousSong(); break;
case next:
playNextSong(); break;
try {
switch (nativeKeyEvent.getRawCode()) {
case playPause:
if (player.isPlaying()) {
player.pause();
} else {
player.play();
}
break;
case stop:
player.stop();
break;
case previous:
player.previous();
break;
case next:
player.next();
break;
}
}catch (StartPlayingException ex){
showError(ex);
}
}
}

View File

@ -9,4 +9,8 @@ public class StartPlayingException extends Exception {
public StartPlayingException(Song song){
this.song = song;
}
public Song getSong() {
return song;
}
}

View File

@ -7,32 +7,13 @@ import musicplayer.model.Song;
@ImplementedBy(PlayerGUI.class)
public interface PlayerCallbackInterface {
/**
* Set the song currently shown to the user as playing.
* @param playingSong Song currently playing.
*/
void setSongHighlighting(Song playingSong);
/**
* Set the seekbar position.
*
* @param seconds Position to set the seekbar to.
*/
void setSeekBarDuration(int seconds);
/**
* Remove a song from the current playlist.
* @param invalidSong Song to remove.
*/
void removeInvalidSong(Song invalidSong);
/**
* Playback has ceased.
*/
void playerStopped();
/**
* Start playing the next song.
*/
void playNextSong();
void setSeekBarPosition(int position);
}

View File

@ -4,6 +4,7 @@ import com.google.inject.Inject;
import musicplayer.StartPlayingException;
import musicplayer.callbacks.PlayerCallbackInterface;
import musicplayer.model.Song;
import musicplayer.playlist.IPlaylist;
import org.gstreamer.ClockTime;
import org.gstreamer.ElementFactory;
import org.gstreamer.Gst;
@ -22,14 +23,16 @@ public class GStreamerPlayer implements IPlayer{
private Song currentSong;
private final PlayerCallbackInterface callbackInterface;
private int currentVolume = 100;
private final IPlaylist playlist;
/**
* Manages GStreamer based playback operations.
* @param callbackInterface Interface on which UI updates can be called.
*/
@Inject
public GStreamerPlayer(PlayerCallbackInterface callbackInterface) {
public GStreamerPlayer(PlayerCallbackInterface callbackInterface, IPlaylist playlist) {
this.callbackInterface = callbackInterface;
this.playlist = playlist;
Gst.init();
playBin = new PlayBin2("BusMessages");
playBin.setVideoSink(ElementFactory.make("fakesink", "videosink"));
@ -38,16 +41,39 @@ public class GStreamerPlayer implements IPlayer{
Thread callbackThing = new Thread(() -> {
try {
Thread.sleep(1000); // Song is about to finish, wait so we don't cut it off early.
} catch (InterruptedException e) {
playSong(playlist.getNext(currentSong));
} catch (InterruptedException | StartPlayingException e) {
e.printStackTrace();
}
callbackInterface.playNextSong();
});
callbackThing.start();
});
if (callbackInterface != null) {
Thread seekBarUpdater = new Thread(() -> {
boolean running = true;
while (running) {
try {
Thread.sleep(1000);
if (isPlaying())
callbackInterface.setSeekBarPosition(currentSongPosition());
} catch (InterruptedException e) {
running = false;
}
}
}, "seekbar");
seekBarUpdater.start();
}
currentVolume = getVolume();
}
private void resetSeek(){
callbackInterface.setSeekBarPosition(0);
}
public void play() throws StartPlayingException {
playSong(playlist.getActive());
}
/**
* Set a source Song file and start playing it via GStreamer.
* @param inputSong Song to play.
@ -60,13 +86,14 @@ public class GStreamerPlayer implements IPlayer{
resume();
return;
}
resetSeek();
playBin.setState(State.READY);
currentSong = inputSong.get();
callbackInterface.setSongHighlighting(currentSong);
playlist.setPlayingSong(currentSong);
File songFile = currentSong.getSongFile();
if (!songFile.exists()) {
callbackInterface.playNextSong();
callbackInterface.removeInvalidSong(currentSong);
playlist.delete(currentSong);
next();
return;
}
playBin.setURI(songFile.toURI());
@ -95,7 +122,8 @@ public class GStreamerPlayer implements IPlayer{
playBin.stop();
internalThread.stop();
thread = null;
callbackInterface.playerStopped();
resetSeek();
playlist.setPlayingSong(currentSong);
}
}
@ -110,9 +138,18 @@ public class GStreamerPlayer implements IPlayer{
* Pause the currently playing song.
*/
public void pause() {
playlist.setPlayingSong(currentSong);
playBin.pause();
}
public void next() throws StartPlayingException {
playSong(playlist.getNext(currentSong));
}
public void previous() throws StartPlayingException{
playSong(playlist.getPrevious(currentSong));
}
/**
* @return The Song currently being played or ready to be played.
*/

View File

@ -6,10 +6,13 @@ import musicplayer.model.Song;
import java.util.Optional;
public interface IPlayer {
void play() throws StartPlayingException;
void playSong(Optional<Song> inputSong) throws StartPlayingException;
void stop();
void resume();
void pause();
void next() throws StartPlayingException;
void previous() throws StartPlayingException;
Song getCurrentSong();
int currentSongPosition();
void setVolume(int volume);