GStreamerPlayer no longer proxies via PlayerGUI to interact with a playlist.
This commit is contained in:
parent
974ff2c8c1
commit
41e7de065e
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,8 @@ public class StartPlayingException extends Exception {
|
||||
public StartPlayingException(Song song){
|
||||
this.song = song;
|
||||
}
|
||||
|
||||
public Song getSong() {
|
||||
return song;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user