kopia lustrzana https://github.com/TeamNewPipe/NewPipe
-Enabled play queue control in main video player.
-Fixed video players does not resolve to preferred quality on playlists. -Refactored resolution conversion to Localization. -Fixed video player quality menu building exception when stream info is not yet available.pull/680/head
rodzic
87fca5cffe
commit
b597774bb9
|
@ -754,15 +754,6 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||
}
|
||||
}
|
||||
|
||||
private static int resolutionOf(final String resolution) {
|
||||
final String[] candidates = TextUtils.split(resolution, "p");
|
||||
if (candidates.length > 0 && TextUtils.isDigitsOnly(candidates[0])) {
|
||||
return Integer.parseInt(candidates[0]);
|
||||
} else {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
private void openPopupPlayer(final boolean append) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(activity)) {
|
||||
Toast toast = Toast.makeText(activity, R.string.msg_popup_permission, Toast.LENGTH_LONG);
|
||||
|
@ -785,7 +776,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||
if (append) {
|
||||
intent = NavigationHelper.getPlayerIntent(activity, PopupVideoPlayer.class, playQueue, true);
|
||||
} else {
|
||||
intent = NavigationHelper.getPlayerIntent(activity, PopupVideoPlayer.class, playQueue, resolutionOf(candidate.resolution));
|
||||
intent = NavigationHelper.getPlayerIntent(activity, PopupVideoPlayer.class, playQueue, Localization.resolutionOf(candidate.resolution));
|
||||
}
|
||||
activity.startService(intent);
|
||||
}
|
||||
|
@ -853,7 +844,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
|
|||
// ExoPlayer
|
||||
final PlayQueue playQueue = new SinglePlayQueue(currentInfo);
|
||||
final VideoStream candidate = sortedStreamVideosList.get(actionBarHandler.getSelectedVideoStream());
|
||||
mIntent = NavigationHelper.getPlayerIntent(activity, MainVideoPlayer.class, playQueue, resolutionOf(candidate.resolution));
|
||||
mIntent = NavigationHelper.getPlayerIntent(activity, MainVideoPlayer.class, playQueue, Localization.resolutionOf(candidate.resolution));
|
||||
} else {
|
||||
// Internal Player
|
||||
mIntent = new Intent(activity, PlayVideoActivity.class)
|
||||
|
|
|
@ -28,6 +28,9 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.helper.ItemTouchHelper;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
|
@ -35,6 +38,7 @@ import android.view.View;
|
|||
import android.view.WindowManager;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.PopupMenu;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
@ -45,7 +49,10 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
|||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||
import org.schabi.newpipe.playlist.PlayQueueItem;
|
||||
import org.schabi.newpipe.playlist.PlayQueueItemBuilder;
|
||||
import org.schabi.newpipe.playlist.PlayQueueItemHolder;
|
||||
import org.schabi.newpipe.util.AnimationUtils;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
|
@ -159,6 +166,7 @@ public final class MainVideoPlayer extends Activity {
|
|||
|
||||
private void showSystemUi() {
|
||||
if (DEBUG) Log.d(TAG, "showSystemUi() called");
|
||||
if (playerImpl != null && playerImpl.queueVisible) return;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
|
@ -212,10 +220,18 @@ public final class MainVideoPlayer extends Activity {
|
|||
private TextView volumeTextView;
|
||||
private TextView brightnessTextView;
|
||||
private ImageButton repeatButton;
|
||||
private ImageButton queueButton;
|
||||
|
||||
private ImageButton screenRotationButton;
|
||||
private ImageButton playPauseButton;
|
||||
|
||||
private RelativeLayout queueLayout;
|
||||
private ImageButton itemsListCloseButton;
|
||||
private RecyclerView itemsList;
|
||||
private ItemTouchHelper itemTouchHelper;
|
||||
|
||||
private boolean queueVisible;
|
||||
|
||||
VideoPlayerImpl() {
|
||||
super("VideoPlayerImpl" + MainVideoPlayer.TAG, MainVideoPlayer.this);
|
||||
}
|
||||
|
@ -228,6 +244,7 @@ public final class MainVideoPlayer extends Activity {
|
|||
this.volumeTextView = rootView.findViewById(R.id.volumeTextView);
|
||||
this.brightnessTextView = rootView.findViewById(R.id.brightnessTextView);
|
||||
this.repeatButton = rootView.findViewById(R.id.repeatButton);
|
||||
this.queueButton = rootView.findViewById(R.id.queueButton);
|
||||
|
||||
this.screenRotationButton = rootView.findViewById(R.id.screenRotationButton);
|
||||
this.playPauseButton = rootView.findViewById(R.id.playPauseButton);
|
||||
|
@ -244,11 +261,22 @@ public final class MainVideoPlayer extends Activity {
|
|||
gestureDetector.setIsLongpressEnabled(false);
|
||||
getRootView().setOnTouchListener(listener);
|
||||
|
||||
queueButton.setOnClickListener(this);
|
||||
repeatButton.setOnClickListener(this);
|
||||
playPauseButton.setOnClickListener(this);
|
||||
screenRotationButton.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredResolution() {
|
||||
if (sharedPreferences == null || context == null) return Integer.MAX_VALUE;
|
||||
|
||||
return Localization.resolutionOf(sharedPreferences.getString(
|
||||
context.getString(R.string.default_resolution_key),
|
||||
context.getString(R.string.default_resolution_value)
|
||||
));
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// ExoPlayer Video Listener
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
@ -310,9 +338,19 @@ public final class MainVideoPlayer extends Activity {
|
|||
@Override
|
||||
public void onClick(View v) {
|
||||
super.onClick(v);
|
||||
if (v.getId() == repeatButton.getId()) onRepeatClicked();
|
||||
else if (v.getId() == playPauseButton.getId()) onVideoPlayPause();
|
||||
else if (v.getId() == screenRotationButton.getId()) onScreenRotationClicked();
|
||||
if (v.getId() == repeatButton.getId()) {
|
||||
onRepeatClicked();
|
||||
|
||||
} else if (v.getId() == playPauseButton.getId()) {
|
||||
onVideoPlayPause();
|
||||
|
||||
} else if (v.getId() == screenRotationButton.getId()) {
|
||||
onScreenRotationClicked();
|
||||
|
||||
} else if (v.getId() == queueButton.getId()) {
|
||||
onQueueClicked();
|
||||
return;
|
||||
}
|
||||
|
||||
if (getCurrentState() != STATE_COMPLETED) {
|
||||
getControlsVisibilityHandler().removeCallbacksAndMessages(null);
|
||||
|
@ -327,6 +365,19 @@ public final class MainVideoPlayer extends Activity {
|
|||
}
|
||||
}
|
||||
|
||||
private void onQueueClicked() {
|
||||
queueVisible = true;
|
||||
buildQueue();
|
||||
hideSystemUi();
|
||||
getControlsRoot().setVisibility(View.INVISIBLE);
|
||||
queueLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void onQueueClosed() {
|
||||
queueLayout.setVisibility(View.GONE);
|
||||
queueVisible = false;
|
||||
}
|
||||
|
||||
private void onScreenRotationClicked() {
|
||||
if (DEBUG) Log.d(TAG, "onScreenRotationClicked() called");
|
||||
toggleOrientation();
|
||||
|
@ -434,6 +485,20 @@ public final class MainVideoPlayer extends Activity {
|
|||
// Utils
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
@Override
|
||||
public void showControlsThenHide() {
|
||||
if (queueVisible) return;
|
||||
|
||||
super.showControlsThenHide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showControls(long duration) {
|
||||
if (queueVisible) return;
|
||||
|
||||
super.showControls(duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideControls(final long duration, long delay) {
|
||||
if (DEBUG) Log.d(TAG, "hideControls() called with: delay = [" + delay + "]");
|
||||
|
@ -451,6 +516,85 @@ public final class MainVideoPlayer extends Activity {
|
|||
}, delay);
|
||||
}
|
||||
|
||||
private void buildQueue() {
|
||||
queueLayout = findViewById(R.id.play_queue_control);
|
||||
|
||||
itemsListCloseButton = findViewById(R.id.play_queue_close_area);
|
||||
|
||||
itemsList = findViewById(R.id.play_queue);
|
||||
itemsList.setAdapter(playQueueAdapter);
|
||||
itemsList.setClickable(true);
|
||||
itemsList.setLongClickable(true);
|
||||
|
||||
itemTouchHelper = new ItemTouchHelper(getItemTouchCallback());
|
||||
itemTouchHelper.attachToRecyclerView(itemsList);
|
||||
|
||||
playQueueAdapter.setSelectedListener(getOnSelectedListener());
|
||||
|
||||
itemsListCloseButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
onQueueClosed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ItemTouchHelper.SimpleCallback getItemTouchCallback() {
|
||||
return new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0) {
|
||||
@Override
|
||||
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
|
||||
if (source.getItemViewType() != target.getItemViewType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int sourceIndex = source.getLayoutPosition();
|
||||
final int targetIndex = target.getLayoutPosition();
|
||||
playQueue.move(sourceIndex, targetIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLongPressDragEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemViewSwipeEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {}
|
||||
};
|
||||
}
|
||||
|
||||
private PlayQueueItemBuilder.OnSelectedListener getOnSelectedListener() {
|
||||
return new PlayQueueItemBuilder.OnSelectedListener() {
|
||||
@Override
|
||||
public void selected(PlayQueueItem item, View view) {
|
||||
final int index = playQueue.indexOf(item);
|
||||
if (index == -1) return;
|
||||
|
||||
if (playQueue.getIndex() == index) {
|
||||
onRestart();
|
||||
} else {
|
||||
playQueue.setIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void held(PlayQueueItem item, View view) {
|
||||
final int index = playQueue.indexOf(item);
|
||||
if (index != -1) playQueue.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartDrag(PlayQueueItemHolder viewHolder) {
|
||||
if (itemTouchHelper != null) itemTouchHelper.startDrag(viewHolder);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -53,6 +53,7 @@ import android.widget.Toast;
|
|||
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
|
||||
import org.schabi.newpipe.BuildConfig;
|
||||
import org.schabi.newpipe.MainActivity;
|
||||
|
@ -73,6 +74,7 @@ import org.schabi.newpipe.report.ErrorActivity;
|
|||
import org.schabi.newpipe.report.UserAction;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
import org.schabi.newpipe.util.ExtractorHelper;
|
||||
import org.schabi.newpipe.util.Localization;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
|
||||
|
@ -405,6 +407,15 @@ public final class PopupVideoPlayer extends Service {
|
|||
resizingIndicator = rootView.findViewById(R.id.resizing_indicator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPreferredResolution() {
|
||||
if (sharedPreferences == null || context == null) return Integer.MAX_VALUE;
|
||||
return Localization.resolutionOf(sharedPreferences.getString(
|
||||
context.getString(R.string.default_popup_resolution_key),
|
||||
context.getString(R.string.default_popup_resolution_value)
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
|
@ -451,6 +462,7 @@ public final class PopupVideoPlayer extends Service {
|
|||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
context.startActivity(intent);
|
||||
playerImpl.stopActivityBinding();
|
||||
destroyPlayer();
|
||||
stopSelf();
|
||||
}
|
||||
|
|
|
@ -222,13 +222,15 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
|
|||
super.handleIntent(intent);
|
||||
if (intent == null) return;
|
||||
|
||||
final int resolutionTarget = intent.getIntExtra(MAX_RESOLUTION, Integer.MAX_VALUE);
|
||||
final int resolutionTarget = intent.getIntExtra(MAX_RESOLUTION, getPreferredResolution());
|
||||
trackSelector.setParameters(
|
||||
// Assume video is horizontal
|
||||
new DefaultTrackSelector.Parameters().withMaxVideoSize(Integer.MAX_VALUE, resolutionTarget)
|
||||
);
|
||||
}
|
||||
|
||||
public abstract int getPreferredResolution();
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
// UI Builders
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
@ -246,7 +248,8 @@ public abstract class VideoPlayer extends BasePlayer implements SimpleExoPlayer.
|
|||
}
|
||||
|
||||
private void buildQualityMenu() {
|
||||
if (qualityPopupMenu == null || videoTrackGroups == null || selectedVideoTrackGroup == null || videoTrackGroups.length != availableStreams.size()) return;
|
||||
if (qualityPopupMenu == null || videoTrackGroups == null || selectedVideoTrackGroup == null
|
||||
|| availableStreams == null || videoTrackGroups.length != availableStreams.size()) return;
|
||||
|
||||
qualityPopupMenu.getMenu().removeGroup(qualityPopupMenuGroupId);
|
||||
trackGroupInfos = new ArrayList<>();
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.content.res.Resources;
|
|||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.PluralsRes;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
|
||||
|
@ -151,4 +152,13 @@ public class Localization {
|
|||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public static int resolutionOf(final String resolution) {
|
||||
final String[] candidates = TextUtils.split(resolution, "p");
|
||||
if (candidates.length > 0 && TextUtils.isDigitsOnly(candidates[0])) {
|
||||
return Integer.parseInt(candidates[0]);
|
||||
} else {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@android:color/black"
|
||||
android:gravity="center">
|
||||
|
||||
|
@ -41,6 +42,33 @@
|
|||
tools:ignore="ContentDescription"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/play_queue_control"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#64000000"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/play_queue_close_area"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:src="@drawable/ic_close_white_24dp"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/play_queue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/play_queue_close_area"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="LinearLayoutManager"
|
||||
tools:listitem="@layout/play_queue_item"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/playbackControlRoot"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -139,6 +167,7 @@
|
|||
android:layout_toLeftOf="@+id/repeatButton"
|
||||
android:background="#00ffffff"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="8dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_screen_rotation_white"
|
||||
|
@ -150,14 +179,30 @@
|
|||
android:layout_height="35dp"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:layout_toLeftOf="@+id/fullScreenButton"
|
||||
android:layout_toLeftOf="@+id/queueButton"
|
||||
android:background="#00ffffff"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/exo_controls_repeat_off"
|
||||
tools:ignore="ContentDescription,RtlHardcoded"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/queueButton"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:layout_toLeftOf="@+id/fullScreenButton"
|
||||
android:background="#00ffffff"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/list"
|
||||
tools:ignore="ContentDescription,RtlHardcoded"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/fullScreenButton"
|
||||
android:layout_width="35dp"
|
||||
|
@ -166,6 +211,7 @@
|
|||
android:layout_marginLeft="4dp"
|
||||
android:background="#00ffffff"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_fullscreen_exit_white"
|
||||
tools:ignore="ContentDescription,RtlHardcoded"/>
|
||||
|
|
Ładowanie…
Reference in New Issue