Merge pull request #4347 from avently/player-rebind

Player rebind
pull/4365/head
Tobias Groza 2020-10-01 15:03:43 +02:00 zatwierdzone przez GitHub
commit 4e7632949d
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 98 dodań i 23 usunięć

Wyświetl plik

@ -20,7 +20,10 @@
package org.schabi.newpipe; package org.schabi.newpipe;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Build; import android.os.Build;
@ -101,6 +104,8 @@ public class MainActivity extends AppCompatActivity {
private boolean servicesShown = false; private boolean servicesShown = false;
private ImageView serviceArrow; private ImageView serviceArrow;
private BroadcastReceiver broadcastReceiver;
private static final int ITEM_ID_SUBSCRIPTIONS = -1; private static final int ITEM_ID_SUBSCRIPTIONS = -1;
private static final int ITEM_ID_FEED = -2; private static final int ITEM_ID_FEED = -2;
private static final int ITEM_ID_BOOKMARKS = -3; private static final int ITEM_ID_BOOKMARKS = -3;
@ -147,6 +152,7 @@ public class MainActivity extends AppCompatActivity {
if (DeviceUtils.isTv(this)) { if (DeviceUtils.isTv(this)) {
FocusOverlayView.setupFocusObserver(this); FocusOverlayView.setupFocusObserver(this);
} }
setupBroadcastReceiver();
} }
private void setupDrawer() throws Exception { private void setupDrawer() throws Exception {
@ -454,6 +460,9 @@ public class MainActivity extends AppCompatActivity {
if (!isChangingConfigurations()) { if (!isChangingConfigurations()) {
StateSaver.clearStateFiles(); StateSaver.clearStateFiles();
} }
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver);
}
} }
@Override @Override
@ -795,9 +804,36 @@ public class MainActivity extends AppCompatActivity {
ErrorActivity.reportUiError(this, e); ErrorActivity.reportUiError(this, e);
} }
} }
private void setupBroadcastReceiver() {
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().equals(VideoDetailFragment.ACTION_PLAYER_STARTED)) {
final Fragment fragmentPlayer = getSupportFragmentManager()
.findFragmentById(R.id.fragment_player_holder);
if (fragmentPlayer == null) {
/* /*
* Utils * We still don't have a fragment attached to the activity.
* It can happen when a user started popup or background players
* without opening a stream inside the fragment.
* Adding it in a collapsed state (only mini player will be visible)
* */ * */
NavigationHelper.showMiniPlayer(getSupportFragmentManager());
}
/*
* At this point the player is added 100%, we can unregister.
* Other actions are useless since the fragment will not be removed after that
* */
unregisterReceiver(broadcastReceiver);
broadcastReceiver = null;
}
}
};
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(VideoDetailFragment.ACTION_PLAYER_STARTED);
registerReceiver(broadcastReceiver, intentFilter);
}
private boolean bottomSheetHiddenOrCollapsed() { private boolean bottomSheetHiddenOrCollapsed() {
final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder); final FrameLayout bottomSheetLayout = findViewById(R.id.fragment_player_holder);

Wyświetl plik

@ -146,6 +146,8 @@ public class VideoDetailFragment
"org.schabi.newpipe.VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER"; "org.schabi.newpipe.VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER";
public static final String ACTION_HIDE_MAIN_PLAYER = public static final String ACTION_HIDE_MAIN_PLAYER =
"org.schabi.newpipe.VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER"; "org.schabi.newpipe.VideoDetailFragment.ACTION_HIDE_MAIN_PLAYER";
public static final String ACTION_PLAYER_STARTED =
"org.schabi.newpipe.VideoDetailFragment.ACTION_PLAYER_STARTED";
public static final String ACTION_VIDEO_FRAGMENT_RESUMED = public static final String ACTION_VIDEO_FRAGMENT_RESUMED =
"org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED"; "org.schabi.newpipe.VideoDetailFragment.ACTION_VIDEO_FRAGMENT_RESUMED";
public static final String ACTION_VIDEO_FRAGMENT_STOPPED = public static final String ACTION_VIDEO_FRAGMENT_STOPPED =
@ -302,6 +304,12 @@ public class VideoDetailFragment
return instance; return instance;
} }
public static VideoDetailFragment getInstanceInCollapsedState() {
final VideoDetailFragment instance = new VideoDetailFragment();
instance.bottomSheetState = BottomSheetBehavior.STATE_COLLAPSED;
return instance;
}
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Fragment's Lifecycle // Fragment's Lifecycle
@ -518,7 +526,7 @@ public class VideoDetailFragment
openVideoPlayer(); openVideoPlayer();
} }
setOverlayPlayPauseImage(); setOverlayPlayPauseImage(player != null && player.isPlaying());
break; break;
case R.id.overlay_close_button: case R.id.overlay_close_button:
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
@ -1325,12 +1333,22 @@ public class VideoDetailFragment
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
} else if (intent.getAction().equals(ACTION_HIDE_MAIN_PLAYER)) { } else if (intent.getAction().equals(ACTION_HIDE_MAIN_PLAYER)) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
} else if (intent.getAction().equals(ACTION_PLAYER_STARTED)) {
// If the state is not hidden we don't need to show the mini player
if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
// Rebound to the service if it was closed via notification or mini player
if (!PlayerHolder.bound) {
PlayerHolder.startService(App.getApp(), false, VideoDetailFragment.this);
}
} }
} }
}; };
final IntentFilter intentFilter = new IntentFilter(); final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_SHOW_MAIN_PLAYER); intentFilter.addAction(ACTION_SHOW_MAIN_PLAYER);
intentFilter.addAction(ACTION_HIDE_MAIN_PLAYER); intentFilter.addAction(ACTION_HIDE_MAIN_PLAYER);
intentFilter.addAction(ACTION_PLAYER_STARTED);
activity.registerReceiver(broadcastReceiver, intentFilter); activity.registerReceiver(broadcastReceiver, intentFilter);
} }
@ -1719,8 +1737,12 @@ public class VideoDetailFragment
// It will allow to have live instance of PlayQueue with actual information about // It will allow to have live instance of PlayQueue with actual information about
// deleted/added items inside Channel/Playlist queue and makes possible to have // deleted/added items inside Channel/Playlist queue and makes possible to have
// a history of played items // a history of played items
if (stack.isEmpty() || !stack.peek().getPlayQueue().equals(queue)) { if ((stack.isEmpty() || !stack.peek().getPlayQueue().equals(queue)
stack.push(new StackItem(serviceId, url, name, playQueue)); && queue.getItem() != null)) {
stack.push(new StackItem(queue.getItem().getServiceId(),
queue.getItem().getUrl(),
queue.getItem().getTitle(),
queue));
} else { } else {
final StackItem stackWithQueue = findQueueInStack(queue); final StackItem stackWithQueue = findQueueInStack(queue);
if (stackWithQueue != null) { if (stackWithQueue != null) {
@ -1744,7 +1766,7 @@ public class VideoDetailFragment
final int repeatMode, final int repeatMode,
final boolean shuffled, final boolean shuffled,
final PlaybackParameters parameters) { final PlaybackParameters parameters) {
setOverlayPlayPauseImage(); setOverlayPlayPauseImage(player != null && player.isPlaying());
switch (state) { switch (state) {
case BasePlayer.STATE_PLAYING: case BasePlayer.STATE_PLAYING:
@ -1818,7 +1840,7 @@ public class VideoDetailFragment
@Override @Override
public void onServiceStopped() { public void onServiceStopped() {
setOverlayPlayPauseImage(); setOverlayPlayPauseImage(false);
if (currentInfo != null) { if (currentInfo != null) {
updateOverlayData(currentInfo.getName(), updateOverlayData(currentInfo.getName(),
currentInfo.getUploaderName(), currentInfo.getUploaderName(),
@ -2224,6 +2246,9 @@ public class VideoDetailFragment
break; break;
case BottomSheetBehavior.STATE_COLLAPSED: case BottomSheetBehavior.STATE_COLLAPSED:
moveFocusToMainFragment(true); moveFocusToMainFragment(true);
manageSpaceAtTheBottom(false);
bottomSheetBehavior.setPeekHeight(peekHeight);
// Re-enable clicks // Re-enable clicks
setOverlayElementsClickable(true); setOverlayElementsClickable(true);
@ -2270,8 +2295,8 @@ public class VideoDetailFragment
} }
} }
private void setOverlayPlayPauseImage() { private void setOverlayPlayPauseImage(final boolean playerIsPlaying) {
final int attr = player != null && player.isPlaying() final int attr = playerIsPlaying
? R.attr.ic_pause ? R.attr.ic_pause
: R.attr.ic_play_arrow; : R.attr.ic_play_arrow;
overlayPlayPauseButton.setImageResource( overlayPlayPauseButton.setImageResource(

Wyświetl plik

@ -255,10 +255,10 @@ public class VideoPlayerImpl extends VideoPlayer
onQueueClosed(); onQueueClosed();
// Android TV: without it focus will frame the whole player // Android TV: without it focus will frame the whole player
playPauseButton.requestFocus(); playPauseButton.requestFocus();
}
onPlay(); onPlay();
} }
NavigationHelper.sendPlayerStartedEvent(service);
}
VideoPlayerImpl(final MainPlayer service) { VideoPlayerImpl(final MainPlayer service) {
super("MainPlayer" + TAG, service); super("MainPlayer" + TAG, service);
@ -662,6 +662,7 @@ public class VideoPlayerImpl extends VideoPlayer
@Override @Override
public void onPlayQueueEdited() { public void onPlayQueueEdited() {
updatePlayback(); updatePlayback();
showOrHideButtons();
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
@ -1455,15 +1456,16 @@ public class VideoPlayerImpl extends VideoPlayer
return; return;
} }
playPreviousButton.setVisibility(playQueue.getIndex() == 0 final boolean showPrev = playQueue.getIndex() != 0;
? View.INVISIBLE final boolean showNext = playQueue.getIndex() + 1 != playQueue.getStreams().size();
: View.VISIBLE); final boolean showQueue = playQueue.getStreams().size() > 1 && !popupPlayerSelected();
playNextButton.setVisibility(playQueue.getIndex() + 1 == playQueue.getStreams().size()
? View.INVISIBLE playPreviousButton.setVisibility(showPrev ? View.VISIBLE : View.INVISIBLE);
: View.VISIBLE); playPreviousButton.setAlpha(showPrev ? 1.0f : 0.0f);
queueButton.setVisibility(playQueue.getStreams().size() <= 1 || popupPlayerSelected() playNextButton.setVisibility(showNext ? View.VISIBLE : View.INVISIBLE);
? View.GONE playNextButton.setAlpha(showNext ? 1.0f : 0.0f);
: View.VISIBLE); queueButton.setVisibility(showQueue ? View.VISIBLE : View.GONE);
queueButton.setAlpha(showQueue ? 1.0f : 0.0f);
} }
private void showSystemUIPartially() { private void showSystemUIPartially() {
@ -1936,6 +1938,7 @@ public class VideoPlayerImpl extends VideoPlayer
getControlsRoot().setPadding(0, 0, 0, 0); getControlsRoot().setPadding(0, 0, 0, 0);
} }
queueLayout.setPadding(0, 0, 0, 0); queueLayout.setPadding(0, 0, 0, 0);
updateQueue();
updateMetadata(); updateMetadata();
updatePlayback(); updatePlayback();
triggerProgressUpdate(); triggerProgressUpdate();

Wyświetl plik

@ -384,8 +384,19 @@ public final class NavigationHelper {
} }
public static void expandMainPlayer(final Context context) { public static void expandMainPlayer(final Context context) {
final Intent intent = new Intent(VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER); context.sendBroadcast(new Intent(VideoDetailFragment.ACTION_SHOW_MAIN_PLAYER));
context.sendBroadcast(intent); }
public static void sendPlayerStartedEvent(final Context context) {
context.sendBroadcast(new Intent(VideoDetailFragment.ACTION_PLAYER_STARTED));
}
public static void showMiniPlayer(final FragmentManager fragmentManager) {
final VideoDetailFragment instance = VideoDetailFragment.getInstanceInCollapsedState();
defaultTransaction(fragmentManager)
.replace(R.id.fragment_player_holder, instance)
.runOnCommit(() -> sendPlayerStartedEvent(instance.requireActivity()))
.commit();
} }
public static void openChannelFragment(final FragmentManager fragmentManager, public static void openChannelFragment(final FragmentManager fragmentManager,