Added functionality for reading m3u playlists.
This commit is contained in:
parent
1eceab8227
commit
68aca0d416
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
61
src/main/java/musicplayer/util/PlaylistUtils.java
Normal file
61
src/main/java/musicplayer/util/PlaylistUtils.java
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user