diff options
author | Scott Jackson <daneren2005@gmail.com> | 2012-11-25 12:09:19 -0800 |
---|---|---|
committer | Scott Jackson <daneren2005@gmail.com> | 2012-11-25 12:09:19 -0800 |
commit | f208d0562a619596ebf0ba982599564e7f860756 (patch) | |
tree | 2086621d0ca152e80eac35e4e8438d6b758ce057 /subsonic-android/src | |
parent | 4770337d1e8c78facb5fe4f5bf7bfcd428e2cfa9 (diff) | |
parent | 836141bc69e30848adf049a50a95cf4d81c38cc1 (diff) | |
download | dsub-f208d0562a619596ebf0ba982599564e7f860756.tar.gz dsub-f208d0562a619596ebf0ba982599564e7f860756.tar.bz2 dsub-f208d0562a619596ebf0ba982599564e7f860756.zip |
Merge branch 'master' of https://github.com/daneren2005/Subsonic.git
Diffstat (limited to 'subsonic-android/src')
12 files changed, 228 insertions, 183 deletions
diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/PlayVideoActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/PlayVideoActivity.java deleted file mode 100644 index 7a77736e..00000000 --- a/subsonic-android/src/github/daneren2005/dsub/activity/PlayVideoActivity.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - This file is part of Subsonic. - - Subsonic is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Subsonic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Subsonic. If not, see <http://www.gnu.org/licenses/>. - - Copyright 2009 (C) Sindre Mehus - */ - -package github.daneren2005.dsub.activity; - -import java.lang.reflect.Method; - -import android.app.Activity; -import android.graphics.Bitmap; -import android.media.AudioManager; -import android.os.Bundle; -import android.util.Log; -import android.view.Window; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import github.daneren2005.dsub.R; -import github.daneren2005.dsub.service.MusicServiceFactory; -import github.daneren2005.dsub.util.Constants; -import github.daneren2005.dsub.util.Util; - -/** - * Plays videos in a web page. - * - * @author Sindre Mehus - */ -public final class PlayVideoActivity extends Activity { - - private static final String TAG = PlayVideoActivity.class.getSimpleName(); - private WebView webView; - - @Override - protected void onCreate(Bundle bundle) { - super.onCreate(bundle); - getWindow().requestFeature(Window.FEATURE_NO_TITLE); - setVolumeControlStream(AudioManager.STREAM_MUSIC); - - setContentView(R.layout.play_video); - - webView = (WebView) findViewById(R.id.play_video_contents); - webView.getSettings().setJavaScriptEnabled(true); - webView.getSettings().setPluginsEnabled(true); - webView.getSettings().setAllowFileAccess(true); - webView.getSettings().setSupportZoom(true); - webView.getSettings().setBuiltInZoomControls(true); - - webView.setWebViewClient(new Client()); - if (bundle != null) { - webView.restoreState(bundle); - } else { - webView.loadUrl(getVideoUrl()); - } - - // Show warning if Flash plugin is not installed. - if (isFlashPluginInstalled()) { - Util.toast(this, R.string.play_video_loading, false); - } else { - Util.toast(this, R.string.play_video_noplugin, false); - } - } - - @Override - protected void onPause() { - super.onPause(); - callHiddenWebViewMethod("onPause"); - } - - @Override - protected void onResume() { - super.onResume(); - callHiddenWebViewMethod("onResume"); - } - - private String getVideoUrl() { - String id = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ID); - return MusicServiceFactory.getMusicService(this).getVideoUrl(this, id); - } - - @Override - protected void onSaveInstanceState(Bundle state) { - webView.saveState(state); - } - - private void callHiddenWebViewMethod(String name){ - if( webView != null ){ - try { - Method method = WebView.class.getMethod(name); - method.invoke(webView); - } catch (Throwable x) { - Log.e(TAG, "Failed to invoke " + name, x); - } - } - } - - private boolean isFlashPluginInstalled() { - try { - PackageInfo packageInfo = getPackageManager().getPackageInfo("com.adobe.flashplayer", 0); - return packageInfo != null; - } catch (PackageManager.NameNotFoundException x) { - return false; - } - } - - private final class Client extends WebViewClient { - - @Override - public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { - Util.toast(PlayVideoActivity.this, description); - Log.e(TAG, "Error: " + description); - } - - @Override - public void onLoadResource(WebView view, String url) { - super.onLoadResource(view, url); - Log.d(TAG, "onLoadResource: " + url); - } - - @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) { - super.onPageStarted(view, url, favicon); - Log.d(TAG, "onPageStarted: " + url); - } - - @Override - public void onPageFinished(WebView view, String url) { - super.onPageFinished(view, url); - Log.d(TAG, "onPageFinished: " + url); - } - } -} diff --git a/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java b/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java index ccd5d5af..891c2edd 100644 --- a/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java +++ b/subsonic-android/src/github/daneren2005/dsub/activity/SelectAlbumActivity.java @@ -34,14 +34,11 @@ import android.widget.*; import com.actionbarsherlock.view.Menu; import github.daneren2005.dsub.R; import github.daneren2005.dsub.domain.MusicDirectory; -import github.daneren2005.dsub.service.MusicService; -import github.daneren2005.dsub.service.MusicServiceFactory; +import github.daneren2005.dsub.service.*; import github.daneren2005.dsub.util.*; +import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class SelectAlbumActivity extends SubsonicTabActivity { @@ -78,7 +75,7 @@ public class SelectAlbumActivity extends SubsonicTabActivity { intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, entry.getTitle()); Util.startActivityWithoutTransition(SelectAlbumActivity.this, intent); } else if (entry.isVideo()) { - playVideo(entry); + playExternalPlayer(entry); } } } @@ -113,10 +110,17 @@ public class SelectAlbumActivity extends SubsonicTabActivity { inflater.inflate(R.menu.select_album, menu); hideButtons = false; } else { - if(Util.isOffline(this)) + if(Util.isOffline(this)) { inflater.inflate(R.menu.select_song_offline, menu); - else + } + else { inflater.inflate(R.menu.select_song, menu); + + String playlistId = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID); + if(playlistId == null) { + menu.removeItem(R.id.menu_remove_playlist); + } + } } return true; } @@ -155,6 +159,11 @@ public class SelectAlbumActivity extends SubsonicTabActivity { case R.id.menu_add_playlist: addToPlaylist(getSelectedSongs()); return true; + case R.id.menu_remove_playlist: + String playlistId = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID); + String playlistName = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME); + removeFromPlaylist(playlistId, playlistName, getSelectedIndexes()); + return true; case R.id.menu_exit: intent = new Intent(this, MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); @@ -222,13 +231,25 @@ public class SelectAlbumActivity extends SubsonicTabActivity { inflater.inflate(R.menu.select_album_context_offline, menu); else inflater.inflate(R.menu.select_album_context, menu); - } else { + } else if(!entry.isVideo()) { MenuInflater inflater = getMenuInflater(); - if(Util.isOffline(this)) + if(Util.isOffline(this)) { inflater.inflate(R.menu.select_song_context_offline, menu); - else + } + else { inflater.inflate(R.menu.select_song_context, menu); - } + String playlistId = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID); + if(playlistId == null) { + menu.removeItem(R.id.song_menu_remove_playlist); + } + } + } else { + MenuInflater inflater = getMenuInflater(); + if(Util.isOffline(this)) + inflater.inflate(R.menu.select_video_context_offline, menu); + else + inflater.inflate(R.menu.select_video_context, menu); + } if (!Util.isOffline(this)) { menu.findItem(entry.isDirectory() ? R.id.album_menu_star : R.id.song_menu_star).setTitle(entry.isStarred() ? R.string.common_unstar : R.string.common_star); @@ -284,6 +305,17 @@ public class SelectAlbumActivity extends SubsonicTabActivity { case R.id.song_menu_star: toggleStarred(entry); break; + case R.id.song_menu_webview: + playWebView(entry); + break; + case R.id.song_menu_play_external: + playExternalPlayer(entry); + break; + case R.id.song_menu_remove_playlist: + String playlistId = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID); + String playlistName = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME); + removeFromPlaylist(playlistId, playlistName, Arrays.<Integer>asList(info.position - 1)); + break; default: return super.onContextItemSelected(menuItem); } @@ -411,6 +443,19 @@ public class SelectAlbumActivity extends SubsonicTabActivity { } return songs; } + + private List<Integer> getSelectedIndexes() { + List<Integer> indexes = new ArrayList<Integer>(); + + int count = entryList.getCount(); + for (int i = 0; i < count; i++) { + if (entryList.isItemChecked(i)) { + indexes.add(i - 1); + } + } + + return indexes; + } private void download(final boolean append, final boolean save, final boolean autoplay, final boolean playNext, final boolean shuffle) { if (getDownloadService() == null) { @@ -483,12 +528,22 @@ public class SelectAlbumActivity extends SubsonicTabActivity { } } - private void playVideo(MusicDirectory.Entry entry) { + private void playWebView(MusicDirectory.Entry entry) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(MusicServiceFactory.getMusicService(this).getVideoUrl(this, entry.getId()))); - + startActivity(intent); } + private void playExternalPlayer(MusicDirectory.Entry entry) { + DownloadFile check = new DownloadFile(this, entry, false); + if(!check.isCompleteFileAvailable()) { + Util.toast(this, R.string.download_need_download); + } else { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(Uri.parse(entry.getPath()), "video/*"); + startActivity(intent); + } + } private void checkLicenseAndTrialPeriod(Runnable onValid) { if (licenseValid) { @@ -627,4 +682,33 @@ public class SelectAlbumActivity extends SubsonicTabActivity { return header; } + + public void removeFromPlaylist(final String id, final String name, final List<Integer> indexes) { + new LoadingTask<Void>(this, true) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(SelectAlbumActivity.this); + musicService.removeFromPlaylist(id, indexes, SelectAlbumActivity.this, null); + return null; + } + + @Override + protected void done(Void result) { + refresh(); + Util.toast(SelectAlbumActivity.this, getResources().getString(R.string.removed_playlist, indexes.size(), name)); + } + + @Override + protected void error(Throwable error) { + String msg; + if (error instanceof OfflineException || error instanceof ServerTooOldException) { + msg = getErrorMessage(error); + } else { + msg = getResources().getString(R.string.updated_playlist_error, name) + " " + getErrorMessage(error); + } + + Util.toast(SelectAlbumActivity.this, msg, false); + } + }.execute(); + } } diff --git a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java index 798cf8e6..fe0a3f19 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/CachedMusicService.java @@ -53,7 +53,7 @@ public class CachedMusicService implements MusicService { private final LRUCache<String, TimeLimitedCache<MusicDirectory>> cachedMusicDirectories; private final TimeLimitedCache<Boolean> cachedLicenseValid = new TimeLimitedCache<Boolean>(120, TimeUnit.SECONDS); private final TimeLimitedCache<Indexes> cachedIndexes = new TimeLimitedCache<Indexes>(60 * 60, TimeUnit.SECONDS); - private final TimeLimitedCache<List<Playlist>> cachedPlaylists = new TimeLimitedCache<List<Playlist>>(60, TimeUnit.SECONDS); + private final TimeLimitedCache<List<Playlist>> cachedPlaylists = new TimeLimitedCache<List<Playlist>>(3600, TimeUnit.SECONDS); private final TimeLimitedCache<List<MusicFolder>> cachedMusicFolders = new TimeLimitedCache<List<MusicFolder>>(10 * 3600, TimeUnit.SECONDS); private String restUrl; @@ -146,6 +146,7 @@ public class CachedMusicService implements MusicService { @Override public void createPlaylist(String id, String name, List<MusicDirectory.Entry> entries, Context context, ProgressListener progressListener) throws Exception { + cachedPlaylists.clear(); musicService.createPlaylist(id, name, entries, context, progressListener); } @@ -160,6 +161,11 @@ public class CachedMusicService implements MusicService { } @Override + public void removeFromPlaylist(String id, List<Integer> toRemove, Context context, ProgressListener progressListener) throws Exception { + musicService.removeFromPlaylist(id, toRemove, context, progressListener); + } + + @Override public void updatePlaylist(String id, String name, String comment, Context context, ProgressListener progressListener) throws Exception { musicService.updatePlaylist(id, name, comment, context, progressListener); } @@ -185,8 +191,8 @@ public class CachedMusicService implements MusicService { } @Override - public MusicDirectory getRandomSongs(int size, String folder, Context context, ProgressListener progressListener) throws Exception { - return musicService.getRandomSongs(size, folder, context, progressListener); + public MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception { + return musicService.getRandomSongs(size, folder, genre, startYear, endYear, context, progressListener); } @Override @@ -213,6 +219,11 @@ public class CachedMusicService implements MusicService { public String getVideoUrl(Context context, String id) { return musicService.getVideoUrl(context, id); } + + @Override + public String getVideoStreamUrl(Context context, String id) { + return musicService.getVideoStreamUrl(context, id); + } @Override public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception { diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadService.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadService.java index d11c8285..f68f8db6 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadService.java @@ -38,6 +38,8 @@ public interface DownloadService { void setShufflePlayEnabled(boolean enabled); boolean isShufflePlayEnabled(); + + void setShuffleParams(String genre, String startYear, String endYear); void shuffle(); diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java index 38b3fe03..aae4829a 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java @@ -299,6 +299,11 @@ public class DownloadServiceImpl extends Service implements DownloadService { public synchronized boolean isShufflePlayEnabled() { return shufflePlay; } + + @Override + public void setShuffleParams(String genre, String startYear, String endYear) { + shufflePlayBuffer.setOptions(genre, startYear, endYear); + } @Override public synchronized void shuffle() { diff --git a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java index 1dc247f1..98951853 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/MusicService.java @@ -65,6 +65,8 @@ public interface MusicService { void addToPlaylist(String id, List<MusicDirectory.Entry> toAdd, Context context, ProgressListener progressListener) throws Exception; + void removeFromPlaylist(String id, List<Integer> toRemove, Context context, ProgressListener progressListener) throws Exception; + void updatePlaylist(String id, String name, String comment, Context context, ProgressListener progressListener) throws Exception; Lyrics getLyrics(String artist, String title, Context context, ProgressListener progressListener) throws Exception; @@ -73,7 +75,7 @@ public interface MusicService { MusicDirectory getAlbumList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception; - MusicDirectory getRandomSongs(int size, String folder, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception; Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, boolean saveToFile, ProgressListener progressListener) throws Exception; @@ -84,6 +86,8 @@ public interface MusicService { Version getLatestVersion(Context context, ProgressListener progressListener) throws Exception; String getVideoUrl(Context context, String id); + + String getVideoStreamUrl(Context context, String id); JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception; diff --git a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java index 29249268..a12a169e 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java @@ -86,7 +86,7 @@ public class OfflineMusicService extends RESTMusicService { Set<String> names = new HashSet<String>(); - for (File file : FileUtil.listMusicFiles(dir)) { + for (File file : FileUtil.listMediaFiles(dir)) { String name = getName(file); if (name != null & !names.contains(name)) { names.add(name); @@ -129,6 +129,9 @@ public class OfflineMusicService extends RESTMusicService { if (albumArt.exists()) { entry.setCoverArt(albumArt.getPath()); } + if(FileUtil.isVideoFile(file)) { + entry.setVideo(true); + } return entry; } @@ -174,7 +177,7 @@ public class OfflineMusicService extends RESTMusicService { } private void recursiveAlbumSearch(String artistName, File file, SearchCritera criteria, Context context, List<MusicDirectory.Entry> albums, List<MusicDirectory.Entry> songs) { - for(File albumFile : FileUtil.listMusicFiles(file)) { + for(File albumFile : FileUtil.listMediaFiles(file)) { if(albumFile.isDirectory()) { String albumName = getName(albumFile); if(matchCriteria(criteria, albumName)) { @@ -183,7 +186,7 @@ public class OfflineMusicService extends RESTMusicService { albums.add(album); } - for(File songFile : FileUtil.listMusicFiles(albumFile)) { + for(File songFile : FileUtil.listMediaFiles(albumFile)) { String songName = getName(songFile); if(songFile.isDirectory()) { recursiveAlbumSearch(artistName, songFile, criteria, context, albums, songs); @@ -292,6 +295,11 @@ public class OfflineMusicService extends RESTMusicService { } @Override + public void removeFromPlaylist(String id, List<Integer> toRemove, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException("Removing from playlist not available in offline mode"); + } + + @Override public void updatePlaylist(String id, String name, String comment, Context context, ProgressListener progressListener) throws Exception { throw new OfflineException("Updating playlist not available in offline mode"); } @@ -315,6 +323,11 @@ public class OfflineMusicService extends RESTMusicService { public String getVideoUrl(Context context, String id) { return null; } + + @Override + public String getVideoStreamUrl(Context context, String id) { + return null; + } @Override public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception { @@ -352,7 +365,7 @@ public class OfflineMusicService extends RESTMusicService { } @Override - public MusicDirectory getRandomSongs(int size, String folder, Context context, ProgressListener progressListener) throws Exception { + public MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception { File root = FileUtil.getMusicDirectory(context); List<File> children = new LinkedList<File>(); listFilesRecursively(root, children); @@ -371,7 +384,7 @@ public class OfflineMusicService extends RESTMusicService { } private void listFilesRecursively(File parent, List<File> children) { - for (File file : FileUtil.listMusicFiles(parent)) { + for (File file : FileUtil.listMediaFiles(parent)) { if (file.isFile()) { children.add(file); } else { diff --git a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java index 60cffc7b..75ec6142 100644 --- a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java +++ b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java @@ -214,7 +214,7 @@ public class RESTMusicService implements MusicService { return cachedIndexes; } - long lastModified = cachedIndexes == null ? 0L : cachedIndexes.getLastModified(); + long lastModified = (cachedIndexes == null || refresh) ? 0L : cachedIndexes.getLastModified(); List<String> parameterNames = new ArrayList<String>(); List<Object> parameterValues = new ArrayList<Object>(); @@ -423,6 +423,25 @@ public class RESTMusicService implements MusicService { } @Override + public void removeFromPlaylist(String id, List<Integer> toRemove, Context context, ProgressListener progressListener) throws Exception { + checkServerVersion(context, "1.8", "Updating playlists is not supported."); + List<String> names = new ArrayList<String>(); + List<Object> values = new ArrayList<Object>(); + names.add("playlistId"); + values.add(id); + for(Integer song: toRemove) { + names.add("songIndexToRemove"); + values.add(song); + } + Reader reader = getReader(context, progressListener, "updatePlaylist", null, names, values); + try { + new ErrorParser(context).parse(reader); + } finally { + Util.close(reader); + } + } + + @Override public void updatePlaylist(String id, String name, String comment, Context context, ProgressListener progressListener) throws Exception { checkServerVersion(context, "1.8", "Updating playlists is not supported."); Reader reader = getReader(context, progressListener, "updatePlaylist", null, Arrays.asList("playlistId", "name", "comment"), Arrays.<Object>asList(id, name, comment)); @@ -476,7 +495,7 @@ public class RESTMusicService implements MusicService { } @Override - public MusicDirectory getRandomSongs(int size, String musicFolderId, Context context, ProgressListener progressListener) throws Exception { + public MusicDirectory getRandomSongs(int size, String musicFolderId, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception { HttpParams params = new BasicHttpParams(); HttpConnectionParams.setSoTimeout(params, SOCKET_READ_TIMEOUT_GET_RANDOM_SONGS); @@ -490,6 +509,18 @@ public class RESTMusicService implements MusicService { names.add("musicFolderId"); values.add(musicFolderId); } + if(genre != null) { + names.add("genre"); + values.add(genre); + } + if(startYear != null) { + names.add("fromYear"); + values.add(startYear); + } + if(endYear != null) { + names.add("toYear"); + values.add(endYear); + } Reader reader = getReader(context, progressListener, "getRandomSongs", params, names, values); try { @@ -619,6 +650,17 @@ public class RESTMusicService implements MusicService { Log.i(TAG, "Using video URL: " + url); return url; } + + @Override + public String getVideoStreamUrl(Context context, String id) { + StringBuilder builder = new StringBuilder(Util.getRestUrl(context, "stream")); + builder.append("&id=").append(id); + builder.append("&maxBitRate=500"); + + String url = rewriteUrlWithRedirect(context, builder.toString()); + Log.i(TAG, "Using video URL: " + url); + return url; + } @Override public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception { diff --git a/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java b/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java index da7c8fdc..890420fc 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<String> MUSIC_FILE_EXTENSIONS = Arrays.asList("mp3", "ogg", "aac", "flac", "m4a", "wav", "wma"); + private static final List<String> VIDEO_FILE_EXTENSIONS = Arrays.asList("flv", "mp4", "m4v", "wmv", "avi", "mov", "mpg", "mkv"); private static final List<String> PLAYLIST_FILE_EXTENSIONS = Arrays.asList("m3u"); private static final File DEFAULT_MUSIC_DIR = createDirectory("music"); @@ -237,23 +238,32 @@ public class FileUtil { return new TreeSet<File>(Arrays.asList(files)); } - public static SortedSet<File> listMusicFiles(File dir) { + public static SortedSet<File> listMediaFiles(File dir) { SortedSet<File> files = listFiles(dir); Iterator<File> iterator = files.iterator(); while (iterator.hasNext()) { File file = iterator.next(); - if (!file.isDirectory() && !isMusicFile(file)) { + if (!file.isDirectory() && !isMediaFile(file)) { iterator.remove(); } } return files; } - private static boolean isMusicFile(File file) { + private static boolean isMediaFile(File file) { String extension = getExtension(file.getName()); - return MUSIC_FILE_EXTENSIONS.contains(extension); + return MUSIC_FILE_EXTENSIONS.contains(extension) || VIDEO_FILE_EXTENSIONS.contains(extension); } + public static boolean isMusicFile(File file) { + String extension = getExtension(file.getName()); + return MUSIC_FILE_EXTENSIONS.contains(extension); + } + public static boolean isVideoFile(File file) { + String extension = getExtension(file.getName()); + return VIDEO_FILE_EXTENSIONS.contains(extension); + } + public static boolean isPlaylistFile(File file) { String extension = getExtension(file.getName()); return PLAYLIST_FILE_EXTENSIONS.contains(extension); diff --git a/subsonic-android/src/github/daneren2005/dsub/util/ShufflePlayBuffer.java b/subsonic-android/src/github/daneren2005/dsub/util/ShufflePlayBuffer.java index f30f3d6d..3cc26057 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/ShufflePlayBuffer.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/ShufflePlayBuffer.java @@ -45,6 +45,10 @@ public class ShufflePlayBuffer { private Context context; private int currentServer; private String currentFolder; + + private String genre; + private String startYear; + private String endYear; public ShufflePlayBuffer(Context context) { this.context = context; @@ -88,7 +92,7 @@ public class ShufflePlayBuffer { MusicService service = MusicServiceFactory.getMusicService(context); int n = CAPACITY - buffer.size(); String folder = Util.getSelectedMusicFolderId(context); - MusicDirectory songs = service.getRandomSongs(n, folder, context, null); + MusicDirectory songs = service.getRandomSongs(n, folder, genre, startYear, endYear, context, null); synchronized (buffer) { buffer.addAll(songs.getChildren()); @@ -108,5 +112,11 @@ public class ShufflePlayBuffer { } } } + + public void setOptions(String genre, String startYear, String endYear) { + this.genre = genre; + this.startYear = startYear; + this.endYear = endYear; + } } diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Util.java b/subsonic-android/src/github/daneren2005/dsub/util/Util.java index f8d108d3..2bdd969e 100644 --- a/subsonic-android/src/github/daneren2005/dsub/util/Util.java +++ b/subsonic-android/src/github/daneren2005/dsub/util/Util.java @@ -466,10 +466,17 @@ public final class Util { return null; } - int minutes = seconds / 60; + int hours = seconds / 3600; + int minutes = (seconds / 60) % 60; int secs = seconds % 60; - StringBuilder builder = new StringBuilder(6); + StringBuilder builder = new StringBuilder(7); + if(hours > 0) { + builder.append(hours).append(":"); + if(minutes < 10) { + builder.append("0"); + } + } builder.append(minutes).append(":"); if (secs < 10) { builder.append("0"); diff --git a/subsonic-android/src/github/daneren2005/dsub/view/SongView.java b/subsonic-android/src/github/daneren2005/dsub/view/SongView.java index f1701822..98ceebba 100644 --- a/subsonic-android/src/github/daneren2005/dsub/view/SongView.java +++ b/subsonic-android/src/github/daneren2005/dsub/view/SongView.java @@ -78,9 +78,13 @@ public class SongView extends UpdateView implements Checkable { fileFormat = song.getSuffix(); } - artist.append(song.getArtist()).append(" (") - .append(String.format(getContext().getString(R.string.song_details_all), bitRate == null ? "" : bitRate, fileFormat)) - .append(")"); + if(!song.isVideo()) { + artist.append(song.getArtist()).append(" (") + .append(String.format(getContext().getString(R.string.song_details_all), bitRate == null ? "" : bitRate, fileFormat)) + .append(")"); + } else { + artist.append(String.format(getContext().getString(R.string.song_details_all), bitRate == null ? "" : bitRate, fileFormat)); + } titleTextView.setText(song.getTitle()); artistTextView.setText(artist); |