diff options
21 files changed, 130 insertions, 9 deletions
diff --git a/app/build.gradle b/app/build.gradle index e8b7108a..2cf18f0e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,8 +1,9 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 22 - buildToolsVersion "22.0.0" + compileSdkVersion 23 + buildToolsVersion "23.0.3" + useLibrary 'org.apache.http.legacy' defaultConfig { applicationId "github.daneren2005.dsub" @@ -42,11 +43,11 @@ android { dependencies { compile project(':Server Proxy') compile fileTree(include: ['*.jar'], dir: 'libs') - compile 'com.android.support:support-v4:22.2.+' - compile 'com.android.support:appcompat-v7:22.2.+' - compile 'com.android.support:mediarouter-v7:22.2.+' - compile 'com.android.support:recyclerview-v7:22.2.+' - compile 'com.android.support:design:22.2.+' + compile 'com.android.support:support-v4:23.3.+' + compile 'com.android.support:appcompat-v7:23.3.+' + compile 'com.android.support:mediarouter-v7:23.3.+' + compile 'com.android.support:recyclerview-v7:23.3.+' + compile 'com.android.support:design:23.3.+' compile 'com.google.android.gms:play-services-cast:8.1.0' compile 'com.sothree.slidinguppanel:library:3.0.0' compile 'de.hdodenhof:circleimageview:1.2.1' diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java index c8e99f51..e4984fce 100644 --- a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java +++ b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java @@ -51,6 +51,7 @@ import android.view.animation.AnimationUtils; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.PopupMenu; import android.widget.SeekBar; import android.widget.TextView; import android.widget.ViewFlipper; @@ -116,6 +117,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis private ImageButton bookmarkButton; private ImageButton rateBadButton; private ImageButton rateGoodButton; + private ImageButton playbackSpeedButton; private ScheduledExecutorService executorService; private DownloadFile currentPlaying; @@ -182,6 +184,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis bookmarkButton = (ImageButton) rootView.findViewById(R.id.download_bookmark); rateBadButton = (ImageButton) rootView.findViewById(R.id.download_rating_bad); rateGoodButton = (ImageButton) rootView.findViewById(R.id.download_rating_good); + playbackSpeedButton = (ImageButton) rootView.findViewById(R.id.download_playback_speed); toggleListButton =rootView.findViewById(R.id.download_toggle_list); playlistView = (RecyclerView)rootView.findViewById(R.id.download_list); @@ -216,6 +219,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis bookmarkButton.setOnTouchListener(touchListener); rateBadButton.setOnTouchListener(touchListener); rateGoodButton.setOnTouchListener(touchListener); + playbackSpeedButton.setOnTouchListener(touchListener); emptyTextView.setOnTouchListener(touchListener); albumArtImageView.setOnTouchListener(new View.OnTouchListener() { @Override @@ -386,6 +390,48 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis } }); + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + playbackSpeedButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + PopupMenu popup = new PopupMenu(context, v); + popup.getMenuInflater().inflate(R.menu.playback_speed_options, popup.getMenu()); + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + DownloadService downloadService = getDownloadService(); + if (downloadService == null) { + return false; + } + + float playbackSpeed = 1.0f; + switch (menuItem.getItemId()) { + case R.id.playback_speed_half: + playbackSpeed = 0.5f; + break; + case R.id.playback_speed_one_half: + playbackSpeed = 1.5f; + break; + case R.id.playback_speed_double: + playbackSpeed = 2.0f; + break; + case R.id.playback_speed_tripple: + playbackSpeed = 3.0f; + break; + } + + downloadService.setPlaybackSpeed(playbackSpeed); + return true; + } + }); + popup.show(); + } + }); + } else { + playbackSpeedButton.setVisibility(View.GONE); + } + toggleListButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java index 01007b68..988dea5f 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java @@ -76,6 +76,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.media.AudioManager; import android.media.MediaPlayer; +import android.media.PlaybackParams; import android.media.audiofx.AudioEffect; import android.net.wifi.WifiManager; import android.os.Build; @@ -161,6 +162,7 @@ public class DownloadService extends Service { private int cachedPosition = 0; private boolean downloadOngoing = false; private float volume = 1.0f; + private long delayUpdateProgress = 1000L; private AudioEffectsController effectsController; private RemoteControlState remoteState = LOCAL; @@ -1503,7 +1505,7 @@ public class DownloadService extends Service { while(isRunning) { try { onSongProgress(); - Thread.sleep(1000L); + Thread.sleep(delayUpdateProgress); } catch(Exception e) { isRunning = false; @@ -1545,7 +1547,7 @@ public class DownloadService extends Service { } } onSongProgress(cachedPosition < 2000 ? true: false); - Thread.sleep(1000L); + Thread.sleep(delayUpdateProgress); } catch(Exception e) { Log.w(TAG, "Crashed getting current position", e); @@ -1877,6 +1879,7 @@ public class DownloadService extends Service { cachedPosition = position; applyReplayGain(mediaPlayer, downloadFile); + applyPlaybackParams(mediaPlayer); if (start || autoPlayStart) { mediaPlayer.start(); @@ -1947,6 +1950,7 @@ public class DownloadService extends Service { } applyReplayGain(nextMediaPlayer, downloadFile); + applyPlaybackParams(nextMediaPlayer); } catch (Exception x) { handleErrorNext(x); } @@ -2600,6 +2604,30 @@ public class DownloadService extends Service { } } + public void setPlaybackSpeed(float playbackSpeed) { + Util.getPreferences(this).edit().putFloat(Constants.PREFERENCES_KEY_PLAYBACK_SPEED, playbackSpeed).commit(); + applyPlaybackParams(mediaPlayer); + if(nextMediaPlayer != null && nextPlayerState == PREPARED) { + applyPlaybackParams(nextMediaPlayer); + } + + delayUpdateProgress = Math.round(1000L / playbackSpeed); + } + public float getPlaybackSpeed() { + return Util.getPreferences(this).getFloat(Constants.PREFERENCES_KEY_PLAYBACK_SPEED, 1.0f); + } + private synchronized void applyPlaybackParams(MediaPlayer mediaPlayer) { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + float playbackSpeed = getPlaybackSpeed(); + + if(playbackSpeed != 1.0f || mediaPlayer.getPlaybackParams() != null) { + PlaybackParams playbackParams = new PlaybackParams(); + playbackParams.setSpeed(playbackSpeed); + mediaPlayer.setPlaybackParams(playbackParams); + } + } + } + public void toggleStarred() { final DownloadFile currentPlaying = this.currentPlaying; if(currentPlaying == null) { diff --git a/app/src/main/java/github/daneren2005/dsub/util/Constants.java b/app/src/main/java/github/daneren2005/dsub/util/Constants.java index ec3489ab..230cce16 100644 --- a/app/src/main/java/github/daneren2005/dsub/util/Constants.java +++ b/app/src/main/java/github/daneren2005/dsub/util/Constants.java @@ -174,6 +174,7 @@ public final class Constants { public static final String PREFERENCES_KEY_CAST_STREAM_ORIGINAL = "castStreamOriginal"; public static final String PREFERENCES_KEY_HEADS_UP_NOTIFICATION = "headsUpNotification"; public static final String PREFERENCES_KEY_CAST_CACHE = "castCache"; + public static final String PREFERENCES_KEY_PLAYBACK_SPEED = "playbackSpeed"; public static final String OFFLINE_SCROBBLE_COUNT = "scrobbleCount"; public static final String OFFLINE_SCROBBLE_ID = "scrobbleID"; diff --git a/app/src/main/res/drawable-hdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-hdpi/ic_action_playback_speed_dark.png Binary files differnew file mode 100644 index 00000000..5f4d890a --- /dev/null +++ b/app/src/main/res/drawable-hdpi/ic_action_playback_speed_dark.png diff --git a/app/src/main/res/drawable-hdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-hdpi/ic_action_playback_speed_light.png Binary files differnew file mode 100644 index 00000000..4b481822 --- /dev/null +++ b/app/src/main/res/drawable-hdpi/ic_action_playback_speed_light.png diff --git a/app/src/main/res/drawable-mdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-mdpi/ic_action_playback_speed_dark.png Binary files differnew file mode 100644 index 00000000..b05ecefd --- /dev/null +++ b/app/src/main/res/drawable-mdpi/ic_action_playback_speed_dark.png diff --git a/app/src/main/res/drawable-mdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-mdpi/ic_action_playback_speed_light.png Binary files differnew file mode 100644 index 00000000..392d2b4d --- /dev/null +++ b/app/src/main/res/drawable-mdpi/ic_action_playback_speed_light.png diff --git a/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_dark.png Binary files differnew file mode 100644 index 00000000..2aeadf7e --- /dev/null +++ b/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_dark.png diff --git a/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_light.png Binary files differnew file mode 100644 index 00000000..ce3f561c --- /dev/null +++ b/app/src/main/res/drawable-xhdpi/ic_action_playback_speed_light.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_dark.png Binary files differnew file mode 100644 index 00000000..a9acc5e6 --- /dev/null +++ b/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_dark.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_light.png Binary files differnew file mode 100644 index 00000000..dcd6fea8 --- /dev/null +++ b/app/src/main/res/drawable-xxhdpi/ic_action_playback_speed_light.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_dark.png b/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_dark.png Binary files differnew file mode 100644 index 00000000..c1e92342 --- /dev/null +++ b/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_dark.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_light.png b/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_light.png Binary files differnew file mode 100644 index 00000000..3dc5f32a --- /dev/null +++ b/app/src/main/res/drawable-xxxhdpi/ic_action_playback_speed_light.png diff --git a/app/src/main/res/layout-land/download.xml b/app/src/main/res/layout-land/download.xml index 9451a587..1bae4ae2 100644 --- a/app/src/main/res/layout-land/download.xml +++ b/app/src/main/res/layout-land/download.xml @@ -65,6 +65,11 @@ android:src="@android:drawable/star_big_off"/> <ImageButton + android:id="@+id/download_playback_speed" + style="@style/DownloadActionImageButton" + android:src="?attr/playback_speed"/> + + <ImageButton android:id="@+id/download_bookmark" style="@style/DownloadActionImageButton" android:src="?attr/bookmark"/> diff --git a/app/src/main/res/layout-large-land/download.xml b/app/src/main/res/layout-large-land/download.xml index 0b48384f..339a02a9 100644 --- a/app/src/main/res/layout-large-land/download.xml +++ b/app/src/main/res/layout-large-land/download.xml @@ -62,6 +62,11 @@ android:src="@android:drawable/star_big_off"/> <ImageButton + android:id="@+id/download_playback_speed" + style="@style/DownloadActionImageButton" + android:src="?attr/playback_speed"/> + + <ImageButton android:id="@+id/download_bookmark" style="@style/DownloadActionImageButton" android:src="?attr/bookmark"/> diff --git a/app/src/main/res/layout-port/download.xml b/app/src/main/res/layout-port/download.xml index f7c4f6e8..81f4e8dc 100644 --- a/app/src/main/res/layout-port/download.xml +++ b/app/src/main/res/layout-port/download.xml @@ -60,6 +60,11 @@ android:src="@drawable/ic_toggle_star_outline_dark"/> <ImageButton + android:id="@+id/download_playback_speed" + style="@style/DownloadActionImageButton" + android:src="@drawable/ic_action_playback_speed_dark"/> + + <ImageButton android:id="@+id/download_bookmark" style="@style/DownloadActionImageButton" android:src="@drawable/ic_menu_bookmark_dark"/> diff --git a/app/src/main/res/menu/playback_speed_options.xml b/app/src/main/res/menu/playback_speed_options.xml new file mode 100644 index 00000000..e64ecd04 --- /dev/null +++ b/app/src/main/res/menu/playback_speed_options.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/playback_speed_half" + android:title="@string/download.playback_speed_half"/> + + <item + android:id="@+id/playback_speed_normal" + android:title="@string/download.playback_speed_normal"/> + + <item + android:id="@+id/playback_speed_one_half" + android:title="@string/download.playback_speed_one_half"/> + + <item + android:id="@+id/playback_speed_double" + android:title="@string/download.playback_speed_double"/> + + <item + android:id="@+id/playback_speed_tripple" + android:title="@string/download.playback_speed_tripple"/> +</menu>
\ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 2d3794d6..7cd447f0 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -42,6 +42,7 @@ <attr name="radio" format="reference"/> <attr name="star_outline" format="reference"/> <attr name="download" format="reference"/> + <attr name="playback_speed" format="reference"/> <attr name="drawerItemsIcons" format="reference"/> <attr name="drawerHome" format="reference"/> <attr name="drawerLibrary" format="reference"/> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4b3dc1c9..896f3dac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -220,6 +220,11 @@ <string name="download.thumbs_up">Thumbs Up</string> <string name="download.thumbs_down">Thumbs Down</string> <string name="download.batch_mode">Batch Mode</string> + <string name="download.playback_speed_half">0.5x</string> + <string name="download.playback_speed_normal">1.0x</string> + <string name="download.playback_speed_one_half">1.5x</string> + <string name="download.playback_speed_double">2.0x</string> + <string name="download.playback_speed_tripple">3.0x</string> <string name="sync.new_podcasts">New podcasts available</string> <string name="sync.new_playlists">New songs in playlists</string> diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index e86084b0..9e95fe9d 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -43,6 +43,7 @@ <item name="radio">@drawable/ic_menu_radio_dark</item> <item name="star_outline">@drawable/ic_toggle_star_outline_light</item> <item name="download">@drawable/ic_menu_download_dark</item> + <item name="playback_speed">@drawable/ic_action_playback_speed_light</item> <item name="drawerHome">@drawable/main_offline_light</item> <item name="drawerLibrary">@drawable/ic_menu_library_light</item> <item name="drawerPlaylists">@drawable/ic_menu_playlist_light</item> @@ -113,6 +114,7 @@ <item name="radio">@drawable/ic_menu_radio_dark</item> <item name="star_outline">@drawable/ic_toggle_star_outline_dark</item> <item name="download">@drawable/ic_menu_download_dark</item> + <item name="playback_speed">@drawable/ic_action_playback_speed_dark</item> <item name="drawerHome">@drawable/main_offline_dark</item> <item name="drawerLibrary">@drawable/ic_menu_library_dark</item> <item name="drawerPlaylists">@drawable/ic_menu_playlist_dark</item> |