Player now properly handles empty playlists and songs with missing files.

This commit is contained in:
neviyn 2016-02-24 15:04:45 +00:00
parent 1af5f72e1d
commit 1068e67e89
4 changed files with 42 additions and 19 deletions

View File

@ -8,6 +8,7 @@ import org.gstreamer.State;
import org.gstreamer.elements.PlayBin2; import org.gstreamer.elements.PlayBin2;
import java.io.File; import java.io.File;
import java.util.Optional;
public class Player { public class Player {
@ -43,15 +44,21 @@ public class Player {
/** /**
* Set a source Song file and start playing it via GStreamer. * Set a source Song file and start playing it via GStreamer.
* @param song Song to play. * @param inputSong Song to play.
*/ */
public void playSong(Song song) { public void playSong(Optional<Song> inputSong){
callbackInterface.setSongHighlighting(song);
currentSong = song;
File songFile = song.getSongFile();
if (playBin.getState() == State.PLAYING) if (playBin.getState() == State.PLAYING)
stop(); stop();
playBin.setState(State.READY); playBin.setState(State.READY);
if(inputSong.isPresent()) {
currentSong = inputSong.get();
callbackInterface.setSongHighlighting(currentSong);
File songFile = currentSong.getSongFile();
if (!songFile.exists()) {
callbackInterface.removeInvalidSong(currentSong);
playSong(callbackInterface.getNextSong(currentSong));
return;
}
playBin.setURI(songFile.toURI()); playBin.setURI(songFile.toURI());
internalThread = new InternalThread(); internalThread = new InternalThread();
thread = new Thread(internalThread); thread = new Thread(internalThread);
@ -62,6 +69,7 @@ public class Player {
} // Wait for song to actually be playing otherwise queryDuration is always zero } // Wait for song to actually be playing otherwise queryDuration is always zero
callbackInterface.setSeekBarDuration((int) playBin.queryDuration().toSeconds()); callbackInterface.setSeekBarDuration((int) playBin.queryDuration().toSeconds());
} }
}
/** /**
* Stop any music currently playing. * Stop any music currently playing.

View File

@ -66,7 +66,7 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
//Action Listeners //Action Listeners
playButton.addActionListener(e -> { playButton.addActionListener(e -> {
if (playList.getRowCount() > 0) { if (playList.getRowCount() > 0) {
player.playSong(playlistTableModel.getFirst().get()); player.playSong(playlistTableModel.getFirst());
} }
}); });
MouseListener mouseListener = new libraryMouseAdapter(); MouseListener mouseListener = new libraryMouseAdapter();
@ -150,7 +150,7 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
* @return The next song to be selected. * @return The next song to be selected.
*/ */
@Override @Override
public Song getNextSong(Song currentSong) { public Optional<Song> getNextSong(Song currentSong) {
return playlistTableModel.nextSong(currentSong); return playlistTableModel.nextSong(currentSong);
} }
@ -180,6 +180,11 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
SwingUtilities.invokeLater(() -> seekBar.setMaximum(seconds)); SwingUtilities.invokeLater(() -> seekBar.setMaximum(seconds));
} }
@Override
public void removeInvalidSong(Song invalidSong) {
playlistTableModel.removeSong(invalidSong);
}
public void refreshLibrary(){ public void refreshLibrary(){
DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode()); DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode());
DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) model.getRoot(); DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) model.getRoot();
@ -261,4 +266,5 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
private void setVolumeValue(int value){ private void setVolumeValue(int value){
volumeValue.setText(String.format("%d%%", value)); volumeValue.setText(String.format("%d%%", value));
} }
} }

View File

@ -66,10 +66,10 @@ public class PlaylistTableModel extends AbstractTableModel {
return songList.size() > 0 ? Optional.of(songList.get(0)) : Optional.<Song>empty(); return songList.size() > 0 ? Optional.of(songList.get(0)) : Optional.<Song>empty();
} }
public Song nextSong(Song song){ public Optional<Song> nextSong(Song song){
int index = songList.indexOf(song) + 1; int index = songList.indexOf(song) + 1;
if(index >= songList.size()) index = 0; if(index >= songList.size()) index = 0;
return songList.get(index); return songList.size() > 0 ? Optional.of(songList.get(index)) : Optional.empty();
} }
public Song previous(Song song){ public Song previous(Song song){
@ -94,4 +94,9 @@ public class PlaylistTableModel extends AbstractTableModel {
Collections.reverse(indices); Collections.reverse(indices);
indices.forEach(this::removeSong); indices.forEach(this::removeSong);
} }
public void removeSong(Song song){
songList.remove(song);
fireTableDataChanged();
}
} }

View File

@ -2,12 +2,16 @@ package musicplayer.callbacks;
import musicplayer.model.Song; import musicplayer.model.Song;
import java.util.Optional;
public interface PlayerCallbackInterface { public interface PlayerCallbackInterface {
Song getNextSong(Song currentSong); Optional<Song> getNextSong(Song currentSong);
void setSongHighlighting(Song playingSong); void setSongHighlighting(Song playingSong);
void setSeekBarDuration(int seconds); void setSeekBarDuration(int seconds);
void removeInvalidSong(Song invalidSong);
} }