Added functionality for reading m3u playlists.

This commit is contained in:
neviyn 2016-03-09 01:58:19 +00:00
parent 1eceab8227
commit 68aca0d416
4 changed files with 90 additions and 23 deletions

View File

@ -10,6 +10,8 @@ import musicplayer.db.Gateway;
import musicplayer.model.Album;
import musicplayer.model.Song;
import musicplayer.swingmodels.PlaylistTableModel;
import musicplayer.util.LibraryUtils;
import musicplayer.util.PlaylistUtils;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
@ -17,7 +19,10 @@ import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
@ -432,19 +437,20 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
});
playlistTools.add(menuItem);
FileNameExtensionFilter m3uExtensionFilter = new FileNameExtensionFilter("m3u playlist", "m3u");
menuItem = new JMenuItem("Save Playlist");
menuItem.addActionListener(e -> {
if(!playlistTableModel.isEmpty()) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
fileChooser.setSelectedFile(new File("playlist.m3u"));
fileChooser.setFileFilter(new FileNameExtensionFilter("m3u playlist", "m3u"));
fileChooser.setFileFilter(m3uExtensionFilter);
if (fileChooser.showSaveDialog(mainPanel) == JFileChooser.APPROVE_OPTION) {
String filename = fileChooser.getSelectedFile().toString();
if (!filename.endsWith(".m3u"))
filename += ".m3u";
try {
playlistTableModel.writePlaylistToFile(new File(filename));
PlaylistUtils.writePlaylistToFile(playlistTableModel.getSongList(), new File(filename));
} catch (IOException e1) {
JOptionPane.showMessageDialog(null, e1.getMessage() + "\n" + Arrays.toString(e1.getStackTrace()), "Error", JOptionPane.ERROR_MESSAGE);
}
@ -453,6 +459,17 @@ public class PlayerGUI implements PlayerCallbackInterface, LibraryCallbackInterf
});
playlistTools.add(menuItem);
menuItem = new JMenuItem("Open Playlist");
menuItem.addActionListener(e -> {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
fileChooser.setFileFilter(m3uExtensionFilter);
if(fileChooser.showOpenDialog(mainPanel) == JFileChooser.APPROVE_OPTION){
PlaylistUtils.readPlaylistFromFile(fileChooser.getSelectedFile()).stream().forEach(playlistTableModel::addSong);
}
});
playlistTools.add(menuItem);
// Add everything to the menu bar itself
menuBar.add(playlistTools);
return menuBar;

View File

@ -3,7 +3,6 @@ package musicplayer.swingmodels;
import musicplayer.model.Song;
import javax.swing.table.AbstractTableModel;
import java.io.*;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@ -170,20 +169,10 @@ public class PlaylistTableModel extends AbstractTableModel {
fireTableDataChanged();
}
public String getM3UPlaylist(){
StringBuilder output = new StringBuilder("#EXTM3U\n");
songList.forEach(x -> output.append(x.getM3UFormatString()));
return output.toString();
}
public void writePlaylistToFile(File targetFile) throws IOException {
if(!targetFile.exists())
targetFile.createNewFile();
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "utf-8"))) {
writer.write("#EXTM3U\n");
for(Song song : songList){
writer.write(song.getM3UFormatString());
}
}
/**
* @return Songs currently in the playlist.
*/
public List<Song> getSongList(){
return songList;
}
}

View File

@ -1,4 +1,4 @@
package musicplayer;
package musicplayer.util;
import musicplayer.callbacks.LibraryCallbackInterface;
import musicplayer.db.Gateway;
@ -16,7 +16,7 @@ import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
final class LibraryUtils {
public final class LibraryUtils {
private static final String musicFileExtensionRegex = "(?iu).*\\.(mp3|mp4|flac|ogg)";
private static Thread updaterThread;
@ -35,7 +35,7 @@ final class LibraryUtils {
.filter(f -> f.toString().matches(musicFileExtensionRegex)).map(LibraryUtils::autoParse)
.forEach(x -> x.ifPresent(i -> {
Gateway.addSong(i);
if(callbacksEnabled)
if (callbacksEnabled)
callbackInterface.currentlyUpdating(i.toString());
}));
} catch (IOException e) {
@ -63,7 +63,7 @@ final class LibraryUtils {
* @param targetFile Path to file to extract metadata from.
* @return Metadata contained in targetFile.
*/
private static Optional<ExtractedMetadata> autoParse(Path targetFile) {
public static Optional<ExtractedMetadata> autoParse(Path targetFile) {
Tag audioTags = null;
try {
audioTags = AudioFileIO.read(targetFile.toFile()).getTag();

View File

@ -0,0 +1,61 @@
package musicplayer.util;
import musicplayer.model.Album;
import musicplayer.model.Artist;
import musicplayer.model.Song;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public final class PlaylistUtils {
/**
* Write a list of songs to a file as an m3u format playlist file.
* @param playlist Playlist of songs to write.
* @param targetFile File to write playlist into.
* @throws IOException
*/
public static void writePlaylistToFile(List<Song> playlist, File targetFile) throws IOException {
if(!targetFile.exists())
targetFile.createNewFile();
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile), "utf-8"))) {
writer.write("#EXTM3U\n");
for(Song song : playlist){
writer.write(song.getM3UFormatString());
}
}
}
/**
* Read songs in from an m3u playlist.
* Songs in the playlist with files that don't actually exists will be dropped.
* @param targetFile File to read m3u playlist data from.
* @return List of songs contained in the playlist.
*/
public static List<Song> readPlaylistFromFile(File targetFile){
List<Song> result = new ArrayList<>();
if(targetFile.exists()){
try {
List<String> playlistData = Files.lines(targetFile.toPath()).filter(x -> !x.isEmpty() && !x.contains("#EXTINF")).collect(Collectors.toList());
if(playlistData.get(0).equals("#EXTM3U")){
playlistData.remove(0);
List<Path> songPaths = playlistData.stream().map(Paths::get).collect(Collectors.toList());
for(int i = 0; i < songPaths.size(); i++){
if(!Files.exists(songPaths.get(i))){ // If song file doesn't exists, try treating it as relative
songPaths.set(i, Paths.get(targetFile.getParent(), songPaths.get(i).toString()));
}
}
songPaths.stream().map(LibraryUtils::autoParse).filter(Optional::isPresent).map(Optional::get)
.forEach(x -> result.add(new Song(x.getTrackNumber(), x.getDiscNumber(), x.getTitle(), new Artist(x.getArtist()), new Album(x.getAlbum()), x.getGenre(), x.getSongFile())));
}
} catch (IOException ignored) { }
}
return result;
}
}