From 662f6cd23c23aa798e9023d6a7b43208e1c77529 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Sat, 10 Nov 2012 18:02:46 -0800 Subject: Moved to .m3u playlists for small playlist files + can be played by external players #12 --- .../dsub/service/OfflineMusicService.java | 40 +++++++++++++++++----- .../daneren2005/dsub/service/RESTMusicService.java | 39 +++++++++++++-------- .../src/github/daneren2005/dsub/util/FileUtil.java | 14 ++++++-- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java index e39d9233..29249268 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java @@ -34,6 +34,7 @@ import java.util.Set; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.util.Log; import github.daneren2005.dsub.domain.Artist; import github.daneren2005.dsub.domain.Indexes; import github.daneren2005.dsub.domain.JukeboxStatus; @@ -48,11 +49,13 @@ import github.daneren2005.dsub.util.Constants; import github.daneren2005.dsub.util.FileUtil; import github.daneren2005.dsub.util.ProgressListener; import github.daneren2005.dsub.util.Util; +import java.io.*; /** * @author Sindre Mehus */ public class OfflineMusicService extends RESTMusicService { + private static final String TAG = OfflineMusicService.class.getSimpleName(); @Override public boolean isLicenseValid(Context context, ProgressListener progressListener) throws Exception { @@ -223,8 +226,19 @@ public class OfflineMusicService extends RESTMusicService { List playlists = new ArrayList(); File root = FileUtil.getPlaylistDirectory(); for (File file : FileUtil.listFiles(root)) { - Playlist playlist = new Playlist(file.getName(), file.getName()); - playlists.add(playlist); + if(FileUtil.isPlaylistFile(file)) { + String id = file.getName(); + String filename = FileUtil.getBaseName(id); + Playlist playlist = new Playlist(id, filename); + playlists.add(playlist); + } else { + // Delete legacy playlist files + try { + file.delete(); + } catch(Exception e) { + Log.w(TAG, "Failed to delete old playlist file: " + file.getName()); + } + } } return playlists; } @@ -237,19 +251,27 @@ public class OfflineMusicService extends RESTMusicService { } Reader reader = null; + BufferedReader buffer = null; try { - reader = new FileReader(FileUtil.getPlaylistFile(name)); - MusicDirectory fullList = new PlaylistParser(context).parse(reader, progressListener); + File playlistFile = FileUtil.getPlaylistFile(name); + reader = new FileReader(playlistFile); + buffer = new BufferedReader(reader); + MusicDirectory playlist = new MusicDirectory(); - for(MusicDirectory.Entry song: fullList.getChildren()) { - DownloadFile downloadFile = downloadService.forSong(song); - File completeFile = downloadFile.getCompleteFile(); - if(completeFile.exists()) { - playlist.addChild(song); + String line = buffer.readLine(); + if(!"#EXTM3U".equals(line)) return playlist; + + while( (line = buffer.readLine()) != null ){ + File entryFile = new File(line); + String entryName = getName(entryFile); + if(entryFile.exists() && entryName != null){ + playlist.addChild(createEntry(context, entryFile, entryName)); } } + return playlist; } finally { + Util.close(buffer); Util.close(reader); } } diff --git a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java index fd323119..60cffc7b 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java @@ -103,6 +103,7 @@ import github.daneren2005.dsub.util.Constants; import github.daneren2005.dsub.util.FileUtil; import github.daneren2005.dsub.util.ProgressListener; import github.daneren2005.dsub.util.Util; +import java.io.*; /** * @author Sindre Mehus @@ -326,23 +327,31 @@ public class RESTMusicService implements MusicService { HttpConnectionParams.setSoTimeout(params, SOCKET_READ_TIMEOUT_GET_PLAYLIST); Reader reader = getReader(context, progressListener, "getPlaylist", params, "id", id); - OutputStreamWriter out = null; - try { - out = new OutputStreamWriter(new FileOutputStream(FileUtil.getPlaylistFile(name))); + try { + MusicDirectory playlist = new PlaylistParser(context).parse(reader, progressListener); - char[] buff = new char[256]; - int n; - while((n = reader.read(buff)) >= 0) { - out.write(buff, 0, n); + File playlistFile = FileUtil.getPlaylistFile(name); + FileWriter fw = new FileWriter(playlistFile); + BufferedWriter bw = new BufferedWriter(fw); + try { + fw.write("#EXTM3U\n"); + for (MusicDirectory.Entry e : playlist.getChildren()) { + String filePath = FileUtil.getSongFile(context, e).getAbsolutePath(); + if(! new File(filePath).exists()){ + String ext = FileUtil.getExtension(filePath); + String base = FileUtil.getBaseName(filePath); + filePath = base + ".complete." + ext; + } + fw.write(filePath + "\n"); + } + } catch(Exception e) { + Log.w(TAG, "Failed to save playlist: " + name); + } finally { + bw.close(); + fw.close(); } - } finally { - Util.close(out); - Util.close(reader); - } - - try { - reader = new FileReader(FileUtil.getPlaylistFile(name)); - return new PlaylistParser(context).parse(reader, progressListener); + + return playlist; } finally { Util.close(reader); } diff --git a/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java b/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java index d77f21c5..2dbf2d26 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java @@ -46,6 +46,7 @@ public class FileUtil { private static final String[] FILE_SYSTEM_UNSAFE = {"/", "\\", "..", ":", "\"", "?", "*", "<", ">", "|"}; private static final String[] FILE_SYSTEM_UNSAFE_DIR = {"\\", "..", ":", "\"", "?", "*", "<", ">", "|"}; private static final List MUSIC_FILE_EXTENSIONS = Arrays.asList("mp3", "ogg", "aac", "flac", "m4a", "wav", "wma"); + private static final List PLAYLIST_FILE_EXTENSIONS = Arrays.asList("m3u"); private static final File DEFAULT_MUSIC_DIR = createDirectory("music"); public static File getSongFile(Context context, MusicDirectory.Entry song) { @@ -71,9 +72,13 @@ public class FileUtil { return new File(dir, fileName.toString()); } - public static File getPlaylistFile(String id) { + public static File getPlaylistFile(String name) { File playlistDir = getPlaylistDirectory(); - return new File(playlistDir, id); + return new File(playlistDir, name + ".m3u"); + } + public static File getOldPlaylistFile(String name) { + File playlistDir = getPlaylistDirectory(); + return new File(playlistDir, name); } public static File getPlaylistDirectory() { File playlistDir = new File(getSubsonicDirectory(), "playlists"); @@ -248,6 +253,11 @@ public class FileUtil { String extension = getExtension(file.getName()); return MUSIC_FILE_EXTENSIONS.contains(extension); } + + public static boolean isPlaylistFile(File file) { + String extension = getExtension(file.getName()); + return PLAYLIST_FILE_EXTENSIONS.contains(extension); + } /** * Returns the extension (the substring after the last dot) of the given file. The dot -- cgit v1.2.3