-Added variable speed and pitch to background player.

-Moved playback speed LUT to BasePlayer.
This commit is contained in:
John Zhen M 2017-10-09 19:52:23 -07:00 committed by John Zhen Mo
parent 77979eddde
commit 94f7baf299
4 changed files with 122 additions and 10 deletions

View File

@ -74,6 +74,11 @@ public class BackgroundPlayerActivity extends AppCompatActivity
private ImageButton forwardButton;
private ImageButton shuffleButton;
private TextView playbackSpeedButton;
private PopupMenu playbackSpeedPopupMenu;
private TextView playbackPitchButton;
private PopupMenu playbackPitchPopupMenu;
////////////////////////////////////////////////////////////////////////////
// Activity Lifecycle
////////////////////////////////////////////////////////////////////////////
@ -198,12 +203,57 @@ public class BackgroundPlayerActivity extends AppCompatActivity
playPauseButton = rootView.findViewById(R.id.control_play_pause);
forwardButton = rootView.findViewById(R.id.control_forward);
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);
backwardButton.setOnClickListener(this);
playPauseButton.setOnClickListener(this);
forwardButton.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) {
@ -313,16 +363,26 @@ public class BackgroundPlayerActivity extends AppCompatActivity
public void onClick(View view) {
if (view.getId() == repeatButton.getId()) {
player.onRepeatClicked();
} else if (view.getId() == backwardButton.getId()) {
player.onPlayPrevious();
scrollToSelected();
} else if (view.getId() == playPauseButton.getId()) {
player.onVideoPlayPause();
scrollToSelected();
} else if (view.getId() == forwardButton.getId()) {
player.onPlayNext();
} else if (view.getId() == shuffleButton.getId()) {
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;
break;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
repeatButton.setImageAlpha(repeatAlpha);
} else {
repeatButton.setAlpha(repeatAlpha);
}
int shuffleAlpha = 255;
if (!shuffled) {
shuffleAlpha = 77;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
repeatButton.setImageAlpha(repeatAlpha);
shuffleButton.setImageAlpha(shuffleAlpha);
} else {
repeatButton.setAlpha(repeatAlpha);
shuffleButton.setAlpha(shuffleAlpha);
}
if (parameters != null) {
final float speed = parameters.speed;
final float pitch = parameters.pitch;
playbackSpeedButton.setText(player.formatSpeed(parameters.speed));
playbackPitchButton.setText(player.formatPitch(parameters.pitch));
}
scrollToSelected();

View File

@ -142,6 +142,9 @@ public abstract class BasePlayer implements Player.EventListener,
// 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 PlayQueue playQueue;
@ -862,6 +865,7 @@ public abstract class BasePlayer implements Player.EventListener,
private final StringBuilder stringBuilder = new StringBuilder();
private final Formatter formatter = new Formatter(stringBuilder, Locale.getDefault());
private final NumberFormat speedFormatter = new DecimalFormat("0.##x");
private final NumberFormat pitchFormatter = new DecimalFormat("##.##%");
// todo: merge this into Localization
public String getTimeString(int milliSeconds) {
@ -880,6 +884,10 @@ public abstract class BasePlayer implements Player.EventListener,
return speedFormatter.format(speed);
}
protected String formatPitch(float pitch) {
return pitchFormatter.format(pitch);
}
protected void startProgressLoop() {
if (progressUpdateReactor != null) progressUpdateReactor.dispose();
progressUpdateReactor = getProgressReactor();
@ -990,11 +998,28 @@ public abstract class BasePlayer implements Player.EventListener,
}
public float getPlaybackSpeed() {
return simpleExoPlayer.getPlaybackParameters().speed;
return getPlaybackParameters().speed;
}
public float getPlaybackPitch() {
return getPlaybackParameters().pitch;
}
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() {

View File

@ -103,7 +103,6 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
//////////////////////////////////////////////////////////////////////////*/
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 List<TrackGroupInfo> trackGroupInfos;

View File

@ -122,6 +122,21 @@
android:background="@drawable/player_controls_bg"
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
android:id="@+id/control_repeat"
android:layout_width="25dp"
@ -196,6 +211,21 @@
android:scaleType="fitXY"
android:src="@drawable/ic_palette_white_24dp"
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>