-Added variable speed and pitch to background player.
-Moved playback speed LUT to BasePlayer.
This commit is contained in:
parent
77979eddde
commit
94f7baf299
|
@ -74,6 +74,11 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
||||||
private ImageButton forwardButton;
|
private ImageButton forwardButton;
|
||||||
private ImageButton shuffleButton;
|
private ImageButton shuffleButton;
|
||||||
|
|
||||||
|
private TextView playbackSpeedButton;
|
||||||
|
private PopupMenu playbackSpeedPopupMenu;
|
||||||
|
private TextView playbackPitchButton;
|
||||||
|
private PopupMenu playbackPitchPopupMenu;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Activity Lifecycle
|
// Activity Lifecycle
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -198,12 +203,57 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
||||||
playPauseButton = rootView.findViewById(R.id.control_play_pause);
|
playPauseButton = rootView.findViewById(R.id.control_play_pause);
|
||||||
forwardButton = rootView.findViewById(R.id.control_forward);
|
forwardButton = rootView.findViewById(R.id.control_forward);
|
||||||
shuffleButton = rootView.findViewById(R.id.control_shuffle);
|
shuffleButton = rootView.findViewById(R.id.control_shuffle);
|
||||||
|
playbackSpeedButton = rootView.findViewById(R.id.control_playback_speed);
|
||||||
|
playbackPitchButton = rootView.findViewById(R.id.control_playback_pitch);
|
||||||
|
|
||||||
repeatButton.setOnClickListener(this);
|
repeatButton.setOnClickListener(this);
|
||||||
backwardButton.setOnClickListener(this);
|
backwardButton.setOnClickListener(this);
|
||||||
playPauseButton.setOnClickListener(this);
|
playPauseButton.setOnClickListener(this);
|
||||||
forwardButton.setOnClickListener(this);
|
forwardButton.setOnClickListener(this);
|
||||||
shuffleButton.setOnClickListener(this);
|
shuffleButton.setOnClickListener(this);
|
||||||
|
playbackSpeedButton.setOnClickListener(this);
|
||||||
|
playbackPitchButton.setOnClickListener(this);
|
||||||
|
|
||||||
|
playbackSpeedPopupMenu = new PopupMenu(this, playbackSpeedButton);
|
||||||
|
playbackPitchPopupMenu = new PopupMenu(this, playbackPitchButton);
|
||||||
|
buildPlaybackSpeedMenu();
|
||||||
|
buildPlaybackPitchMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildPlaybackSpeedMenu() {
|
||||||
|
if (playbackSpeedPopupMenu == null) return;
|
||||||
|
|
||||||
|
playbackSpeedPopupMenu.getMenu().removeGroup(PLAYBACK_SPEED_POPUP_MENU_GROUP_ID);
|
||||||
|
for (int i = 0; i < BasePlayer.PLAYBACK_SPEEDS.length; i++) {
|
||||||
|
final float playbackSpeed = BasePlayer.PLAYBACK_SPEEDS[i];
|
||||||
|
final String formattedSpeed = player.formatSpeed(playbackSpeed);
|
||||||
|
final MenuItem item = playbackSpeedPopupMenu.getMenu().add(PLAYBACK_SPEED_POPUP_MENU_GROUP_ID, i, Menu.NONE, formattedSpeed);
|
||||||
|
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem menuItem) {
|
||||||
|
player.setPlaybackSpeed(playbackSpeed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildPlaybackPitchMenu() {
|
||||||
|
if (playbackPitchPopupMenu == null) return;
|
||||||
|
|
||||||
|
playbackPitchPopupMenu.getMenu().removeGroup(PLAYBACK_SPEED_POPUP_MENU_GROUP_ID);
|
||||||
|
for (int i = 0; i < BasePlayer.PLAYBACK_PITCHES.length; i++) {
|
||||||
|
final float playbackPitch = BasePlayer.PLAYBACK_PITCHES[i];
|
||||||
|
final String formattedPitch = player.formatPitch(playbackPitch);
|
||||||
|
final MenuItem item = playbackPitchPopupMenu.getMenu().add(PLAYBACK_SPEED_POPUP_MENU_GROUP_ID, i, Menu.NONE, formattedPitch);
|
||||||
|
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem menuItem) {
|
||||||
|
player.setPlaybackPitch(playbackPitch);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildItemPopupMenu(final PlayQueueItem item, final View view) {
|
private void buildItemPopupMenu(final PlayQueueItem item, final View view) {
|
||||||
|
@ -313,16 +363,26 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (view.getId() == repeatButton.getId()) {
|
if (view.getId() == repeatButton.getId()) {
|
||||||
player.onRepeatClicked();
|
player.onRepeatClicked();
|
||||||
|
|
||||||
} else if (view.getId() == backwardButton.getId()) {
|
} else if (view.getId() == backwardButton.getId()) {
|
||||||
player.onPlayPrevious();
|
player.onPlayPrevious();
|
||||||
scrollToSelected();
|
scrollToSelected();
|
||||||
|
|
||||||
} else if (view.getId() == playPauseButton.getId()) {
|
} else if (view.getId() == playPauseButton.getId()) {
|
||||||
player.onVideoPlayPause();
|
player.onVideoPlayPause();
|
||||||
scrollToSelected();
|
scrollToSelected();
|
||||||
|
|
||||||
} else if (view.getId() == forwardButton.getId()) {
|
} else if (view.getId() == forwardButton.getId()) {
|
||||||
player.onPlayNext();
|
player.onPlayNext();
|
||||||
|
|
||||||
} else if (view.getId() == shuffleButton.getId()) {
|
} else if (view.getId() == shuffleButton.getId()) {
|
||||||
player.onShuffleClicked();
|
player.onShuffleClicked();
|
||||||
|
|
||||||
|
} else if (view.getId() == playbackSpeedButton.getId()) {
|
||||||
|
playbackSpeedPopupMenu.show();
|
||||||
|
|
||||||
|
} else if (view.getId() == playbackPitchButton.getId()) {
|
||||||
|
playbackPitchPopupMenu.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,25 +439,23 @@ public class BackgroundPlayerActivity extends AppCompatActivity
|
||||||
repeatAlpha = 255;
|
repeatAlpha = 255;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
|
||||||
repeatButton.setImageAlpha(repeatAlpha);
|
|
||||||
} else {
|
|
||||||
repeatButton.setAlpha(repeatAlpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
int shuffleAlpha = 255;
|
int shuffleAlpha = 255;
|
||||||
if (!shuffled) {
|
if (!shuffled) {
|
||||||
shuffleAlpha = 77;
|
shuffleAlpha = 77;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
repeatButton.setImageAlpha(repeatAlpha);
|
||||||
shuffleButton.setImageAlpha(shuffleAlpha);
|
shuffleButton.setImageAlpha(shuffleAlpha);
|
||||||
} else {
|
} else {
|
||||||
|
repeatButton.setAlpha(repeatAlpha);
|
||||||
shuffleButton.setAlpha(shuffleAlpha);
|
shuffleButton.setAlpha(shuffleAlpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters != null) {
|
if (parameters != null) {
|
||||||
final float speed = parameters.speed;
|
playbackSpeedButton.setText(player.formatSpeed(parameters.speed));
|
||||||
final float pitch = parameters.pitch;
|
playbackPitchButton.setText(player.formatPitch(parameters.pitch));
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollToSelected();
|
scrollToSelected();
|
||||||
|
|
|
@ -142,6 +142,9 @@ public abstract class BasePlayer implements Player.EventListener,
|
||||||
// Playback
|
// Playback
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
protected static final float[] PLAYBACK_SPEEDS = {0.5f, 0.75f, 1f, 1.25f, 1.5f, 1.75f, 2f};
|
||||||
|
protected static final float[] PLAYBACK_PITCHES = {0.8f, 0.9f, 0.95f, 1f, 1.05f, 1.1f, 1.2f};
|
||||||
|
|
||||||
protected MediaSourceManager playbackManager;
|
protected MediaSourceManager playbackManager;
|
||||||
protected PlayQueue playQueue;
|
protected PlayQueue playQueue;
|
||||||
|
|
||||||
|
@ -862,6 +865,7 @@ public abstract class BasePlayer implements Player.EventListener,
|
||||||
private final StringBuilder stringBuilder = new StringBuilder();
|
private final StringBuilder stringBuilder = new StringBuilder();
|
||||||
private final Formatter formatter = new Formatter(stringBuilder, Locale.getDefault());
|
private final Formatter formatter = new Formatter(stringBuilder, Locale.getDefault());
|
||||||
private final NumberFormat speedFormatter = new DecimalFormat("0.##x");
|
private final NumberFormat speedFormatter = new DecimalFormat("0.##x");
|
||||||
|
private final NumberFormat pitchFormatter = new DecimalFormat("##.##%");
|
||||||
|
|
||||||
// todo: merge this into Localization
|
// todo: merge this into Localization
|
||||||
public String getTimeString(int milliSeconds) {
|
public String getTimeString(int milliSeconds) {
|
||||||
|
@ -880,6 +884,10 @@ public abstract class BasePlayer implements Player.EventListener,
|
||||||
return speedFormatter.format(speed);
|
return speedFormatter.format(speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String formatPitch(float pitch) {
|
||||||
|
return pitchFormatter.format(pitch);
|
||||||
|
}
|
||||||
|
|
||||||
protected void startProgressLoop() {
|
protected void startProgressLoop() {
|
||||||
if (progressUpdateReactor != null) progressUpdateReactor.dispose();
|
if (progressUpdateReactor != null) progressUpdateReactor.dispose();
|
||||||
progressUpdateReactor = getProgressReactor();
|
progressUpdateReactor = getProgressReactor();
|
||||||
|
@ -990,11 +998,28 @@ public abstract class BasePlayer implements Player.EventListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getPlaybackSpeed() {
|
public float getPlaybackSpeed() {
|
||||||
return simpleExoPlayer.getPlaybackParameters().speed;
|
return getPlaybackParameters().speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPlaybackPitch() {
|
||||||
|
return getPlaybackParameters().pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlaybackSpeed(float speed) {
|
public void setPlaybackSpeed(float speed) {
|
||||||
simpleExoPlayer.setPlaybackParameters(new PlaybackParameters(speed, 1f));
|
setPlaybackParameters(speed, getPlaybackPitch());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaybackPitch(float pitch) {
|
||||||
|
setPlaybackParameters(getPlaybackSpeed(), pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlaybackParameters getPlaybackParameters() {
|
||||||
|
final PlaybackParameters parameters = simpleExoPlayer.getPlaybackParameters();
|
||||||
|
return parameters == null ? new PlaybackParameters(1f, 1f) : parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaybackParameters(float speed, float pitch) {
|
||||||
|
simpleExoPlayer.setPlaybackParameters(new PlaybackParameters(speed, pitch));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentQueueIndex() {
|
public int getCurrentQueueIndex() {
|
||||||
|
|
|
@ -103,7 +103,6 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
public static final int DEFAULT_CONTROLS_HIDE_TIME = 2000; // 2 Seconds
|
public static final int DEFAULT_CONTROLS_HIDE_TIME = 2000; // 2 Seconds
|
||||||
private static final float[] PLAYBACK_SPEEDS = {0.5f, 0.75f, 1f, 1.25f, 1.5f, 1.75f, 2f};
|
|
||||||
|
|
||||||
private static final TrackSelection.Factory FIXED_FACTORY = new FixedTrackSelection.Factory();
|
private static final TrackSelection.Factory FIXED_FACTORY = new FixedTrackSelection.Factory();
|
||||||
private List<TrackGroupInfo> trackGroupInfos;
|
private List<TrackGroupInfo> trackGroupInfos;
|
||||||
|
|
|
@ -122,6 +122,21 @@
|
||||||
android:background="@drawable/player_controls_bg"
|
android:background="@drawable/player_controls_bg"
|
||||||
tools:ignore="RtlHardcoded">
|
tools:ignore="RtlHardcoded">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/control_playback_speed"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_marginLeft="2dp"
|
||||||
|
android:layout_marginRight="2dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toLeftOf="@+id/control_repeat"
|
||||||
|
android:gravity="center"
|
||||||
|
android:minWidth="50dp"
|
||||||
|
android:text="1x"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:ignore="HardcodedText,RtlHardcoded"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/control_repeat"
|
android:id="@+id/control_repeat"
|
||||||
android:layout_width="25dp"
|
android:layout_width="25dp"
|
||||||
|
@ -196,6 +211,21 @@
|
||||||
android:scaleType="fitXY"
|
android:scaleType="fitXY"
|
||||||
android:src="@drawable/ic_palette_white_24dp"
|
android:src="@drawable/ic_palette_white_24dp"
|
||||||
tools:ignore="ContentDescription"/>
|
tools:ignore="ContentDescription"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/control_playback_pitch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_marginLeft="2dp"
|
||||||
|
android:layout_marginRight="2dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toRightOf="@+id/control_shuffle"
|
||||||
|
android:gravity="center"
|
||||||
|
android:minWidth="50dp"
|
||||||
|
android:text="100%"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textStyle="bold"
|
||||||
|
tools:ignore="HardcodedText,RtlHardcoded"/>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
Loading…
Reference in New Issue