From 880676d67028bc23ad8d8df85be4532e807588e1 Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Wed, 7 Feb 2018 13:11:19 -0800 Subject: [PATCH] -Modified popup video player to show extra options only when screen is large enough. -Modified available resize options for different player modes. -Fixed caption menu not working on popup player. -Extracted hardcoded strings. -Added button effects to both main and popup players. --- .../newpipe/player/MainVideoPlayer.java | 29 ++++++++ .../newpipe/player/PopupVideoPlayer.java | 34 ++++++++- .../schabi/newpipe/player/VideoPlayer.java | 51 +++++++------ .../newpipe/player/helper/PlayerHelper.java | 16 +---- .../main/res/layout/activity_main_player.xml | 7 +- app/src/main/res/layout/player_popup.xml | 72 +++++++++++-------- app/src/main/res/values/strings.xml | 8 +++ 7 files changed, 142 insertions(+), 75 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java index a23290486..49ce06a9b 100644 --- a/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/MainVideoPlayer.java @@ -35,7 +35,9 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; +import android.util.DisplayMetrics; import android.util.Log; +import android.util.TypedValue; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; @@ -48,6 +50,7 @@ import android.widget.TextView; import android.widget.Toast; import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import org.schabi.newpipe.R; import org.schabi.newpipe.extractor.stream.StreamInfo; @@ -334,6 +337,8 @@ public final class MainVideoPlayer extends Activity { channelTextView.setSelected(true); getRootView().setKeepScreenOn(true); + getSubtitleView().setFixedTextSize(TypedValue.COMPLEX_UNIT_PX, + getCaptionSizePx(context)); } @Override @@ -547,6 +552,24 @@ public final class MainVideoPlayer extends Activity { if (isPlaying()) hideControls(300, 0); } + @Override + protected void onResizeClicked() { + if (getAspectRatioFrameLayout() != null && context != null) { + final int currentResizeMode = getAspectRatioFrameLayout().getResizeMode(); + final int newResizeMode; + if (currentResizeMode == AspectRatioFrameLayout.RESIZE_MODE_FIT) { + newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL; + } else if (currentResizeMode == AspectRatioFrameLayout.RESIZE_MODE_FILL) { + newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM; + } else { + newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT; + } + + getAspectRatioFrameLayout().setResizeMode(newResizeMode); + getResizeView().setText(PlayerHelper.resizeTypeOf(context, newResizeMode)); + } + } + @Override protected int getDefaultResolutionIndex(final List sortedVideos) { return ListHelper.getDefaultResolutionIndex(context, sortedVideos); @@ -745,6 +768,12 @@ public final class MainVideoPlayer extends Activity { }; } + private float getCaptionSizePx(@NonNull Context context) { + final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + final int minimumLength = Math.min(metrics.heightPixels, metrics.widthPixels); + // todo: expose size control to users + return (float) minimumLength / 20f; + } /////////////////////////////////////////////////////////////////////////// // Getters /////////////////////////////////////////////////////////////////////////// diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index e8ccba7d0..bf6d6f445 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -52,6 +52,7 @@ import android.widget.TextView; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import org.schabi.newpipe.BuildConfig; import org.schabi.newpipe.R; @@ -89,6 +90,8 @@ public final class PopupVideoPlayer extends Service { private static final String POPUP_SAVED_X = "popup_saved_x"; private static final String POPUP_SAVED_Y = "popup_saved_y"; + private static final int MINIMUM_SHOW_EXTRA_WIDTH_DP = 300; + private WindowManager windowManager; private WindowManager.LayoutParams windowLayoutParams; private GestureDetector gestureDetector; @@ -359,10 +362,12 @@ public final class PopupVideoPlayer extends Service { /////////////////////////////////////////////////////////////////////////// - protected class VideoPlayerImpl extends VideoPlayer { + protected class VideoPlayerImpl extends VideoPlayer implements View.OnLayoutChangeListener { private TextView resizingIndicator; private ImageButton fullScreenButton; + private View extraOptionsView; + @Override public void handleIntent(Intent intent) { super.handleIntent(intent); @@ -381,6 +386,17 @@ public final class PopupVideoPlayer extends Service { resizingIndicator = rootView.findViewById(R.id.resizing_indicator); fullScreenButton = rootView.findViewById(R.id.fullScreenButton); fullScreenButton.setOnClickListener(v -> onFullScreenButtonClicked()); + + extraOptionsView = rootView.findViewById(R.id.extraOptionsView); + rootView.addOnLayoutChangeListener(this); + } + + @Override + public void onLayoutChange(final View view, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + float widthDp = Math.abs(right - left) / getResources().getDisplayMetrics().density; + final int visibility = widthDp > MINIMUM_SHOW_EXTRA_WIDTH_DP ? View.VISIBLE : View.GONE; + extraOptionsView.setVisibility(visibility); } @Override @@ -439,6 +455,22 @@ public final class PopupVideoPlayer extends Service { if (isPlaying()) hideControls(500, 0); } + @Override + protected void onResizeClicked() { + if (getAspectRatioFrameLayout() != null && context != null) { + final int currentResizeMode = getAspectRatioFrameLayout().getResizeMode(); + final int newResizeMode; + if (currentResizeMode == AspectRatioFrameLayout.RESIZE_MODE_FILL) { + newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT; + } else { + newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL; + } + + getAspectRatioFrameLayout().setResizeMode(newResizeMode); + getResizeView().setText(PlayerHelper.resizeTypeOf(context, newResizeMode)); + } + } + @Override public void onStopTrackingTouch(SeekBar seekBar) { super.onStopTrackingTouch(seekBar); diff --git a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java index 48d10a4ad..344175030 100644 --- a/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/VideoPlayer.java @@ -36,7 +36,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.util.Log; -import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; import android.view.SurfaceView; @@ -75,7 +74,6 @@ import java.util.List; import static com.google.android.exoplayer2.C.SELECTION_FLAG_AUTOSELECT; import static com.google.android.exoplayer2.C.TIME_UNSET; -import static com.google.android.exoplayer2.C.TRACK_TYPE_TEXT; import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed; import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString; import static org.schabi.newpipe.util.AnimationUtils.animateView; @@ -204,9 +202,6 @@ public abstract class VideoPlayer extends BasePlayer ((ProgressBar) this.loadingPanel.findViewById(R.id.progressBarLoadingPanel)) .getIndeterminateDrawable().setColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY); - - subtitleView.setFixedTextSize(TypedValue.COMPLEX_UNIT_PX, - PlayerHelper.getCaptionSizePx(context)); } @Override @@ -281,8 +276,10 @@ public abstract class VideoPlayer extends BasePlayer captionPopupMenu.getMenu().removeGroup(captionPopupMenuGroupId); if (availableCaptions == null || trackSelector == null) return; + + // Add option for turning off caption MenuItem captionOffItem = captionPopupMenu.getMenu().add(captionPopupMenuGroupId, - 0, Menu.NONE, "Caption Off"); + 0, Menu.NONE, R.string.caption_none); captionOffItem.setOnMenuItemClickListener(menuItem -> { final int textRendererIndex = getRendererIndex(C.TRACK_TYPE_TEXT); if (trackSelector != null && textRendererIndex != -1) { @@ -291,6 +288,7 @@ public abstract class VideoPlayer extends BasePlayer return true; }); + // Add all available captions for (int i = 0; i < availableCaptions.size(); i++) { final Subtitles subtitles = availableCaptions.get(i); final String captionLanguage = PlayerHelper.captionLanguageOf(subtitles); @@ -306,7 +304,6 @@ public abstract class VideoPlayer extends BasePlayer return true; }); } - //captionPopupMenu.setOnMenuItemClickListener(this); captionPopupMenu.setOnDismissListener(this); } /*////////////////////////////////////////////////////////////////////////// @@ -334,14 +331,14 @@ public abstract class VideoPlayer extends BasePlayer selectedStreamIndex = getOverrideResolutionIndex(videos, getPlaybackQuality()); } + availableCaptions = info.getSubtitles(); + buildQualityMenu(); buildPlaybackSpeedMenu(); buildCaptionMenu(); qualityTextView.setVisibility(View.VISIBLE); playbackSpeedTextView.setVisibility(View.VISIBLE); - - availableCaptions = info.getSubtitles(); - if (!availableCaptions.isEmpty()) captionTextView.setVisibility(View.VISIBLE); + captionTextView.setVisibility(availableCaptions.isEmpty() ? View.GONE : View.VISIBLE); } } @@ -472,11 +469,13 @@ public abstract class VideoPlayer extends BasePlayer @Override public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { super.onTracksChanged(trackGroups, trackSelections); - if (trackSelector == null || captionTextView == null) return; + if (captionTextView == null) return; - if (trackSelector.getRendererDisabled(getRendererIndex(C.TRACK_TYPE_TEXT)) || + if (trackSelector == null) { + captionTextView.setVisibility(View.GONE); + } else if (trackSelector.getRendererDisabled(getRendererIndex(C.TRACK_TYPE_TEXT)) || trackSelector.getParameters().preferredTextLanguage == null) { - captionTextView.setText("No Caption"); + captionTextView.setText(R.string.caption_none); } else { final String preferredLanguage = trackSelector.getParameters().preferredTextLanguage; captionTextView.setText(preferredLanguage); @@ -646,20 +645,7 @@ public abstract class VideoPlayer extends BasePlayer showControls(300); } - protected void onResizeClicked() { - if (aspectRatioFrameLayout != null && context != null) { - final int currentResizeMode = aspectRatioFrameLayout.getResizeMode(); - final int newResizeMode; - if (currentResizeMode == AspectRatioFrameLayout.RESIZE_MODE_ZOOM) { - newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT; - } else { - newResizeMode = currentResizeMode + 1; - } - - aspectRatioFrameLayout.setResizeMode(newResizeMode); - resizeView.setText(PlayerHelper.resizeTypeOf(context, newResizeMode)); - } - } + protected abstract void onResizeClicked(); /*////////////////////////////////////////////////////////////////////////// // SeekBar Listener //////////////////////////////////////////////////////////////////////////*/ @@ -899,4 +885,15 @@ public abstract class VideoPlayer extends BasePlayer return currentDisplaySeek; } + public SubtitleView getSubtitleView() { + return subtitleView; + } + + public TextView getResizeView() { + return resizeView; + } + + public TextView getCaptionTextView() { + return captionTextView; + } } diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java index 75ea3bdc6..476838f13 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerHelper.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.annotation.NonNull; -import android.util.DisplayMetrics; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.util.MimeTypes; @@ -75,22 +74,13 @@ public class PlayerHelper { public static String resizeTypeOf(@NonNull final Context context, @AspectRatioFrameLayout.ResizeMode final int resizeMode) { switch (resizeMode) { - case RESIZE_MODE_FIT: return "FIT"; - case RESIZE_MODE_FILL: return "FILL"; - case RESIZE_MODE_FIXED_HEIGHT: return "HEIGHT"; - case RESIZE_MODE_FIXED_WIDTH: return "WIDTH"; - case RESIZE_MODE_ZOOM: return "ZOOM"; + case RESIZE_MODE_FIT: return context.getResources().getString(R.string.resize_fit); + case RESIZE_MODE_FILL: return context.getResources().getString(R.string.resize_fill); + case RESIZE_MODE_ZOOM: return context.getResources().getString(R.string.resize_zoom); default: throw new IllegalArgumentException("Unrecognized resize mode: " + resizeMode); } } - public static float getCaptionSizePx(@NonNull final Context context) { - final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - final int minimumLength = Math.min(metrics.heightPixels, metrics.widthPixels); - // todo: expose size control to users - return (float) minimumLength / 20f; - } - public static boolean isResumeAfterAudioFocusGain(@NonNull final Context context) { return isResumeAfterAudioFocusGain(context, false); } diff --git a/app/src/main/res/layout/activity_main_player.xml b/app/src/main/res/layout/activity_main_player.xml index 577a6a8f5..80c67974f 100644 --- a/app/src/main/res/layout/activity_main_player.xml +++ b/app/src/main/res/layout/activity_main_player.xml @@ -286,12 +286,13 @@ @@ -83,52 +84,61 @@ android:layout_height="30dp" android:layout_toRightOf="@+id/qualityTextView" android:gravity="center" - android:padding="6dp" + android:padding="5dp" android:textColor="@android:color/white" android:textStyle="bold" + android:background="?attr/selectableItemBackground" tools:ignore="RelativeOverlap,RtlHardcoded,RtlSymmetry" tools:text="1.75x"/> + + + + + + + - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 767bffa10..b1bd5c3ec 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -395,4 +395,12 @@ Added to playlist Playlist thumbnail changed Failed to delete playlist + + + No Caption + + FIT + FILL + ZOOM +