Merge pull request #5371 from Stypox/merge-player
Merge player classes into a single one
This commit is contained in:
commit
c90696e67e
31 changed files with 4571 additions and 5267 deletions
|
@ -53,7 +53,7 @@
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".player.BackgroundPlayerActivity"
|
android:name=".player.PlayQueueActivity"
|
||||||
android:label="@string/title_activity_play_queue"
|
android:label="@string/title_activity_play_queue"
|
||||||
android:launchMode="singleTask" />
|
android:launchMode="singleTask" />
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ import org.schabi.newpipe.fragments.BackPressable;
|
||||||
import org.schabi.newpipe.fragments.MainFragment;
|
import org.schabi.newpipe.fragments.MainFragment;
|
||||||
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
|
||||||
import org.schabi.newpipe.fragments.list.search.SearchFragment;
|
import org.schabi.newpipe.fragments.list.search.SearchFragment;
|
||||||
import org.schabi.newpipe.player.VideoPlayer;
|
import org.schabi.newpipe.player.Player;
|
||||||
import org.schabi.newpipe.player.event.OnKeyDownListener;
|
import org.schabi.newpipe.player.event.OnKeyDownListener;
|
||||||
import org.schabi.newpipe.player.helper.PlayerHolder;
|
import org.schabi.newpipe.player.helper.PlayerHolder;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||||
|
@ -759,7 +759,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
switch (linkType) {
|
switch (linkType) {
|
||||||
case STREAM:
|
case STREAM:
|
||||||
final String intentCacheKey = intent.getStringExtra(
|
final String intentCacheKey = intent.getStringExtra(
|
||||||
VideoPlayer.PLAY_QUEUE_KEY);
|
Player.PLAY_QUEUE_KEY);
|
||||||
final PlayQueue playQueue = intentCacheKey != null
|
final PlayQueue playQueue = intentCacheKey != null
|
||||||
? SerializedCache.getInstance()
|
? SerializedCache.getInstance()
|
||||||
.take(intentCacheKey, PlayQueue.class)
|
.take(intentCacheKey, PlayQueue.class)
|
||||||
|
|
|
@ -49,7 +49,6 @@ import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.Player;
|
|
||||||
import com.google.android.material.appbar.AppBarLayout;
|
import com.google.android.material.appbar.AppBarLayout;
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
@ -80,9 +79,8 @@ import org.schabi.newpipe.fragments.list.videos.RelatedVideosFragment;
|
||||||
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
|
import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
|
||||||
import org.schabi.newpipe.local.dialog.PlaylistCreationDialog;
|
import org.schabi.newpipe.local.dialog.PlaylistCreationDialog;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.player.BasePlayer;
|
import org.schabi.newpipe.player.Player;
|
||||||
import org.schabi.newpipe.player.MainPlayer;
|
import org.schabi.newpipe.player.MainPlayer;
|
||||||
import org.schabi.newpipe.player.VideoPlayerImpl;
|
|
||||||
import org.schabi.newpipe.player.event.OnKeyDownListener;
|
import org.schabi.newpipe.player.event.OnKeyDownListener;
|
||||||
import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener;
|
import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener;
|
||||||
import org.schabi.newpipe.player.helper.PlayerHelper;
|
import org.schabi.newpipe.player.helper.PlayerHelper;
|
||||||
|
@ -255,14 +253,14 @@ public final class VideoDetailFragment
|
||||||
|
|
||||||
private ContentObserver settingsContentObserver;
|
private ContentObserver settingsContentObserver;
|
||||||
private MainPlayer playerService;
|
private MainPlayer playerService;
|
||||||
private VideoPlayerImpl player;
|
private Player player;
|
||||||
|
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Service management
|
// Service management
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(final VideoPlayerImpl connectedPlayer,
|
public void onServiceConnected(final Player connectedPlayer,
|
||||||
final MainPlayer connectedPlayerService,
|
final MainPlayer connectedPlayerService,
|
||||||
final boolean playAfterConnect) {
|
final boolean playAfterConnect) {
|
||||||
player = connectedPlayer;
|
player = connectedPlayer;
|
||||||
|
@ -539,7 +537,7 @@ public final class VideoDetailFragment
|
||||||
break;
|
break;
|
||||||
case R.id.overlay_play_pause_button:
|
case R.id.overlay_play_pause_button:
|
||||||
if (playerIsNotStopped()) {
|
if (playerIsNotStopped()) {
|
||||||
player.onPlayPause();
|
player.playPause();
|
||||||
player.hideControls(0, 0);
|
player.hideControls(0, 0);
|
||||||
showSystemUi();
|
showSystemUi();
|
||||||
} else {
|
} else {
|
||||||
|
@ -805,7 +803,7 @@ public final class VideoDetailFragment
|
||||||
// If we are in fullscreen mode just exit from it via first back press
|
// If we are in fullscreen mode just exit from it via first back press
|
||||||
if (player != null && player.isFullscreen()) {
|
if (player != null && player.isFullscreen()) {
|
||||||
if (!DeviceUtils.isTablet(activity)) {
|
if (!DeviceUtils.isTablet(activity)) {
|
||||||
player.onPause();
|
player.pause();
|
||||||
}
|
}
|
||||||
restoreDefaultOrientation();
|
restoreDefaultOrientation();
|
||||||
setAutoPlay(false);
|
setAutoPlay(false);
|
||||||
|
@ -850,7 +848,7 @@ public final class VideoDetailFragment
|
||||||
|
|
||||||
final PlayQueueItem playQueueItem = item.getPlayQueue().getItem();
|
final PlayQueueItem playQueueItem = item.getPlayQueue().getItem();
|
||||||
// Update title, url, uploader from the last item in the stack (it's current now)
|
// Update title, url, uploader from the last item in the stack (it's current now)
|
||||||
final boolean isPlayerStopped = player == null || player.isPlayerStopped();
|
final boolean isPlayerStopped = player == null || player.isStopped();
|
||||||
if (playQueueItem != null && isPlayerStopped) {
|
if (playQueueItem != null && isPlayerStopped) {
|
||||||
updateOverlayData(playQueueItem.getTitle(),
|
updateOverlayData(playQueueItem.getTitle(),
|
||||||
playQueueItem.getUploader(), playQueueItem.getThumbnailUrl());
|
playQueueItem.getUploader(), playQueueItem.getThumbnailUrl());
|
||||||
|
@ -1569,7 +1567,7 @@ public final class VideoDetailFragment
|
||||||
showMetaInfoInTextView(info.getMetaInfo(), detailMetaInfoTextView, detailMetaInfoSeparator);
|
showMetaInfoInTextView(info.getMetaInfo(), detailMetaInfoTextView, detailMetaInfoSeparator);
|
||||||
|
|
||||||
|
|
||||||
if (player == null || player.isPlayerStopped()) {
|
if (player == null || player.isStopped()) {
|
||||||
updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl());
|
updateOverlayData(info.getName(), info.getUploaderName(), info.getThumbnailUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1797,7 +1795,7 @@ public final class VideoDetailFragment
|
||||||
setOverlayPlayPauseImage(player != null && player.isPlaying());
|
setOverlayPlayPauseImage(player != null && player.isPlaying());
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case BasePlayer.STATE_PLAYING:
|
case Player.STATE_PLAYING:
|
||||||
if (positionView.getAlpha() != 1.0f
|
if (positionView.getAlpha() != 1.0f
|
||||||
&& player.getPlayQueue() != null
|
&& player.getPlayQueue() != null
|
||||||
&& player.getPlayQueue().getItem() != null
|
&& player.getPlayQueue().getItem() != null
|
||||||
|
@ -1814,7 +1812,7 @@ public final class VideoDetailFragment
|
||||||
final int duration,
|
final int duration,
|
||||||
final int bufferPercent) {
|
final int bufferPercent) {
|
||||||
// Progress updates every second even if media is paused. It's useless until playing
|
// Progress updates every second even if media is paused. It's useless until playing
|
||||||
if (!player.getPlayer().isPlaying() || playQueue == null) {
|
if (!player.isPlaying() || playQueue == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1891,10 +1889,8 @@ public final class VideoDetailFragment
|
||||||
|
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
hideSystemUiIfNeeded();
|
hideSystemUiIfNeeded();
|
||||||
viewPager.setVisibility(View.GONE);
|
|
||||||
} else {
|
} else {
|
||||||
showSystemUi();
|
showSystemUi();
|
||||||
viewPager.setVisibility(View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (relatedStreamsLayout != null) {
|
if (relatedStreamsLayout != null) {
|
||||||
|
@ -2020,9 +2016,7 @@ public final class VideoDetailFragment
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean playerIsNotStopped() {
|
private boolean playerIsNotStopped() {
|
||||||
return player != null
|
return player != null && !player.isStopped();
|
||||||
&& player.getPlayer() != null
|
|
||||||
&& player.getPlayer().getPlaybackState() != Player.STATE_IDLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restoreDefaultBrightness() {
|
private void restoreDefaultBrightness() {
|
||||||
|
@ -2073,7 +2067,7 @@ public final class VideoDetailFragment
|
||||||
player.checkLandscape();
|
player.checkLandscape();
|
||||||
// Let's give a user time to look at video information page if video is not playing
|
// Let's give a user time to look at video information page if video is not playing
|
||||||
if (globalScreenOrientationLocked(activity) && !player.isPlaying()) {
|
if (globalScreenOrientationLocked(activity) && !player.isPlaying()) {
|
||||||
player.onPlay();
|
player.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2287,7 +2281,7 @@ public final class VideoDetailFragment
|
||||||
// Re-enable clicks
|
// Re-enable clicks
|
||||||
setOverlayElementsClickable(true);
|
setOverlayElementsClickable(true);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.onQueueClosed();
|
player.closeQueue();
|
||||||
}
|
}
|
||||||
setOverlayLook(appBarLayout, behavior, 0);
|
setOverlayLook(appBarLayout, behavior, 0);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
package org.schabi.newpipe.player;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.view.Menu;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
|
||||||
|
|
||||||
public final class BackgroundPlayerActivity extends ServicePlayerActivity {
|
|
||||||
|
|
||||||
private static final String TAG = "BackgroundPlayerActivity";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTag() {
|
|
||||||
return TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSupportActionTitle() {
|
|
||||||
return getResources().getString(R.string.title_activity_play_queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Intent getBindIntent() {
|
|
||||||
return new Intent(this, MainPlayer.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startPlayerListener() {
|
|
||||||
if (player instanceof VideoPlayerImpl) {
|
|
||||||
((VideoPlayerImpl) player).setActivityListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stopPlayerListener() {
|
|
||||||
if (player instanceof VideoPlayerImpl) {
|
|
||||||
((VideoPlayerImpl) player).removeActivityListener(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPlayerOptionMenuResource() {
|
|
||||||
return R.menu.menu_play_queue_bg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setupMenu(final Menu menu) {
|
|
||||||
if (player == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu.findItem(R.id.action_switch_popup)
|
|
||||||
.setVisible(!((VideoPlayerImpl) player).popupPlayerSelected());
|
|
||||||
menu.findItem(R.id.action_switch_background)
|
|
||||||
.setVisible(!((VideoPlayerImpl) player).audioPlayerSelected());
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -48,9 +48,9 @@ import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
||||||
*/
|
*/
|
||||||
public final class MainPlayer extends Service {
|
public final class MainPlayer extends Service {
|
||||||
private static final String TAG = "MainPlayer";
|
private static final String TAG = "MainPlayer";
|
||||||
private static final boolean DEBUG = BasePlayer.DEBUG;
|
private static final boolean DEBUG = Player.DEBUG;
|
||||||
|
|
||||||
private VideoPlayerImpl playerImpl;
|
private Player player;
|
||||||
private WindowManager windowManager;
|
private WindowManager windowManager;
|
||||||
|
|
||||||
private final IBinder mBinder = new MainPlayer.LocalBinder();
|
private final IBinder mBinder = new MainPlayer.LocalBinder();
|
||||||
|
@ -69,8 +69,6 @@ public final class MainPlayer extends Service {
|
||||||
= App.PACKAGE_NAME + ".player.MainPlayer.CLOSE";
|
= App.PACKAGE_NAME + ".player.MainPlayer.CLOSE";
|
||||||
static final String ACTION_PLAY_PAUSE
|
static final String ACTION_PLAY_PAUSE
|
||||||
= App.PACKAGE_NAME + ".player.MainPlayer.PLAY_PAUSE";
|
= App.PACKAGE_NAME + ".player.MainPlayer.PLAY_PAUSE";
|
||||||
static final String ACTION_OPEN_CONTROLS
|
|
||||||
= App.PACKAGE_NAME + ".player.MainPlayer.OPEN_CONTROLS";
|
|
||||||
static final String ACTION_REPEAT
|
static final String ACTION_REPEAT
|
||||||
= App.PACKAGE_NAME + ".player.MainPlayer.REPEAT";
|
= App.PACKAGE_NAME + ".player.MainPlayer.REPEAT";
|
||||||
static final String ACTION_PLAY_NEXT
|
static final String ACTION_PLAY_NEXT
|
||||||
|
@ -105,11 +103,10 @@ public final class MainPlayer extends Service {
|
||||||
private void createView() {
|
private void createView() {
|
||||||
final PlayerBinding binding = PlayerBinding.inflate(LayoutInflater.from(this));
|
final PlayerBinding binding = PlayerBinding.inflate(LayoutInflater.from(this));
|
||||||
|
|
||||||
playerImpl = new VideoPlayerImpl(this);
|
player = new Player(this);
|
||||||
playerImpl.setup(binding);
|
player.setupFromView(binding);
|
||||||
playerImpl.shouldUpdateOnProgress = true;
|
|
||||||
|
|
||||||
NotificationUtil.getInstance().createNotificationAndStartForeground(playerImpl, this);
|
NotificationUtil.getInstance().createNotificationAndStartForeground(player, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -119,19 +116,19 @@ public final class MainPlayer extends Service {
|
||||||
+ "], flags = [" + flags + "], startId = [" + startId + "]");
|
+ "], flags = [" + flags + "], startId = [" + startId + "]");
|
||||||
}
|
}
|
||||||
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
|
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
|
||||||
&& playerImpl.playQueue == null) {
|
&& player.getPlayQueue() == null) {
|
||||||
// Player is not working, no need to process media button's action
|
// Player is not working, no need to process media button's action
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
|
if (Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())
|
||||||
|| intent.getStringExtra(VideoPlayer.PLAY_QUEUE_KEY) != null) {
|
|| intent.getStringExtra(Player.PLAY_QUEUE_KEY) != null) {
|
||||||
NotificationUtil.getInstance().createNotificationAndStartForeground(playerImpl, this);
|
NotificationUtil.getInstance().createNotificationAndStartForeground(player, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerImpl.handleIntent(intent);
|
player.handleIntent(intent);
|
||||||
if (playerImpl.mediaSessionManager != null) {
|
if (player.getMediaSessionManager() != null) {
|
||||||
playerImpl.mediaSessionManager.handleMediaButtonIntent(intent);
|
player.getMediaSessionManager().handleMediaButtonIntent(intent);
|
||||||
}
|
}
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
@ -141,20 +138,20 @@ public final class MainPlayer extends Service {
|
||||||
Log.d(TAG, "stop() called");
|
Log.d(TAG, "stop() called");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerImpl.getPlayer() != null) {
|
if (!player.exoPlayerIsNull()) {
|
||||||
playerImpl.wasPlaying = playerImpl.getPlayer().getPlayWhenReady();
|
player.saveWasPlaying();
|
||||||
// Releases wifi & cpu, disables keepScreenOn, etc.
|
// Releases wifi & cpu, disables keepScreenOn, etc.
|
||||||
if (!autoplayEnabled) {
|
if (!autoplayEnabled) {
|
||||||
playerImpl.onPause();
|
player.pause();
|
||||||
}
|
}
|
||||||
// We can't just pause the player here because it will make transition
|
// We can't just pause the player here because it will make transition
|
||||||
// from one stream to a new stream not smooth
|
// from one stream to a new stream not smooth
|
||||||
playerImpl.getPlayer().stop(false);
|
player.smoothStopPlayer();
|
||||||
playerImpl.setRecovery();
|
player.setRecovery();
|
||||||
// Android TV will handle back button in case controls will be visible
|
// Android TV will handle back button in case controls will be visible
|
||||||
// (one more additional unneeded click while the player is hidden)
|
// (one more additional unneeded click while the player is hidden)
|
||||||
playerImpl.hideControls(0, 0);
|
player.hideControls(0, 0);
|
||||||
playerImpl.onQueueClosed();
|
player.closeQueue();
|
||||||
// Notification shows information about old stream but if a user selects
|
// Notification shows information about old stream but if a user selects
|
||||||
// a stream from backStack it's not actual anymore
|
// a stream from backStack it's not actual anymore
|
||||||
// So we should hide the notification at all.
|
// So we should hide the notification at all.
|
||||||
|
@ -168,7 +165,7 @@ public final class MainPlayer extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void onTaskRemoved(final Intent rootIntent) {
|
public void onTaskRemoved(final Intent rootIntent) {
|
||||||
super.onTaskRemoved(rootIntent);
|
super.onTaskRemoved(rootIntent);
|
||||||
if (!playerImpl.videoPlayerSelected()) {
|
if (!player.videoPlayerSelected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onDestroy();
|
onDestroy();
|
||||||
|
@ -181,7 +178,23 @@ public final class MainPlayer extends Service {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "destroy() called");
|
Log.d(TAG, "destroy() called");
|
||||||
}
|
}
|
||||||
onClose();
|
|
||||||
|
if (player != null) {
|
||||||
|
// Exit from fullscreen when user closes the player via notification
|
||||||
|
if (player.isFullscreen()) {
|
||||||
|
player.toggleFullscreen();
|
||||||
|
}
|
||||||
|
removeViewFromParent();
|
||||||
|
|
||||||
|
player.saveStreamProgressState();
|
||||||
|
player.setRecovery();
|
||||||
|
player.stopActivityBinding();
|
||||||
|
player.removePopupFromView();
|
||||||
|
player.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationUtil.getInstance().cancelNotificationAndStopForeground(this);
|
||||||
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -194,32 +207,6 @@ public final class MainPlayer extends Service {
|
||||||
return mBinder;
|
return mBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Actions
|
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
|
||||||
private void onClose() {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "onClose() called");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerImpl != null) {
|
|
||||||
// Exit from fullscreen when user closes the player via notification
|
|
||||||
if (playerImpl.isFullscreen()) {
|
|
||||||
playerImpl.toggleFullscreen();
|
|
||||||
}
|
|
||||||
removeViewFromParent();
|
|
||||||
|
|
||||||
playerImpl.setRecovery();
|
|
||||||
playerImpl.savePlaybackState();
|
|
||||||
playerImpl.stopActivityBinding();
|
|
||||||
playerImpl.removePopupFromView();
|
|
||||||
playerImpl.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationUtil.getInstance().cancelNotificationAndStopForeground(this);
|
|
||||||
stopSelf();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*//////////////////////////////////////////////////////////////////////////
|
/*//////////////////////////////////////////////////////////////////////////
|
||||||
// Utils
|
// Utils
|
||||||
//////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////*/
|
||||||
|
@ -227,25 +214,25 @@ public final class MainPlayer extends Service {
|
||||||
boolean isLandscape() {
|
boolean isLandscape() {
|
||||||
// DisplayMetrics from activity context knows about MultiWindow feature
|
// DisplayMetrics from activity context knows about MultiWindow feature
|
||||||
// while DisplayMetrics from app context doesn't
|
// while DisplayMetrics from app context doesn't
|
||||||
final DisplayMetrics metrics = (playerImpl != null
|
final DisplayMetrics metrics = (player != null
|
||||||
&& playerImpl.getParentActivity() != null
|
&& player.getParentActivity() != null
|
||||||
? playerImpl.getParentActivity().getResources()
|
? player.getParentActivity().getResources()
|
||||||
: getResources()).getDisplayMetrics();
|
: getResources()).getDisplayMetrics();
|
||||||
return metrics.heightPixels < metrics.widthPixels;
|
return metrics.heightPixels < metrics.widthPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public View getView() {
|
public View getView() {
|
||||||
if (playerImpl == null) {
|
if (player == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return playerImpl.getRootView();
|
return player.getRootView();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeViewFromParent() {
|
public void removeViewFromParent() {
|
||||||
if (getView() != null && getView().getParent() != null) {
|
if (getView() != null && getView().getParent() != null) {
|
||||||
if (playerImpl.getParentActivity() != null) {
|
if (player.getParentActivity() != null) {
|
||||||
// This means view was added to fragment
|
// This means view was added to fragment
|
||||||
final ViewGroup parent = (ViewGroup) getView().getParent();
|
final ViewGroup parent = (ViewGroup) getView().getParent();
|
||||||
parent.removeView(getView());
|
parent.removeView(getView());
|
||||||
|
@ -263,8 +250,8 @@ public final class MainPlayer extends Service {
|
||||||
return MainPlayer.this;
|
return MainPlayer.this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VideoPlayerImpl getPlayer() {
|
public Player getPlayer() {
|
||||||
return MainPlayer.this.playerImpl;
|
return MainPlayer.this.player;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ import static org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE;
|
||||||
*/
|
*/
|
||||||
public final class NotificationUtil {
|
public final class NotificationUtil {
|
||||||
private static final String TAG = NotificationUtil.class.getSimpleName();
|
private static final String TAG = NotificationUtil.class.getSimpleName();
|
||||||
private static final boolean DEBUG = BasePlayer.DEBUG;
|
private static final boolean DEBUG = Player.DEBUG;
|
||||||
private static final int NOTIFICATION_ID = 123789;
|
private static final int NOTIFICATION_ID = 123789;
|
||||||
|
|
||||||
@Nullable private static NotificationUtil instance = null;
|
@Nullable private static NotificationUtil instance = null;
|
||||||
|
@ -76,7 +76,7 @@ public final class NotificationUtil {
|
||||||
* @param forceRecreate whether to force the recreation of the notification even if it already
|
* @param forceRecreate whether to force the recreation of the notification even if it already
|
||||||
* exists
|
* exists
|
||||||
*/
|
*/
|
||||||
synchronized void createNotificationIfNeededAndUpdate(final VideoPlayerImpl player,
|
synchronized void createNotificationIfNeededAndUpdate(final Player player,
|
||||||
final boolean forceRecreate) {
|
final boolean forceRecreate) {
|
||||||
if (forceRecreate || notificationBuilder == null) {
|
if (forceRecreate || notificationBuilder == null) {
|
||||||
notificationBuilder = createNotification(player);
|
notificationBuilder = createNotification(player);
|
||||||
|
@ -85,14 +85,14 @@ public final class NotificationUtil {
|
||||||
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
|
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized NotificationCompat.Builder createNotification(
|
private synchronized NotificationCompat.Builder createNotification(final Player player) {
|
||||||
final VideoPlayerImpl player) {
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "createNotification()");
|
Log.d(TAG, "createNotification()");
|
||||||
}
|
}
|
||||||
notificationManager = NotificationManagerCompat.from(player.context);
|
notificationManager = NotificationManagerCompat.from(player.getContext());
|
||||||
final NotificationCompat.Builder builder = new NotificationCompat.Builder(player.context,
|
final NotificationCompat.Builder builder =
|
||||||
player.context.getString(R.string.notification_channel_id));
|
new NotificationCompat.Builder(player.getContext(),
|
||||||
|
player.getContext().getString(R.string.notification_channel_id));
|
||||||
|
|
||||||
initializeNotificationSlots(player);
|
initializeNotificationSlots(player);
|
||||||
|
|
||||||
|
@ -107,25 +107,25 @@ public final class NotificationUtil {
|
||||||
|
|
||||||
// build the compact slot indices array (need code to convert from Integer... because Java)
|
// build the compact slot indices array (need code to convert from Integer... because Java)
|
||||||
final List<Integer> compactSlotList = NotificationConstants.getCompactSlotsFromPreferences(
|
final List<Integer> compactSlotList = NotificationConstants.getCompactSlotsFromPreferences(
|
||||||
player.context, player.sharedPreferences, nonNothingSlotCount);
|
player.getContext(), player.getPrefs(), nonNothingSlotCount);
|
||||||
final int[] compactSlots = new int[compactSlotList.size()];
|
final int[] compactSlots = new int[compactSlotList.size()];
|
||||||
for (int i = 0; i < compactSlotList.size(); i++) {
|
for (int i = 0; i < compactSlotList.size(); i++) {
|
||||||
compactSlots[i] = compactSlotList.get(i);
|
compactSlots[i] = compactSlotList.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
|
builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
|
||||||
.setMediaSession(player.mediaSessionManager.getSessionToken())
|
.setMediaSession(player.getMediaSessionManager().getSessionToken())
|
||||||
.setShowActionsInCompactView(compactSlots))
|
.setShowActionsInCompactView(compactSlots))
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||||
.setCategory(NotificationCompat.CATEGORY_TRANSPORT)
|
.setCategory(NotificationCompat.CATEGORY_TRANSPORT)
|
||||||
.setShowWhen(false)
|
.setShowWhen(false)
|
||||||
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
|
.setSmallIcon(R.drawable.ic_newpipe_triangle_white)
|
||||||
.setColor(ContextCompat.getColor(player.context, R.color.dark_background_color))
|
.setColor(ContextCompat.getColor(player.getContext(),
|
||||||
.setColorized(player.sharedPreferences.getBoolean(
|
R.color.dark_background_color))
|
||||||
player.context.getString(R.string.notification_colorize_key),
|
.setColorized(player.getPrefs().getBoolean(
|
||||||
true))
|
player.getContext().getString(R.string.notification_colorize_key), true))
|
||||||
.setDeleteIntent(PendingIntent.getBroadcast(player.context, NOTIFICATION_ID,
|
.setDeleteIntent(PendingIntent.getBroadcast(player.getContext(), NOTIFICATION_ID,
|
||||||
new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT));
|
new Intent(ACTION_CLOSE), FLAG_UPDATE_CURRENT));
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
@ -135,20 +135,20 @@ public final class NotificationUtil {
|
||||||
* Updates the notification builder and the button icons depending on the playback state.
|
* Updates the notification builder and the button icons depending on the playback state.
|
||||||
* @param player the player currently open, to take data from
|
* @param player the player currently open, to take data from
|
||||||
*/
|
*/
|
||||||
private synchronized void updateNotification(final VideoPlayerImpl player) {
|
private synchronized void updateNotification(final Player player) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "updateNotification()");
|
Log.d(TAG, "updateNotification()");
|
||||||
}
|
}
|
||||||
|
|
||||||
// also update content intent, in case the user switched players
|
// also update content intent, in case the user switched players
|
||||||
notificationBuilder.setContentIntent(PendingIntent.getActivity(player.context,
|
notificationBuilder.setContentIntent(PendingIntent.getActivity(player.getContext(),
|
||||||
NOTIFICATION_ID, getIntentForNotification(player), FLAG_UPDATE_CURRENT));
|
NOTIFICATION_ID, getIntentForNotification(player), FLAG_UPDATE_CURRENT));
|
||||||
notificationBuilder.setContentTitle(player.getVideoTitle());
|
notificationBuilder.setContentTitle(player.getVideoTitle());
|
||||||
notificationBuilder.setContentText(player.getUploaderName());
|
notificationBuilder.setContentText(player.getUploaderName());
|
||||||
notificationBuilder.setTicker(player.getVideoTitle());
|
notificationBuilder.setTicker(player.getVideoTitle());
|
||||||
updateActions(notificationBuilder, player);
|
updateActions(notificationBuilder, player);
|
||||||
final boolean showThumbnail = player.sharedPreferences.getBoolean(
|
final boolean showThumbnail = player.getPrefs().getBoolean(
|
||||||
player.context.getString(R.string.show_thumbnail_key), true);
|
player.getContext().getString(R.string.show_thumbnail_key), true);
|
||||||
if (showThumbnail) {
|
if (showThumbnail) {
|
||||||
setLargeIcon(notificationBuilder, player);
|
setLargeIcon(notificationBuilder, player);
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ public final class NotificationUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void createNotificationAndStartForeground(final VideoPlayerImpl player, final Service service) {
|
void createNotificationAndStartForeground(final Player player, final Service service) {
|
||||||
if (notificationBuilder == null) {
|
if (notificationBuilder == null) {
|
||||||
notificationBuilder = createNotification(player);
|
notificationBuilder = createNotification(player);
|
||||||
}
|
}
|
||||||
|
@ -203,17 +203,16 @@ public final class NotificationUtil {
|
||||||
// ACTIONS
|
// ACTIONS
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void initializeNotificationSlots(final VideoPlayerImpl player) {
|
private void initializeNotificationSlots(final Player player) {
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
notificationSlots[i] = player.sharedPreferences.getInt(
|
notificationSlots[i] = player.getPrefs().getInt(
|
||||||
player.context.getString(NotificationConstants.SLOT_PREF_KEYS[i]),
|
player.getContext().getString(NotificationConstants.SLOT_PREF_KEYS[i]),
|
||||||
NotificationConstants.SLOT_DEFAULTS[i]);
|
NotificationConstants.SLOT_DEFAULTS[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
private void updateActions(final NotificationCompat.Builder builder,
|
private void updateActions(final NotificationCompat.Builder builder, final Player player) {
|
||||||
final VideoPlayerImpl player) {
|
|
||||||
builder.mActions.clear();
|
builder.mActions.clear();
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
addAction(builder, player, notificationSlots[i]);
|
addAction(builder, player, notificationSlots[i]);
|
||||||
|
@ -221,7 +220,7 @@ public final class NotificationUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAction(final NotificationCompat.Builder builder,
|
private void addAction(final NotificationCompat.Builder builder,
|
||||||
final VideoPlayerImpl player,
|
final Player player,
|
||||||
@NotificationConstants.Action final int slot) {
|
@NotificationConstants.Action final int slot) {
|
||||||
final NotificationCompat.Action action = getAction(player, slot);
|
final NotificationCompat.Action action = getAction(player, slot);
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
|
@ -231,7 +230,7 @@ public final class NotificationUtil {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private NotificationCompat.Action getAction(
|
private NotificationCompat.Action getAction(
|
||||||
final VideoPlayerImpl player,
|
final Player player,
|
||||||
@NotificationConstants.Action final int selectedAction) {
|
@NotificationConstants.Action final int selectedAction) {
|
||||||
final int baseActionIcon = NotificationConstants.ACTION_ICONS[selectedAction];
|
final int baseActionIcon = NotificationConstants.ACTION_ICONS[selectedAction];
|
||||||
switch (selectedAction) {
|
switch (selectedAction) {
|
||||||
|
@ -252,7 +251,7 @@ public final class NotificationUtil {
|
||||||
R.string.exo_controls_fastforward_description, ACTION_FAST_FORWARD);
|
R.string.exo_controls_fastforward_description, ACTION_FAST_FORWARD);
|
||||||
|
|
||||||
case NotificationConstants.SMART_REWIND_PREVIOUS:
|
case NotificationConstants.SMART_REWIND_PREVIOUS:
|
||||||
if (player.playQueue != null && player.playQueue.size() > 1) {
|
if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) {
|
||||||
return getAction(player, R.drawable.exo_notification_previous,
|
return getAction(player, R.drawable.exo_notification_previous,
|
||||||
R.string.exo_controls_previous_description, ACTION_PLAY_PREVIOUS);
|
R.string.exo_controls_previous_description, ACTION_PLAY_PREVIOUS);
|
||||||
} else {
|
} else {
|
||||||
|
@ -261,7 +260,7 @@ public final class NotificationUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
case NotificationConstants.SMART_FORWARD_NEXT:
|
case NotificationConstants.SMART_FORWARD_NEXT:
|
||||||
if (player.playQueue != null && player.playQueue.size() > 1) {
|
if (player.getPlayQueue() != null && player.getPlayQueue().size() > 1) {
|
||||||
return getAction(player, R.drawable.exo_notification_next,
|
return getAction(player, R.drawable.exo_notification_next,
|
||||||
R.string.exo_controls_next_description, ACTION_PLAY_NEXT);
|
R.string.exo_controls_next_description, ACTION_PLAY_NEXT);
|
||||||
} else {
|
} else {
|
||||||
|
@ -270,23 +269,23 @@ public final class NotificationUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
case NotificationConstants.PLAY_PAUSE_BUFFERING:
|
case NotificationConstants.PLAY_PAUSE_BUFFERING:
|
||||||
if (player.getCurrentState() == BasePlayer.STATE_PREFLIGHT
|
if (player.getCurrentState() == Player.STATE_PREFLIGHT
|
||||||
|| player.getCurrentState() == BasePlayer.STATE_BLOCKED
|
|| player.getCurrentState() == Player.STATE_BLOCKED
|
||||||
|| player.getCurrentState() == BasePlayer.STATE_BUFFERING) {
|
|| player.getCurrentState() == Player.STATE_BUFFERING) {
|
||||||
// null intent -> show hourglass icon that does nothing when clicked
|
// null intent -> show hourglass icon that does nothing when clicked
|
||||||
return new NotificationCompat.Action(R.drawable.ic_hourglass_top_white_24dp_png,
|
return new NotificationCompat.Action(R.drawable.ic_hourglass_top_white_24dp_png,
|
||||||
player.context.getString(R.string.notification_action_buffering),
|
player.getContext().getString(R.string.notification_action_buffering),
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
case NotificationConstants.PLAY_PAUSE:
|
case NotificationConstants.PLAY_PAUSE:
|
||||||
if (player.getCurrentState() == BasePlayer.STATE_COMPLETED) {
|
if (player.getCurrentState() == Player.STATE_COMPLETED) {
|
||||||
return getAction(player, R.drawable.ic_replay_white_24dp_png,
|
return getAction(player, R.drawable.ic_replay_white_24dp_png,
|
||||||
R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE);
|
R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE);
|
||||||
} else if (player.isPlaying()
|
} else if (player.isPlaying()
|
||||||
|| player.getCurrentState() == BasePlayer.STATE_PREFLIGHT
|
|| player.getCurrentState() == Player.STATE_PREFLIGHT
|
||||||
|| player.getCurrentState() == BasePlayer.STATE_BLOCKED
|
|| player.getCurrentState() == Player.STATE_BLOCKED
|
||||||
|| player.getCurrentState() == BasePlayer.STATE_BUFFERING) {
|
|| player.getCurrentState() == Player.STATE_BUFFERING) {
|
||||||
return getAction(player, R.drawable.exo_notification_pause,
|
return getAction(player, R.drawable.exo_notification_pause,
|
||||||
R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE);
|
R.string.exo_controls_pause_description, ACTION_PLAY_PAUSE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -307,7 +306,7 @@ public final class NotificationUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
case NotificationConstants.SHUFFLE:
|
case NotificationConstants.SHUFFLE:
|
||||||
if (player.playQueue != null && player.playQueue.isShuffled()) {
|
if (player.getPlayQueue() != null && player.getPlayQueue().isShuffled()) {
|
||||||
return getAction(player, R.drawable.exo_controls_shuffle_on,
|
return getAction(player, R.drawable.exo_controls_shuffle_on,
|
||||||
R.string.exo_controls_shuffle_on_description, ACTION_SHUFFLE);
|
R.string.exo_controls_shuffle_on_description, ACTION_SHUFFLE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -326,23 +325,23 @@ public final class NotificationUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private NotificationCompat.Action getAction(final VideoPlayerImpl player,
|
private NotificationCompat.Action getAction(final Player player,
|
||||||
@DrawableRes final int drawable,
|
@DrawableRes final int drawable,
|
||||||
@StringRes final int title,
|
@StringRes final int title,
|
||||||
final String intentAction) {
|
final String intentAction) {
|
||||||
return new NotificationCompat.Action(drawable, player.context.getString(title),
|
return new NotificationCompat.Action(drawable, player.getContext().getString(title),
|
||||||
PendingIntent.getBroadcast(player.context, NOTIFICATION_ID,
|
PendingIntent.getBroadcast(player.getContext(), NOTIFICATION_ID,
|
||||||
new Intent(intentAction), FLAG_UPDATE_CURRENT));
|
new Intent(intentAction), FLAG_UPDATE_CURRENT));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Intent getIntentForNotification(final VideoPlayerImpl player) {
|
private Intent getIntentForNotification(final Player player) {
|
||||||
if (player.audioPlayerSelected() || player.popupPlayerSelected()) {
|
if (player.audioPlayerSelected() || player.popupPlayerSelected()) {
|
||||||
// Means we play in popup or audio only. Let's show the play queue
|
// Means we play in popup or audio only. Let's show the play queue
|
||||||
return NavigationHelper.getPlayQueueActivityIntent(player.context);
|
return NavigationHelper.getPlayQueueActivityIntent(player.getContext());
|
||||||
} else {
|
} else {
|
||||||
// We are playing in fragment. Don't open another activity just show fragment. That's it
|
// We are playing in fragment. Don't open another activity just show fragment. That's it
|
||||||
final Intent intent = NavigationHelper.getPlayerIntent(
|
final Intent intent = NavigationHelper.getPlayerIntent(
|
||||||
player.context, MainActivity.class, null, true);
|
player.getContext(), MainActivity.class, null, true);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
intent.setAction(Intent.ACTION_MAIN);
|
intent.setAction(Intent.ACTION_MAIN);
|
||||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
|
@ -355,10 +354,9 @@ public final class NotificationUtil {
|
||||||
// BITMAP
|
// BITMAP
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void setLargeIcon(final NotificationCompat.Builder builder,
|
private void setLargeIcon(final NotificationCompat.Builder builder, final Player player) {
|
||||||
final VideoPlayerImpl player) {
|
final boolean scaleImageToSquareAspectRatio = player.getPrefs().getBoolean(
|
||||||
final boolean scaleImageToSquareAspectRatio = player.sharedPreferences.getBoolean(
|
player.getContext().getString(R.string.scale_to_square_image_in_notifications_key),
|
||||||
player.context.getString(R.string.scale_to_square_image_in_notifications_key),
|
|
||||||
false);
|
false);
|
||||||
if (scaleImageToSquareAspectRatio) {
|
if (scaleImageToSquareAspectRatio) {
|
||||||
builder.setLargeIcon(getBitmapWithSquareAspectRatio(player.getThumbnail()));
|
builder.setLargeIcon(getBitmapWithSquareAspectRatio(player.getThumbnail()));
|
||||||
|
|
|
@ -16,13 +16,11 @@ import android.widget.PopupMenu;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.Player;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.databinding.ActivityPlayerQueueControlBinding;
|
import org.schabi.newpipe.databinding.ActivityPlayerQueueControlBinding;
|
||||||
|
@ -49,19 +47,21 @@ import java.util.List;
|
||||||
import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed;
|
import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed;
|
||||||
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
||||||
|
|
||||||
public abstract class ServicePlayerActivity extends AppCompatActivity
|
public final class PlayQueueActivity extends AppCompatActivity
|
||||||
implements PlayerEventListener, SeekBar.OnSeekBarChangeListener,
|
implements PlayerEventListener, SeekBar.OnSeekBarChangeListener,
|
||||||
View.OnClickListener, PlaybackParameterDialog.Callback {
|
View.OnClickListener, PlaybackParameterDialog.Callback {
|
||||||
|
|
||||||
|
private static final String TAG = PlayQueueActivity.class.getSimpleName();
|
||||||
|
|
||||||
private static final int RECYCLER_ITEM_POPUP_MENU_GROUP_ID = 47;
|
private static final int RECYCLER_ITEM_POPUP_MENU_GROUP_ID = 47;
|
||||||
private static final int SMOOTH_SCROLL_MAXIMUM_DISTANCE = 80;
|
private static final int SMOOTH_SCROLL_MAXIMUM_DISTANCE = 80;
|
||||||
|
|
||||||
protected BasePlayer player;
|
protected Player player;
|
||||||
|
|
||||||
private boolean serviceBound;
|
private boolean serviceBound;
|
||||||
private ServiceConnection serviceConnection;
|
private ServiceConnection serviceConnection;
|
||||||
|
|
||||||
private boolean seeking;
|
private boolean seeking;
|
||||||
private boolean redraw;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Views
|
// Views
|
||||||
|
@ -73,24 +73,6 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
|
|
||||||
private Menu menu;
|
private Menu menu;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Abstracts
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
public abstract String getTag();
|
|
||||||
|
|
||||||
public abstract String getSupportActionTitle();
|
|
||||||
|
|
||||||
public abstract Intent getBindIntent();
|
|
||||||
|
|
||||||
public abstract void startPlayerListener();
|
|
||||||
|
|
||||||
public abstract void stopPlayerListener();
|
|
||||||
|
|
||||||
public abstract int getPlayerOptionMenuResource();
|
|
||||||
|
|
||||||
public abstract void setupMenu(Menu m);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Activity Lifecycle
|
// Activity Lifecycle
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -107,35 +89,32 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
setSupportActionBar(queueControlBinding.toolbar);
|
setSupportActionBar(queueControlBinding.toolbar);
|
||||||
if (getSupportActionBar() != null) {
|
if (getSupportActionBar() != null) {
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
getSupportActionBar().setTitle(getSupportActionTitle());
|
getSupportActionBar().setTitle(R.string.title_activity_play_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceConnection = getServiceConnection();
|
serviceConnection = getServiceConnection();
|
||||||
bind();
|
bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
if (redraw) {
|
|
||||||
ActivityCompat.recreate(this);
|
|
||||||
redraw = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(final Menu m) {
|
public boolean onCreateOptionsMenu(final Menu m) {
|
||||||
this.menu = m;
|
this.menu = m;
|
||||||
getMenuInflater().inflate(R.menu.menu_play_queue, m);
|
getMenuInflater().inflate(R.menu.menu_play_queue, m);
|
||||||
getMenuInflater().inflate(getPlayerOptionMenuResource(), m);
|
getMenuInflater().inflate(R.menu.menu_play_queue_bg, m);
|
||||||
onMaybeMuteChanged();
|
onMaybeMuteChanged();
|
||||||
|
onPlaybackParameterChanged(player.getPlaybackParameters());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow to setup visibility of menuItems
|
// Allow to setup visibility of menuItems
|
||||||
@Override
|
@Override
|
||||||
public boolean onPrepareOptionsMenu(final Menu m) {
|
public boolean onPrepareOptionsMenu(final Menu m) {
|
||||||
setupMenu(m);
|
if (player != null) {
|
||||||
|
menu.findItem(R.id.action_switch_popup)
|
||||||
|
.setVisible(!player.popupPlayerSelected());
|
||||||
|
menu.findItem(R.id.action_switch_background)
|
||||||
|
.setVisible(!player.audioPlayerSelected());
|
||||||
|
}
|
||||||
return super.onPrepareOptionsMenu(m);
|
return super.onPrepareOptionsMenu(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,14 +146,14 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
case R.id.action_switch_popup:
|
case R.id.action_switch_popup:
|
||||||
if (PermissionHelper.isPopupEnabled(this)) {
|
if (PermissionHelper.isPopupEnabled(this)) {
|
||||||
this.player.setRecovery();
|
this.player.setRecovery();
|
||||||
NavigationHelper.playOnPopupPlayer(this, player.playQueue, true);
|
NavigationHelper.playOnPopupPlayer(this, player.getPlayQueue(), true);
|
||||||
} else {
|
} else {
|
||||||
PermissionHelper.showPopupEnablementToast(this);
|
PermissionHelper.showPopupEnablementToast(this);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_switch_background:
|
case R.id.action_switch_background:
|
||||||
this.player.setRecovery();
|
this.player.setRecovery();
|
||||||
NavigationHelper.playOnBackgroundPlayer(this, player.playQueue, true);
|
NavigationHelper.playOnBackgroundPlayer(this, player.getPlayQueue(), true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
|
@ -191,7 +170,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void bind() {
|
private void bind() {
|
||||||
final boolean success = bindService(getBindIntent(), serviceConnection, BIND_AUTO_CREATE);
|
final Intent bindIntent = new Intent(this, MainPlayer.class);
|
||||||
|
final boolean success = bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
unbindService(serviceConnection);
|
unbindService(serviceConnection);
|
||||||
}
|
}
|
||||||
|
@ -202,7 +182,9 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
if (serviceBound) {
|
if (serviceBound) {
|
||||||
unbindService(serviceConnection);
|
unbindService(serviceConnection);
|
||||||
serviceBound = false;
|
serviceBound = false;
|
||||||
stopPlayerListener();
|
if (player != null) {
|
||||||
|
player.removeActivityListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
if (player != null && player.getPlayQueueAdapter() != null) {
|
if (player != null && player.getPlayQueueAdapter() != null) {
|
||||||
player.getPlayQueueAdapter().unsetSelectedListener();
|
player.getPlayQueueAdapter().unsetSelectedListener();
|
||||||
|
@ -221,12 +203,12 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
return new ServiceConnection() {
|
return new ServiceConnection() {
|
||||||
@Override
|
@Override
|
||||||
public void onServiceDisconnected(final ComponentName name) {
|
public void onServiceDisconnected(final ComponentName name) {
|
||||||
Log.d(getTag(), "Player service is disconnected");
|
Log.d(TAG, "Player service is disconnected");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(final ComponentName name, final IBinder service) {
|
public void onServiceConnected(final ComponentName name, final IBinder service) {
|
||||||
Log.d(getTag(), "Player service is connected");
|
Log.d(TAG, "Player service is connected");
|
||||||
|
|
||||||
if (service instanceof PlayerServiceBinder) {
|
if (service instanceof PlayerServiceBinder) {
|
||||||
player = ((PlayerServiceBinder) service).getPlayerInstance();
|
player = ((PlayerServiceBinder) service).getPlayerInstance();
|
||||||
|
@ -235,12 +217,14 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player == null || player.getPlayQueue() == null
|
if (player == null || player.getPlayQueue() == null
|
||||||
|| player.getPlayQueueAdapter() == null || player.getPlayer() == null) {
|
|| player.getPlayQueueAdapter() == null || player.exoPlayerIsNull()) {
|
||||||
unbind();
|
unbind();
|
||||||
finish();
|
finish();
|
||||||
} else {
|
} else {
|
||||||
buildComponents();
|
buildComponents();
|
||||||
startPlayerListener();
|
if (player != null) {
|
||||||
|
player.setActivityListener(PlayQueueActivity.this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -375,7 +359,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
@Override
|
@Override
|
||||||
public void selected(final PlayQueueItem item, final View view) {
|
public void selected(final PlayQueueItem item, final View view) {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.onSelected(item);
|
player.selectQueueItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,15 +420,15 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
if (view.getId() == queueControlBinding.controlRepeat.getId()) {
|
if (view.getId() == queueControlBinding.controlRepeat.getId()) {
|
||||||
player.onRepeatClicked();
|
player.onRepeatClicked();
|
||||||
} else if (view.getId() == queueControlBinding.controlBackward.getId()) {
|
} else if (view.getId() == queueControlBinding.controlBackward.getId()) {
|
||||||
player.onPlayPrevious();
|
player.playPrevious();
|
||||||
} else if (view.getId() == queueControlBinding.controlFastRewind.getId()) {
|
} else if (view.getId() == queueControlBinding.controlFastRewind.getId()) {
|
||||||
player.onFastRewind();
|
player.fastRewind();
|
||||||
} else if (view.getId() == queueControlBinding.controlPlayPause.getId()) {
|
} else if (view.getId() == queueControlBinding.controlPlayPause.getId()) {
|
||||||
player.onPlayPause();
|
player.playPause();
|
||||||
} else if (view.getId() == queueControlBinding.controlFastForward.getId()) {
|
} else if (view.getId() == queueControlBinding.controlFastForward.getId()) {
|
||||||
player.onFastForward();
|
player.fastForward();
|
||||||
} else if (view.getId() == queueControlBinding.controlForward.getId()) {
|
} else if (view.getId() == queueControlBinding.controlForward.getId()) {
|
||||||
player.onPlayNext();
|
player.playNext();
|
||||||
} else if (view.getId() == queueControlBinding.controlShuffle.getId()) {
|
} else if (view.getId() == queueControlBinding.controlShuffle.getId()) {
|
||||||
player.onShuffleClicked();
|
player.onShuffleClicked();
|
||||||
} else if (view.getId() == queueControlBinding.metadata.getId()) {
|
} else if (view.getId() == queueControlBinding.metadata.getId()) {
|
||||||
|
@ -463,7 +447,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PlaybackParameterDialog.newInstance(player.getPlaybackSpeed(), player.getPlaybackPitch(),
|
PlaybackParameterDialog.newInstance(player.getPlaybackSpeed(), player.getPlaybackPitch(),
|
||||||
player.getPlaybackSkipSilence(), this).show(getSupportFragmentManager(), getTag());
|
player.getPlaybackSkipSilence(), this).show(getSupportFragmentManager(), TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -517,10 +501,8 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
final PlaylistAppendDialog d = PlaylistAppendDialog.fromPlayQueueItems(playlist);
|
final PlaylistAppendDialog d = PlaylistAppendDialog.fromPlayQueueItems(playlist);
|
||||||
|
|
||||||
PlaylistAppendDialog.onPlaylistFound(getApplicationContext(),
|
PlaylistAppendDialog.onPlaylistFound(getApplicationContext(),
|
||||||
() -> d.show(getSupportFragmentManager(), getTag()),
|
() -> d.show(getSupportFragmentManager(), TAG),
|
||||||
() -> PlaylistCreationDialog.newInstance(d)
|
() -> PlaylistCreationDialog.newInstance(d).show(getSupportFragmentManager(), TAG));
|
||||||
.show(getSupportFragmentManager(), getTag()
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -616,15 +598,15 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
|
|
||||||
private void onStateChanged(final int state) {
|
private void onStateChanged(final int state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case BasePlayer.STATE_PAUSED:
|
case Player.STATE_PAUSED:
|
||||||
queueControlBinding.controlPlayPause
|
queueControlBinding.controlPlayPause
|
||||||
.setImageResource(R.drawable.ic_play_arrow_white_24dp);
|
.setImageResource(R.drawable.ic_play_arrow_white_24dp);
|
||||||
break;
|
break;
|
||||||
case BasePlayer.STATE_PLAYING:
|
case Player.STATE_PLAYING:
|
||||||
queueControlBinding.controlPlayPause
|
queueControlBinding.controlPlayPause
|
||||||
.setImageResource(R.drawable.ic_pause_white_24dp);
|
.setImageResource(R.drawable.ic_pause_white_24dp);
|
||||||
break;
|
break;
|
||||||
case BasePlayer.STATE_COMPLETED:
|
case Player.STATE_COMPLETED:
|
||||||
queueControlBinding.controlPlayPause
|
queueControlBinding.controlPlayPause
|
||||||
.setImageResource(R.drawable.ic_replay_white_24dp);
|
.setImageResource(R.drawable.ic_replay_white_24dp);
|
||||||
break;
|
break;
|
||||||
|
@ -633,9 +615,9 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case BasePlayer.STATE_PAUSED:
|
case Player.STATE_PAUSED:
|
||||||
case BasePlayer.STATE_PLAYING:
|
case Player.STATE_PLAYING:
|
||||||
case BasePlayer.STATE_COMPLETED:
|
case Player.STATE_COMPLETED:
|
||||||
queueControlBinding.controlPlayPause.setClickable(true);
|
queueControlBinding.controlPlayPause.setClickable(true);
|
||||||
queueControlBinding.controlPlayPause.setVisibility(View.VISIBLE);
|
queueControlBinding.controlPlayPause.setVisibility(View.VISIBLE);
|
||||||
queueControlBinding.controlProgressBar.setVisibility(View.GONE);
|
queueControlBinding.controlProgressBar.setVisibility(View.GONE);
|
||||||
|
@ -650,15 +632,15 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
|
|
||||||
private void onPlayModeChanged(final int repeatMode, final boolean shuffled) {
|
private void onPlayModeChanged(final int repeatMode, final boolean shuffled) {
|
||||||
switch (repeatMode) {
|
switch (repeatMode) {
|
||||||
case Player.REPEAT_MODE_OFF:
|
case com.google.android.exoplayer2.Player.REPEAT_MODE_OFF:
|
||||||
queueControlBinding.controlRepeat
|
queueControlBinding.controlRepeat
|
||||||
.setImageResource(R.drawable.exo_controls_repeat_off);
|
.setImageResource(R.drawable.exo_controls_repeat_off);
|
||||||
break;
|
break;
|
||||||
case Player.REPEAT_MODE_ONE:
|
case com.google.android.exoplayer2.Player.REPEAT_MODE_ONE:
|
||||||
queueControlBinding.controlRepeat
|
queueControlBinding.controlRepeat
|
||||||
.setImageResource(R.drawable.exo_controls_repeat_one);
|
.setImageResource(R.drawable.exo_controls_repeat_one);
|
||||||
break;
|
break;
|
||||||
case Player.REPEAT_MODE_ALL:
|
case com.google.android.exoplayer2.Player.REPEAT_MODE_ALL:
|
||||||
queueControlBinding.controlRepeat
|
queueControlBinding.controlRepeat
|
||||||
.setImageResource(R.drawable.exo_controls_repeat_all);
|
.setImageResource(R.drawable.exo_controls_repeat_all);
|
||||||
break;
|
break;
|
||||||
|
@ -700,9 +682,7 @@ public abstract class ServicePlayerActivity extends AppCompatActivity
|
||||||
// using rootView.getContext() because getApplicationContext() didn't work
|
// using rootView.getContext() because getApplicationContext() didn't work
|
||||||
final Context context = queueControlBinding.getRoot().getContext();
|
final Context context = queueControlBinding.getRoot().getContext();
|
||||||
item.setIcon(ThemeHelper.resolveResourceIdFromAttr(context,
|
item.setIcon(ThemeHelper.resolveResourceIdFromAttr(context,
|
||||||
player.isMuted()
|
player.isMuted() ? R.attr.ic_volume_off : R.attr.ic_volume_up));
|
||||||
? R.attr.ic_volume_off
|
|
||||||
: R.attr.ic_volume_up));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
3973
app/src/main/java/org/schabi/newpipe/player/Player.java
Normal file
3973
app/src/main/java/org/schabi/newpipe/player/Player.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -5,13 +5,13 @@ import android.os.Binder;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
class PlayerServiceBinder extends Binder {
|
class PlayerServiceBinder extends Binder {
|
||||||
private final BasePlayer basePlayer;
|
private final Player player;
|
||||||
|
|
||||||
PlayerServiceBinder(@NonNull final BasePlayer basePlayer) {
|
PlayerServiceBinder(@NonNull final Player player) {
|
||||||
this.basePlayer = basePlayer;
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
BasePlayer getPlayerInstance() {
|
Player getPlayerInstance() {
|
||||||
return basePlayer;
|
return player;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -7,10 +7,10 @@ import android.view.GestureDetector
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewConfiguration
|
import android.view.ViewConfiguration
|
||||||
import org.schabi.newpipe.player.BasePlayer
|
|
||||||
import org.schabi.newpipe.player.MainPlayer
|
import org.schabi.newpipe.player.MainPlayer
|
||||||
import org.schabi.newpipe.player.VideoPlayerImpl
|
import org.schabi.newpipe.player.Player
|
||||||
import org.schabi.newpipe.player.helper.PlayerHelper
|
import org.schabi.newpipe.player.helper.PlayerHelper
|
||||||
|
import org.schabi.newpipe.player.helper.PlayerHelper.savePopupPositionAndSizeToPrefs
|
||||||
import org.schabi.newpipe.util.AnimationUtils
|
import org.schabi.newpipe.util.AnimationUtils
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.hypot
|
import kotlin.math.hypot
|
||||||
|
@ -18,14 +18,14 @@ import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base gesture handling for [VideoPlayerImpl]
|
* Base gesture handling for [Player]
|
||||||
*
|
*
|
||||||
* This class contains the logic for the player gestures like View preparations
|
* This class contains the logic for the player gestures like View preparations
|
||||||
* and provides some abstract methods to make it easier separating the logic from the UI.
|
* and provides some abstract methods to make it easier separating the logic from the UI.
|
||||||
*/
|
*/
|
||||||
abstract class BasePlayerGestureListener(
|
abstract class BasePlayerGestureListener(
|
||||||
@JvmField
|
@JvmField
|
||||||
protected val playerImpl: VideoPlayerImpl,
|
protected val player: Player,
|
||||||
@JvmField
|
@JvmField
|
||||||
protected val service: MainPlayer
|
protected val service: MainPlayer
|
||||||
) : GestureDetector.SimpleOnGestureListener(), View.OnTouchListener {
|
) : GestureDetector.SimpleOnGestureListener(), View.OnTouchListener {
|
||||||
|
@ -78,7 +78,7 @@ abstract class BasePlayerGestureListener(
|
||||||
// ///////////////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
||||||
return if (playerImpl.popupPlayerSelected()) {
|
return if (player.popupPlayerSelected()) {
|
||||||
onTouchInPopup(v, event)
|
onTouchInPopup(v, event)
|
||||||
} else {
|
} else {
|
||||||
onTouchInMain(v, event)
|
onTouchInMain(v, event)
|
||||||
|
@ -86,14 +86,14 @@ abstract class BasePlayerGestureListener(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onTouchInMain(v: View, event: MotionEvent): Boolean {
|
private fun onTouchInMain(v: View, event: MotionEvent): Boolean {
|
||||||
playerImpl.gestureDetector.onTouchEvent(event)
|
player.gestureDetector.onTouchEvent(event)
|
||||||
if (event.action == MotionEvent.ACTION_UP && isMovingInMain) {
|
if (event.action == MotionEvent.ACTION_UP && isMovingInMain) {
|
||||||
isMovingInMain = false
|
isMovingInMain = false
|
||||||
onScrollEnd(MainPlayer.PlayerType.VIDEO, event)
|
onScrollEnd(MainPlayer.PlayerType.VIDEO, event)
|
||||||
}
|
}
|
||||||
return when (event.action) {
|
return when (event.action) {
|
||||||
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
|
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
|
||||||
v.parent.requestDisallowInterceptTouchEvent(playerImpl.isFullscreen)
|
v.parent.requestDisallowInterceptTouchEvent(player.isFullscreen)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
MotionEvent.ACTION_UP -> {
|
MotionEvent.ACTION_UP -> {
|
||||||
|
@ -105,7 +105,7 @@ abstract class BasePlayerGestureListener(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onTouchInPopup(v: View, event: MotionEvent): Boolean {
|
private fun onTouchInPopup(v: View, event: MotionEvent): Boolean {
|
||||||
playerImpl.gestureDetector.onTouchEvent(event)
|
player.gestureDetector.onTouchEvent(event)
|
||||||
if (event.pointerCount == 2 && !isMovingInPopup && !isResizing) {
|
if (event.pointerCount == 2 && !isMovingInPopup && !isResizing) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing.")
|
Log.d(TAG, "onTouch() 2 finger pointer detected, enabling resizing.")
|
||||||
|
@ -157,10 +157,10 @@ abstract class BasePlayerGestureListener(
|
||||||
initSecPointerY = (-1).toFloat()
|
initSecPointerY = (-1).toFloat()
|
||||||
|
|
||||||
onPopupResizingEnd()
|
onPopupResizingEnd()
|
||||||
playerImpl.changeState(playerImpl.currentState)
|
player.changeState(player.currentState)
|
||||||
}
|
}
|
||||||
if (!playerImpl.isPopupClosing) {
|
if (!player.isPopupClosing) {
|
||||||
playerImpl.savePositionAndSize()
|
savePopupPositionAndSizeToPrefs(player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,19 +190,15 @@ abstract class BasePlayerGestureListener(
|
||||||
event.getY(0) - event.getY(1).toDouble()
|
event.getY(0) - event.getY(1).toDouble()
|
||||||
)
|
)
|
||||||
|
|
||||||
val popupWidth = playerImpl.popupWidth.toDouble()
|
val popupWidth = player.popupLayoutParams!!.width.toDouble()
|
||||||
// change co-ordinates of popup so the center stays at the same position
|
// change co-ordinates of popup so the center stays at the same position
|
||||||
val newWidth = popupWidth * currentPointerDistance / initPointerDistance
|
val newWidth = popupWidth * currentPointerDistance / initPointerDistance
|
||||||
initPointerDistance = currentPointerDistance
|
initPointerDistance = currentPointerDistance
|
||||||
playerImpl.popupLayoutParams.x += ((popupWidth - newWidth) / 2.0).toInt()
|
player.popupLayoutParams!!.x += ((popupWidth - newWidth) / 2.0).toInt()
|
||||||
|
|
||||||
playerImpl.checkPopupPositionBounds()
|
player.checkPopupPositionBounds()
|
||||||
playerImpl.updateScreenSize()
|
player.updateScreenSize()
|
||||||
|
player.changePopupSize(min(player.screenWidth.toDouble(), newWidth).toInt())
|
||||||
playerImpl.updatePopupSize(
|
|
||||||
min(playerImpl.screenWidth.toDouble(), newWidth).toInt(),
|
|
||||||
-1
|
|
||||||
)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,7 +218,7 @@ abstract class BasePlayerGestureListener(
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (playerImpl.popupPlayerSelected())
|
return if (player.popupPlayerSelected())
|
||||||
onDownInPopup(e)
|
onDownInPopup(e)
|
||||||
else
|
else
|
||||||
true
|
true
|
||||||
|
@ -231,12 +227,10 @@ abstract class BasePlayerGestureListener(
|
||||||
private fun onDownInPopup(e: MotionEvent): Boolean {
|
private fun onDownInPopup(e: MotionEvent): Boolean {
|
||||||
// Fix popup position when the user touch it, it may have the wrong one
|
// Fix popup position when the user touch it, it may have the wrong one
|
||||||
// because the soft input is visible (the draggable area is currently resized).
|
// because the soft input is visible (the draggable area is currently resized).
|
||||||
playerImpl.updateScreenSize()
|
player.updateScreenSize()
|
||||||
playerImpl.checkPopupPositionBounds()
|
player.checkPopupPositionBounds()
|
||||||
initialPopupX = playerImpl.popupLayoutParams.x
|
initialPopupX = player.popupLayoutParams!!.x
|
||||||
initialPopupY = playerImpl.popupLayoutParams.y
|
initialPopupY = player.popupLayoutParams!!.y
|
||||||
playerImpl.popupWidth = playerImpl.popupLayoutParams.width.toFloat()
|
|
||||||
playerImpl.popupHeight = playerImpl.popupLayoutParams.height.toFloat()
|
|
||||||
return super.onDown(e)
|
return super.onDown(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,15 +249,15 @@ abstract class BasePlayerGestureListener(
|
||||||
if (isDoubleTapping)
|
if (isDoubleTapping)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
if (playerImpl.popupPlayerSelected()) {
|
if (player.popupPlayerSelected()) {
|
||||||
if (playerImpl.player == null)
|
if (player.exoPlayerIsNull())
|
||||||
return false
|
return false
|
||||||
|
|
||||||
onSingleTap(MainPlayer.PlayerType.POPUP)
|
onSingleTap(MainPlayer.PlayerType.POPUP)
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
super.onSingleTapConfirmed(e)
|
super.onSingleTapConfirmed(e)
|
||||||
if (playerImpl.currentState == BasePlayer.STATE_BLOCKED)
|
if (player.currentState == Player.STATE_BLOCKED)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
onSingleTap(MainPlayer.PlayerType.VIDEO)
|
onSingleTap(MainPlayer.PlayerType.VIDEO)
|
||||||
|
@ -272,10 +266,10 @@ abstract class BasePlayerGestureListener(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLongPress(e: MotionEvent?) {
|
override fun onLongPress(e: MotionEvent?) {
|
||||||
if (playerImpl.popupPlayerSelected()) {
|
if (player.popupPlayerSelected()) {
|
||||||
playerImpl.updateScreenSize()
|
player.updateScreenSize()
|
||||||
playerImpl.checkPopupPositionBounds()
|
player.checkPopupPositionBounds()
|
||||||
playerImpl.updatePopupSize(playerImpl.screenWidth.toInt(), -1)
|
player.changePopupSize(player.screenWidth.toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +279,7 @@ abstract class BasePlayerGestureListener(
|
||||||
distanceX: Float,
|
distanceX: Float,
|
||||||
distanceY: Float
|
distanceY: Float
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return if (playerImpl.popupPlayerSelected()) {
|
return if (player.popupPlayerSelected()) {
|
||||||
onScrollInPopup(initialEvent, movingEvent, distanceX, distanceY)
|
onScrollInPopup(initialEvent, movingEvent, distanceX, distanceY)
|
||||||
} else {
|
} else {
|
||||||
onScrollInMain(initialEvent, movingEvent, distanceX, distanceY)
|
onScrollInMain(initialEvent, movingEvent, distanceX, distanceY)
|
||||||
|
@ -298,19 +292,18 @@ abstract class BasePlayerGestureListener(
|
||||||
velocityX: Float,
|
velocityX: Float,
|
||||||
velocityY: Float
|
velocityY: Float
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return if (playerImpl.popupPlayerSelected()) {
|
return if (player.popupPlayerSelected()) {
|
||||||
val absVelocityX = abs(velocityX)
|
val absVelocityX = abs(velocityX)
|
||||||
val absVelocityY = abs(velocityY)
|
val absVelocityY = abs(velocityY)
|
||||||
if (absVelocityX.coerceAtLeast(absVelocityY) > tossFlingVelocity) {
|
if (absVelocityX.coerceAtLeast(absVelocityY) > tossFlingVelocity) {
|
||||||
if (absVelocityX > tossFlingVelocity) {
|
if (absVelocityX > tossFlingVelocity) {
|
||||||
playerImpl.popupLayoutParams.x = velocityX.toInt()
|
player.popupLayoutParams!!.x = velocityX.toInt()
|
||||||
}
|
}
|
||||||
if (absVelocityY > tossFlingVelocity) {
|
if (absVelocityY > tossFlingVelocity) {
|
||||||
playerImpl.popupLayoutParams.y = velocityY.toInt()
|
player.popupLayoutParams!!.y = velocityY.toInt()
|
||||||
}
|
}
|
||||||
playerImpl.checkPopupPositionBounds()
|
player.checkPopupPositionBounds()
|
||||||
playerImpl.windowManager
|
player.windowManager!!.updateViewLayout(player.rootView, player.popupLayoutParams)
|
||||||
.updateViewLayout(playerImpl.rootView, playerImpl.popupLayoutParams)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
@ -326,13 +319,13 @@ abstract class BasePlayerGestureListener(
|
||||||
distanceY: Float
|
distanceY: Float
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
|
||||||
if (!playerImpl.isFullscreen) {
|
if (!player.isFullscreen) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val isTouchingStatusBar: Boolean = initialEvent.y < getStatusBarHeight(service)
|
val isTouchingStatusBar: Boolean = initialEvent.y < getStatusBarHeight(service)
|
||||||
val isTouchingNavigationBar: Boolean =
|
val isTouchingNavigationBar: Boolean =
|
||||||
initialEvent.y > (playerImpl.rootView.height - getNavigationBarHeight(service))
|
initialEvent.y > (player.rootView.height - getNavigationBarHeight(service))
|
||||||
if (isTouchingStatusBar || isTouchingNavigationBar) {
|
if (isTouchingStatusBar || isTouchingNavigationBar) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -340,7 +333,7 @@ abstract class BasePlayerGestureListener(
|
||||||
val insideThreshold = abs(movingEvent.y - initialEvent.y) <= MOVEMENT_THRESHOLD
|
val insideThreshold = abs(movingEvent.y - initialEvent.y) <= MOVEMENT_THRESHOLD
|
||||||
if (
|
if (
|
||||||
!isMovingInMain && (insideThreshold || abs(distanceX) > abs(distanceY)) ||
|
!isMovingInMain && (insideThreshold || abs(distanceX) > abs(distanceY)) ||
|
||||||
playerImpl.currentState == BasePlayer.STATE_COMPLETED
|
player.currentState == Player.STATE_COMPLETED
|
||||||
) {
|
) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -371,7 +364,7 @@ abstract class BasePlayerGestureListener(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMovingInPopup) {
|
if (!isMovingInPopup) {
|
||||||
AnimationUtils.animateView(playerImpl.closeButton, true, 200)
|
AnimationUtils.animateView(player.closeOverlayButton, true, 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
isMovingInPopup = true
|
isMovingInPopup = true
|
||||||
|
@ -381,20 +374,20 @@ abstract class BasePlayerGestureListener(
|
||||||
val diffY: Float = (movingEvent.rawY - initialEvent.rawY)
|
val diffY: Float = (movingEvent.rawY - initialEvent.rawY)
|
||||||
var posY: Float = (initialPopupY + diffY)
|
var posY: Float = (initialPopupY + diffY)
|
||||||
|
|
||||||
if (posX > playerImpl.screenWidth - playerImpl.popupWidth) {
|
if (posX > player.screenWidth - player.popupLayoutParams!!.width) {
|
||||||
posX = (playerImpl.screenWidth - playerImpl.popupWidth)
|
posX = (player.screenWidth - player.popupLayoutParams!!.width)
|
||||||
} else if (posX < 0) {
|
} else if (posX < 0) {
|
||||||
posX = 0f
|
posX = 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
if (posY > playerImpl.screenHeight - playerImpl.popupHeight) {
|
if (posY > player.screenHeight - player.popupLayoutParams!!.height) {
|
||||||
posY = (playerImpl.screenHeight - playerImpl.popupHeight)
|
posY = (player.screenHeight - player.popupLayoutParams!!.height)
|
||||||
} else if (posY < 0) {
|
} else if (posY < 0) {
|
||||||
posY = 0f
|
posY = 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
playerImpl.popupLayoutParams.x = posX.toInt()
|
player.popupLayoutParams!!.x = posX.toInt()
|
||||||
playerImpl.popupLayoutParams.y = posY.toInt()
|
player.popupLayoutParams!!.y = posY.toInt()
|
||||||
|
|
||||||
onScroll(
|
onScroll(
|
||||||
MainPlayer.PlayerType.POPUP,
|
MainPlayer.PlayerType.POPUP,
|
||||||
|
@ -405,8 +398,7 @@ abstract class BasePlayerGestureListener(
|
||||||
distanceY
|
distanceY
|
||||||
)
|
)
|
||||||
|
|
||||||
playerImpl.windowManager
|
player.windowManager!!.updateViewLayout(player.rootView, player.popupLayoutParams)
|
||||||
.updateViewLayout(playerImpl.rootView, playerImpl.popupLayoutParams)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,16 +466,16 @@ abstract class BasePlayerGestureListener(
|
||||||
// ///////////////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private fun getDisplayPortion(e: MotionEvent): DisplayPortion {
|
private fun getDisplayPortion(e: MotionEvent): DisplayPortion {
|
||||||
return if (playerImpl.playerType == MainPlayer.PlayerType.POPUP) {
|
return if (player.playerType == MainPlayer.PlayerType.POPUP) {
|
||||||
when {
|
when {
|
||||||
e.x < playerImpl.popupWidth / 3.0 -> DisplayPortion.LEFT
|
e.x < player.popupLayoutParams!!.width / 3.0 -> DisplayPortion.LEFT
|
||||||
e.x > playerImpl.popupWidth * 2.0 / 3.0 -> DisplayPortion.RIGHT
|
e.x > player.popupLayoutParams!!.width * 2.0 / 3.0 -> DisplayPortion.RIGHT
|
||||||
else -> DisplayPortion.MIDDLE
|
else -> DisplayPortion.MIDDLE
|
||||||
}
|
}
|
||||||
} else /* MainPlayer.PlayerType.VIDEO */ {
|
} else /* MainPlayer.PlayerType.VIDEO */ {
|
||||||
when {
|
when {
|
||||||
e.x < playerImpl.rootView.width / 3.0 -> DisplayPortion.LEFT
|
e.x < player.rootView.width / 3.0 -> DisplayPortion.LEFT
|
||||||
e.x > playerImpl.rootView.width * 2.0 / 3.0 -> DisplayPortion.RIGHT
|
e.x > player.rootView.width * 2.0 / 3.0 -> DisplayPortion.RIGHT
|
||||||
else -> DisplayPortion.MIDDLE
|
else -> DisplayPortion.MIDDLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,14 +483,14 @@ abstract class BasePlayerGestureListener(
|
||||||
|
|
||||||
// Currently needed for scrolling since there is no action more the middle portion
|
// Currently needed for scrolling since there is no action more the middle portion
|
||||||
private fun getDisplayHalfPortion(e: MotionEvent): DisplayPortion {
|
private fun getDisplayHalfPortion(e: MotionEvent): DisplayPortion {
|
||||||
return if (playerImpl.playerType == MainPlayer.PlayerType.POPUP) {
|
return if (player.playerType == MainPlayer.PlayerType.POPUP) {
|
||||||
when {
|
when {
|
||||||
e.x < playerImpl.popupWidth / 2.0 -> DisplayPortion.LEFT_HALF
|
e.x < player.popupLayoutParams!!.width / 2.0 -> DisplayPortion.LEFT_HALF
|
||||||
else -> DisplayPortion.RIGHT_HALF
|
else -> DisplayPortion.RIGHT_HALF
|
||||||
}
|
}
|
||||||
} else /* MainPlayer.PlayerType.VIDEO */ {
|
} else /* MainPlayer.PlayerType.VIDEO */ {
|
||||||
when {
|
when {
|
||||||
e.x < playerImpl.rootView.width / 2.0 -> DisplayPortion.LEFT_HALF
|
e.x < player.rootView.width / 2.0 -> DisplayPortion.LEFT_HALF
|
||||||
else -> DisplayPortion.RIGHT_HALF
|
else -> DisplayPortion.RIGHT_HALF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,7 +514,7 @@ abstract class BasePlayerGestureListener(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "BasePlayerGestListener"
|
private const val TAG = "BasePlayerGestListener"
|
||||||
private val DEBUG = BasePlayer.DEBUG
|
private val DEBUG = Player.DEBUG
|
||||||
|
|
||||||
private const val DOUBLE_TAP_DELAY = 550L
|
private const val DOUBLE_TAP_DELAY = 550L
|
||||||
private const val MOVEMENT_THRESHOLD = 40
|
private const val MOVEMENT_THRESHOLD = 40
|
||||||
|
|
|
@ -11,15 +11,15 @@ import android.widget.ProgressBar;
|
||||||
import androidx.appcompat.content.res.AppCompatResources;
|
import androidx.appcompat.content.res.AppCompatResources;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.schabi.newpipe.MainActivity;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.player.BasePlayer;
|
|
||||||
import org.schabi.newpipe.player.MainPlayer;
|
import org.schabi.newpipe.player.MainPlayer;
|
||||||
import org.schabi.newpipe.player.VideoPlayerImpl;
|
import org.schabi.newpipe.player.Player;
|
||||||
import org.schabi.newpipe.player.helper.PlayerHelper;
|
import org.schabi.newpipe.player.helper.PlayerHelper;
|
||||||
|
|
||||||
import static org.schabi.newpipe.player.BasePlayer.STATE_PLAYING;
|
import static org.schabi.newpipe.player.Player.STATE_PLAYING;
|
||||||
import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_DURATION;
|
import static org.schabi.newpipe.player.Player.DEFAULT_CONTROLS_DURATION;
|
||||||
import static org.schabi.newpipe.player.VideoPlayer.DEFAULT_CONTROLS_HIDE_TIME;
|
import static org.schabi.newpipe.player.Player.DEFAULT_CONTROLS_HIDE_TIME;
|
||||||
import static org.schabi.newpipe.util.AnimationUtils.Type.SCALE_AND_ALPHA;
|
import static org.schabi.newpipe.util.AnimationUtils.Type.SCALE_AND_ALPHA;
|
||||||
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||||
|
|
||||||
|
@ -33,14 +33,14 @@ import static org.schabi.newpipe.util.AnimationUtils.animateView;
|
||||||
public class PlayerGestureListener
|
public class PlayerGestureListener
|
||||||
extends BasePlayerGestureListener
|
extends BasePlayerGestureListener
|
||||||
implements View.OnTouchListener {
|
implements View.OnTouchListener {
|
||||||
private static final String TAG = ".PlayerGestureListener";
|
private static final String TAG = PlayerGestureListener.class.getSimpleName();
|
||||||
private static final boolean DEBUG = BasePlayer.DEBUG;
|
private static final boolean DEBUG = MainActivity.DEBUG;
|
||||||
|
|
||||||
private final int maxVolume;
|
private final int maxVolume;
|
||||||
|
|
||||||
public PlayerGestureListener(final VideoPlayerImpl playerImpl, final MainPlayer service) {
|
public PlayerGestureListener(final Player player, final MainPlayer service) {
|
||||||
super(playerImpl, service);
|
super(player, service);
|
||||||
maxVolume = playerImpl.getAudioReactor().getMaxVolume();
|
maxVolume = player.getAudioReactor().getMaxVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,46 +48,44 @@ public class PlayerGestureListener
|
||||||
@NotNull final DisplayPortion portion) {
|
@NotNull final DisplayPortion portion) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onDoubleTap called with playerType = ["
|
Log.d(TAG, "onDoubleTap called with playerType = ["
|
||||||
+ playerImpl.getPlayerType() + "], portion = ["
|
+ player.getPlayerType() + "], portion = [" + portion + "]");
|
||||||
+ portion + "]");
|
|
||||||
}
|
}
|
||||||
if (playerImpl.isSomePopupMenuVisible()) {
|
if (player.isSomePopupMenuVisible()) {
|
||||||
playerImpl.hideControls(0, 0);
|
player.hideControls(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (portion == DisplayPortion.LEFT) {
|
if (portion == DisplayPortion.LEFT) {
|
||||||
playerImpl.onFastRewind();
|
player.fastRewind();
|
||||||
} else if (portion == DisplayPortion.MIDDLE) {
|
} else if (portion == DisplayPortion.MIDDLE) {
|
||||||
playerImpl.onPlayPause();
|
player.playPause();
|
||||||
} else if (portion == DisplayPortion.RIGHT) {
|
} else if (portion == DisplayPortion.RIGHT) {
|
||||||
playerImpl.onFastForward();
|
player.fastForward();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSingleTap(@NotNull final MainPlayer.PlayerType playerType) {
|
public void onSingleTap(@NotNull final MainPlayer.PlayerType playerType) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onSingleTap called with playerType = ["
|
Log.d(TAG, "onSingleTap called with playerType = [" + player.getPlayerType() + "]");
|
||||||
+ playerImpl.getPlayerType() + "]");
|
|
||||||
}
|
}
|
||||||
if (playerType == MainPlayer.PlayerType.POPUP) {
|
if (playerType == MainPlayer.PlayerType.POPUP) {
|
||||||
|
|
||||||
if (playerImpl.isControlsVisible()) {
|
if (player.isControlsVisible()) {
|
||||||
playerImpl.hideControls(100, 100);
|
player.hideControls(100, 100);
|
||||||
} else {
|
} else {
|
||||||
playerImpl.getPlayPauseButton().requestFocus();
|
player.getPlayPauseButton().requestFocus();
|
||||||
playerImpl.showControlsThenHide();
|
player.showControlsThenHide();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else /* playerType == MainPlayer.PlayerType.VIDEO */ {
|
} else /* playerType == MainPlayer.PlayerType.VIDEO */ {
|
||||||
|
|
||||||
if (playerImpl.isControlsVisible()) {
|
if (player.isControlsVisible()) {
|
||||||
playerImpl.hideControls(150, 0);
|
player.hideControls(150, 0);
|
||||||
} else {
|
} else {
|
||||||
if (playerImpl.getCurrentState() == BasePlayer.STATE_COMPLETED) {
|
if (player.getCurrentState() == Player.STATE_COMPLETED) {
|
||||||
playerImpl.showControls(0);
|
player.showControls(0);
|
||||||
} else {
|
} else {
|
||||||
playerImpl.showControlsThenHide();
|
player.showControlsThenHide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,8 +99,7 @@ public class PlayerGestureListener
|
||||||
final float distanceX, final float distanceY) {
|
final float distanceX, final float distanceY) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onScroll called with playerType = ["
|
Log.d(TAG, "onScroll called with playerType = ["
|
||||||
+ playerImpl.getPlayerType() + "], portion = ["
|
+ player.getPlayerType() + "], portion = [" + portion + "]");
|
||||||
+ portion + "]");
|
|
||||||
}
|
}
|
||||||
if (playerType == MainPlayer.PlayerType.VIDEO) {
|
if (playerType == MainPlayer.PlayerType.VIDEO) {
|
||||||
final boolean isBrightnessGestureEnabled =
|
final boolean isBrightnessGestureEnabled =
|
||||||
|
@ -123,8 +120,8 @@ public class PlayerGestureListener
|
||||||
}
|
}
|
||||||
|
|
||||||
} else /* MainPlayer.PlayerType.POPUP */ {
|
} else /* MainPlayer.PlayerType.POPUP */ {
|
||||||
final View closingOverlayView = playerImpl.getClosingOverlay();
|
final View closingOverlayView = player.getClosingOverlayView();
|
||||||
if (playerImpl.isInsideClosingRadius(movingEvent)) {
|
if (player.isInsideClosingRadius(movingEvent)) {
|
||||||
if (closingOverlayView.getVisibility() == View.GONE) {
|
if (closingOverlayView.getVisibility() == View.GONE) {
|
||||||
animateView(closingOverlayView, true, 250);
|
animateView(closingOverlayView, true, 250);
|
||||||
}
|
}
|
||||||
|
@ -137,17 +134,17 @@ public class PlayerGestureListener
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onScrollMainVolume(final float distanceX, final float distanceY) {
|
private void onScrollMainVolume(final float distanceX, final float distanceY) {
|
||||||
playerImpl.getVolumeProgressBar().incrementProgressBy((int) distanceY);
|
player.getVolumeProgressBar().incrementProgressBy((int) distanceY);
|
||||||
final float currentProgressPercent = (float) playerImpl
|
final float currentProgressPercent = (float) player
|
||||||
.getVolumeProgressBar().getProgress() / playerImpl.getMaxGestureLength();
|
.getVolumeProgressBar().getProgress() / player.getMaxGestureLength();
|
||||||
final int currentVolume = (int) (maxVolume * currentProgressPercent);
|
final int currentVolume = (int) (maxVolume * currentProgressPercent);
|
||||||
playerImpl.getAudioReactor().setVolume(currentVolume);
|
player.getAudioReactor().setVolume(currentVolume);
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onScroll().volumeControl, currentVolume = " + currentVolume);
|
Log.d(TAG, "onScroll().volumeControl, currentVolume = " + currentVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerImpl.getVolumeImageView().setImageDrawable(
|
player.getVolumeImageView().setImageDrawable(
|
||||||
AppCompatResources.getDrawable(service, currentProgressPercent <= 0
|
AppCompatResources.getDrawable(service, currentProgressPercent <= 0
|
||||||
? R.drawable.ic_volume_off_white_24dp
|
? R.drawable.ic_volume_off_white_24dp
|
||||||
: currentProgressPercent < 0.25 ? R.drawable.ic_volume_mute_white_24dp
|
: currentProgressPercent < 0.25 ? R.drawable.ic_volume_mute_white_24dp
|
||||||
|
@ -155,23 +152,23 @@ public class PlayerGestureListener
|
||||||
: R.drawable.ic_volume_up_white_24dp)
|
: R.drawable.ic_volume_up_white_24dp)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (playerImpl.getVolumeRelativeLayout().getVisibility() != View.VISIBLE) {
|
if (player.getVolumeRelativeLayout().getVisibility() != View.VISIBLE) {
|
||||||
animateView(playerImpl.getVolumeRelativeLayout(), SCALE_AND_ALPHA, true, 200);
|
animateView(player.getVolumeRelativeLayout(), SCALE_AND_ALPHA, true, 200);
|
||||||
}
|
}
|
||||||
if (playerImpl.getBrightnessRelativeLayout().getVisibility() == View.VISIBLE) {
|
if (player.getBrightnessRelativeLayout().getVisibility() == View.VISIBLE) {
|
||||||
playerImpl.getBrightnessRelativeLayout().setVisibility(View.GONE);
|
player.getBrightnessRelativeLayout().setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onScrollMainBrightness(final float distanceX, final float distanceY) {
|
private void onScrollMainBrightness(final float distanceX, final float distanceY) {
|
||||||
final Activity parent = playerImpl.getParentActivity();
|
final Activity parent = player.getParentActivity();
|
||||||
if (parent == null) {
|
if (parent == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Window window = parent.getWindow();
|
final Window window = parent.getWindow();
|
||||||
final WindowManager.LayoutParams layoutParams = window.getAttributes();
|
final WindowManager.LayoutParams layoutParams = window.getAttributes();
|
||||||
final ProgressBar bar = playerImpl.getBrightnessProgressBar();
|
final ProgressBar bar = player.getBrightnessProgressBar();
|
||||||
final float oldBrightness = layoutParams.screenBrightness;
|
final float oldBrightness = layoutParams.screenBrightness;
|
||||||
bar.setProgress((int) (bar.getMax() * Math.max(0, Math.min(1, oldBrightness))));
|
bar.setProgress((int) (bar.getMax() * Math.max(0, Math.min(1, oldBrightness))));
|
||||||
bar.incrementProgressBy((int) distanceY);
|
bar.incrementProgressBy((int) distanceY);
|
||||||
|
@ -188,7 +185,7 @@ public class PlayerGestureListener
|
||||||
+ "currentBrightness = " + currentProgressPercent);
|
+ "currentBrightness = " + currentProgressPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerImpl.getBrightnessImageView().setImageDrawable(
|
player.getBrightnessImageView().setImageDrawable(
|
||||||
AppCompatResources.getDrawable(service,
|
AppCompatResources.getDrawable(service,
|
||||||
currentProgressPercent < 0.25
|
currentProgressPercent < 0.25
|
||||||
? R.drawable.ic_brightness_low_white_24dp
|
? R.drawable.ic_brightness_low_white_24dp
|
||||||
|
@ -197,11 +194,11 @@ public class PlayerGestureListener
|
||||||
: R.drawable.ic_brightness_high_white_24dp)
|
: R.drawable.ic_brightness_high_white_24dp)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (playerImpl.getBrightnessRelativeLayout().getVisibility() != View.VISIBLE) {
|
if (player.getBrightnessRelativeLayout().getVisibility() != View.VISIBLE) {
|
||||||
animateView(playerImpl.getBrightnessRelativeLayout(), SCALE_AND_ALPHA, true, 200);
|
animateView(player.getBrightnessRelativeLayout(), SCALE_AND_ALPHA, true, 200);
|
||||||
}
|
}
|
||||||
if (playerImpl.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) {
|
if (player.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) {
|
||||||
playerImpl.getVolumeRelativeLayout().setVisibility(View.GONE);
|
player.getVolumeRelativeLayout().setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,40 +207,40 @@ public class PlayerGestureListener
|
||||||
@NotNull final MotionEvent event) {
|
@NotNull final MotionEvent event) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onScrollEnd called with playerType = ["
|
Log.d(TAG, "onScrollEnd called with playerType = ["
|
||||||
+ playerImpl.getPlayerType() + "]");
|
+ player.getPlayerType() + "]");
|
||||||
}
|
}
|
||||||
if (playerType == MainPlayer.PlayerType.VIDEO) {
|
if (playerType == MainPlayer.PlayerType.VIDEO) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onScrollEnd() called");
|
Log.d(TAG, "onScrollEnd() called");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerImpl.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) {
|
if (player.getVolumeRelativeLayout().getVisibility() == View.VISIBLE) {
|
||||||
animateView(playerImpl.getVolumeRelativeLayout(), SCALE_AND_ALPHA,
|
animateView(player.getVolumeRelativeLayout(), SCALE_AND_ALPHA,
|
||||||
false, 200, 200);
|
false, 200, 200);
|
||||||
}
|
}
|
||||||
if (playerImpl.getBrightnessRelativeLayout().getVisibility() == View.VISIBLE) {
|
if (player.getBrightnessRelativeLayout().getVisibility() == View.VISIBLE) {
|
||||||
animateView(playerImpl.getBrightnessRelativeLayout(), SCALE_AND_ALPHA,
|
animateView(player.getBrightnessRelativeLayout(), SCALE_AND_ALPHA,
|
||||||
false, 200, 200);
|
false, 200, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) {
|
if (player.isControlsVisible() && player.getCurrentState() == STATE_PLAYING) {
|
||||||
playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
player.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (playerImpl == null) {
|
if (player == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (playerImpl.isControlsVisible() && playerImpl.getCurrentState() == STATE_PLAYING) {
|
if (player.isControlsVisible() && player.getCurrentState() == STATE_PLAYING) {
|
||||||
playerImpl.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
player.hideControls(DEFAULT_CONTROLS_DURATION, DEFAULT_CONTROLS_HIDE_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerImpl.isInsideClosingRadius(event)) {
|
if (player.isInsideClosingRadius(event)) {
|
||||||
playerImpl.closePopup();
|
player.closePopup();
|
||||||
} else {
|
} else {
|
||||||
animateView(playerImpl.getClosingOverlay(), false, 0);
|
animateView(player.getClosingOverlayView(), false, 0);
|
||||||
|
|
||||||
if (!playerImpl.isPopupClosing) {
|
if (!player.isPopupClosing()) {
|
||||||
animateView(playerImpl.getCloseButton(), false, 200);
|
animateView(player.getCloseOverlayButton(), false, 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,12 +251,12 @@ public class PlayerGestureListener
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onPopupResizingStart called");
|
Log.d(TAG, "onPopupResizingStart called");
|
||||||
}
|
}
|
||||||
playerImpl.showAndAnimateControl(-1, true);
|
player.showAndAnimateControl(-1, true);
|
||||||
playerImpl.getLoadingPanel().setVisibility(View.GONE);
|
player.getLoadingPanel().setVisibility(View.GONE);
|
||||||
|
|
||||||
playerImpl.hideControls(0, 0);
|
player.hideControls(0, 0);
|
||||||
animateView(playerImpl.getCurrentDisplaySeek(), false, 0, 0);
|
animateView(player.getCurrentDisplaySeek(), false, 0, 0);
|
||||||
animateView(playerImpl.getResizingIndicator(), true, 200, 0);
|
animateView(player.getResizingIndicator(), true, 200, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -267,7 +264,7 @@ public class PlayerGestureListener
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "onPopupResizingEnd called");
|
Log.d(TAG, "onPopupResizingEnd called");
|
||||||
}
|
}
|
||||||
animateView(playerImpl.getResizingIndicator(), false, 100, 0);
|
animateView(player.getResizingIndicator(), false, 100, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package org.schabi.newpipe.player.event;
|
package org.schabi.newpipe.player.event;
|
||||||
|
|
||||||
import org.schabi.newpipe.player.MainPlayer;
|
import org.schabi.newpipe.player.MainPlayer;
|
||||||
import org.schabi.newpipe.player.VideoPlayerImpl;
|
import org.schabi.newpipe.player.Player;
|
||||||
|
|
||||||
public interface PlayerServiceExtendedEventListener extends PlayerServiceEventListener {
|
public interface PlayerServiceExtendedEventListener extends PlayerServiceEventListener {
|
||||||
void onServiceConnected(VideoPlayerImpl player,
|
void onServiceConnected(Player player,
|
||||||
MainPlayer playerService,
|
MainPlayer playerService,
|
||||||
boolean playAfterConnect);
|
boolean playAfterConnect);
|
||||||
void onServiceDisconnected();
|
void onServiceDisconnected();
|
||||||
|
|
|
@ -18,7 +18,7 @@ import androidx.fragment.app.DialogFragment;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.util.SliderStrategy;
|
import org.schabi.newpipe.util.SliderStrategy;
|
||||||
|
|
||||||
import static org.schabi.newpipe.player.BasePlayer.DEBUG;
|
import static org.schabi.newpipe.player.Player.DEBUG;
|
||||||
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
||||||
|
|
||||||
public class PlaybackParameterDialog extends DialogFragment {
|
public class PlaybackParameterDialog extends DialogFragment {
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
package org.schabi.newpipe.player.helper;
|
package org.schabi.newpipe.player.helper;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.os.Build;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.accessibility.CaptioningManager;
|
import android.view.accessibility.CaptioningManager;
|
||||||
|
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
|
@ -11,11 +18,14 @@ import androidx.annotation.Nullable;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
|
import com.google.android.exoplayer2.Player.RepeatMode;
|
||||||
import com.google.android.exoplayer2.SeekParameters;
|
import com.google.android.exoplayer2.SeekParameters;
|
||||||
import com.google.android.exoplayer2.text.CaptionStyleCompat;
|
import com.google.android.exoplayer2.text.CaptionStyleCompat;
|
||||||
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
|
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
|
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
|
||||||
|
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
|
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
@ -27,6 +37,8 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
||||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||||
import org.schabi.newpipe.extractor.utils.Utils;
|
import org.schabi.newpipe.extractor.utils.Utils;
|
||||||
|
import org.schabi.newpipe.player.MainPlayer;
|
||||||
|
import org.schabi.newpipe.player.Player;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
||||||
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
|
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
|
||||||
|
@ -41,13 +53,16 @@ import java.util.Formatter;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_FILL;
|
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
|
||||||
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_FIT;
|
import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF;
|
||||||
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_ZOOM;
|
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
|
||||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||||
|
import static org.schabi.newpipe.player.Player.IDLE_WINDOW_FLAGS;
|
||||||
|
import static org.schabi.newpipe.player.Player.PLAYER_TYPE;
|
||||||
import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_ALWAYS;
|
import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_ALWAYS;
|
||||||
import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_NEVER;
|
import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_NEVER;
|
||||||
import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_WIFI;
|
import static org.schabi.newpipe.player.helper.PlayerHelper.AutoplayType.AUTOPLAY_TYPE_WIFI;
|
||||||
|
@ -71,6 +86,15 @@ public final class PlayerHelper {
|
||||||
int AUTOPLAY_TYPE_NEVER = 2;
|
int AUTOPLAY_TYPE_NEVER = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Retention(SOURCE)
|
||||||
|
@IntDef({MINIMIZE_ON_EXIT_MODE_NONE, MINIMIZE_ON_EXIT_MODE_BACKGROUND,
|
||||||
|
MINIMIZE_ON_EXIT_MODE_POPUP})
|
||||||
|
public @interface MinimizeMode {
|
||||||
|
int MINIMIZE_ON_EXIT_MODE_NONE = 0;
|
||||||
|
int MINIMIZE_ON_EXIT_MODE_BACKGROUND = 1;
|
||||||
|
int MINIMIZE_ON_EXIT_MODE_POPUP = 2;
|
||||||
|
}
|
||||||
|
|
||||||
private PlayerHelper() { }
|
private PlayerHelper() { }
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -121,14 +145,16 @@ public final class PlayerHelper {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static String resizeTypeOf(@NonNull final Context context,
|
public static String resizeTypeOf(@NonNull final Context context,
|
||||||
@AspectRatioFrameLayout.ResizeMode final int resizeMode) {
|
@ResizeMode final int resizeMode) {
|
||||||
switch (resizeMode) {
|
switch (resizeMode) {
|
||||||
case RESIZE_MODE_FIT:
|
case AspectRatioFrameLayout.RESIZE_MODE_FIT:
|
||||||
return context.getResources().getString(R.string.resize_fit);
|
return context.getResources().getString(R.string.resize_fit);
|
||||||
case RESIZE_MODE_FILL:
|
case AspectRatioFrameLayout.RESIZE_MODE_FILL:
|
||||||
return context.getResources().getString(R.string.resize_fill);
|
return context.getResources().getString(R.string.resize_fill);
|
||||||
case RESIZE_MODE_ZOOM:
|
case AspectRatioFrameLayout.RESIZE_MODE_ZOOM:
|
||||||
return context.getResources().getString(R.string.resize_zoom);
|
return context.getResources().getString(R.string.resize_zoom);
|
||||||
|
case AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT:
|
||||||
|
case AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH:
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unrecognized resize mode: " + resizeMode);
|
throw new IllegalArgumentException("Unrecognized resize mode: " + resizeMode);
|
||||||
}
|
}
|
||||||
|
@ -199,23 +225,23 @@ public final class PlayerHelper {
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public static boolean isResumeAfterAudioFocusGain(@NonNull final Context context) {
|
public static boolean isResumeAfterAudioFocusGain(@NonNull final Context context) {
|
||||||
return isResumeAfterAudioFocusGain(context, false);
|
return getPreferences(context)
|
||||||
|
.getBoolean(context.getString(R.string.resume_on_audio_focus_gain_key), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isVolumeGestureEnabled(@NonNull final Context context) {
|
public static boolean isVolumeGestureEnabled(@NonNull final Context context) {
|
||||||
return isVolumeGestureEnabled(context, true);
|
return getPreferences(context)
|
||||||
|
.getBoolean(context.getString(R.string.volume_gesture_control_key), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isBrightnessGestureEnabled(@NonNull final Context context) {
|
public static boolean isBrightnessGestureEnabled(@NonNull final Context context) {
|
||||||
return isBrightnessGestureEnabled(context, true);
|
return getPreferences(context)
|
||||||
}
|
.getBoolean(context.getString(R.string.brightness_gesture_control_key), true);
|
||||||
|
|
||||||
public static boolean isRememberingPopupDimensions(@NonNull final Context context) {
|
|
||||||
return isRememberingPopupDimensions(context, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAutoQueueEnabled(@NonNull final Context context) {
|
public static boolean isAutoQueueEnabled(@NonNull final Context context) {
|
||||||
return isAutoQueueEnabled(context, false);
|
return getPreferences(context)
|
||||||
|
.getBoolean(context.getString(R.string.auto_queue_key), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isClearingQueueConfirmationRequired(@NonNull final Context context) {
|
public static boolean isClearingQueueConfirmationRequired(@NonNull final Context context) {
|
||||||
|
@ -229,7 +255,8 @@ public final class PlayerHelper {
|
||||||
final String popupAction = context.getString(R.string.minimize_on_exit_popup_key);
|
final String popupAction = context.getString(R.string.minimize_on_exit_popup_key);
|
||||||
final String backgroundAction = context.getString(R.string.minimize_on_exit_background_key);
|
final String backgroundAction = context.getString(R.string.minimize_on_exit_background_key);
|
||||||
|
|
||||||
final String action = getMinimizeOnExitAction(context, defaultAction);
|
final String action = getPreferences(context)
|
||||||
|
.getString(context.getString(R.string.minimize_on_exit_key), defaultAction);
|
||||||
if (action.equals(popupAction)) {
|
if (action.equals(popupAction)) {
|
||||||
return MINIMIZE_ON_EXIT_MODE_POPUP;
|
return MINIMIZE_ON_EXIT_MODE_POPUP;
|
||||||
} else if (action.equals(backgroundAction)) {
|
} else if (action.equals(backgroundAction)) {
|
||||||
|
@ -239,9 +266,23 @@ public final class PlayerHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isMinimizeOnExitToPopup(@NonNull final Context context) {
|
||||||
|
return getMinimizeOnExitAction(context) == MINIMIZE_ON_EXIT_MODE_POPUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMinimizeOnExitToBackground(@NonNull final Context context) {
|
||||||
|
return getMinimizeOnExitAction(context) == MINIMIZE_ON_EXIT_MODE_BACKGROUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMinimizeOnExitDisabled(@NonNull final Context context) {
|
||||||
|
return getMinimizeOnExitAction(context) == MINIMIZE_ON_EXIT_MODE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
@AutoplayType
|
@AutoplayType
|
||||||
public static int getAutoplayType(@NonNull final Context context) {
|
public static int getAutoplayType(@NonNull final Context context) {
|
||||||
final String type = getAutoplayType(context, context.getString(R.string.autoplay_wifi_key));
|
final String type = getPreferences(context).getString(
|
||||||
|
context.getString(R.string.autoplay_key),
|
||||||
|
context.getString(R.string.autoplay_wifi_key));
|
||||||
if (type.equals(context.getString(R.string.autoplay_always_key))) {
|
if (type.equals(context.getString(R.string.autoplay_always_key))) {
|
||||||
return AUTOPLAY_TYPE_ALWAYS;
|
return AUTOPLAY_TYPE_ALWAYS;
|
||||||
} else if (type.equals(context.getString(R.string.autoplay_never_key))) {
|
} else if (type.equals(context.getString(R.string.autoplay_never_key))) {
|
||||||
|
@ -350,14 +391,32 @@ public final class PlayerHelper {
|
||||||
return captioningManager.getFontScale();
|
return captioningManager.getFontScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context the Android context
|
||||||
|
* @return the screen brightness to use. A value less than 0 (the default) means to use the
|
||||||
|
* preferred screen brightness
|
||||||
|
*/
|
||||||
public static float getScreenBrightness(@NonNull final Context context) {
|
public static float getScreenBrightness(@NonNull final Context context) {
|
||||||
//a value of less than 0, the default, means to use the preferred screen brightness
|
final SharedPreferences sp = getPreferences(context);
|
||||||
return getScreenBrightness(context, -1);
|
final long timestamp =
|
||||||
|
sp.getLong(context.getString(R.string.screen_brightness_timestamp_key), 0);
|
||||||
|
// Hypothesis: 4h covers a viewing block, e.g. evening.
|
||||||
|
// External lightning conditions will change in the next
|
||||||
|
// viewing block so we fall back to the default brightness
|
||||||
|
if ((System.currentTimeMillis() - timestamp) > TimeUnit.HOURS.toMillis(4)) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return sp.getFloat(context.getString(R.string.screen_brightness_key), -1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setScreenBrightness(@NonNull final Context context,
|
public static void setScreenBrightness(@NonNull final Context context,
|
||||||
final float setScreenBrightness) {
|
final float screenBrightness) {
|
||||||
setScreenBrightness(context, setScreenBrightness, System.currentTimeMillis());
|
getPreferences(context).edit()
|
||||||
|
.putFloat(context.getString(R.string.screen_brightness_key), screenBrightness)
|
||||||
|
.putLong(context.getString(R.string.screen_brightness_timestamp_key),
|
||||||
|
System.currentTimeMillis())
|
||||||
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean globalScreenOrientationLocked(final Context context) {
|
public static boolean globalScreenOrientationLocked(final Context context) {
|
||||||
|
@ -376,75 +435,11 @@ public final class PlayerHelper {
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context);
|
return PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isResumeAfterAudioFocusGain(@NonNull final Context context,
|
|
||||||
final boolean b) {
|
|
||||||
return getPreferences(context)
|
|
||||||
.getBoolean(context.getString(R.string.resume_on_audio_focus_gain_key), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isVolumeGestureEnabled(@NonNull final Context context,
|
|
||||||
final boolean b) {
|
|
||||||
return getPreferences(context)
|
|
||||||
.getBoolean(context.getString(R.string.volume_gesture_control_key), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isBrightnessGestureEnabled(@NonNull final Context context,
|
|
||||||
final boolean b) {
|
|
||||||
return getPreferences(context)
|
|
||||||
.getBoolean(context.getString(R.string.brightness_gesture_control_key), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isRememberingPopupDimensions(@NonNull final Context context,
|
|
||||||
final boolean b) {
|
|
||||||
return getPreferences(context)
|
|
||||||
.getBoolean(context.getString(R.string.popup_remember_size_pos_key), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isUsingInexactSeek(@NonNull final Context context) {
|
private static boolean isUsingInexactSeek(@NonNull final Context context) {
|
||||||
return getPreferences(context)
|
return getPreferences(context)
|
||||||
.getBoolean(context.getString(R.string.use_inexact_seek_key), false);
|
.getBoolean(context.getString(R.string.use_inexact_seek_key), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isAutoQueueEnabled(@NonNull final Context context, final boolean b) {
|
|
||||||
return getPreferences(context).getBoolean(context.getString(R.string.auto_queue_key), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setScreenBrightness(@NonNull final Context context,
|
|
||||||
final float screenBrightness, final long timestamp) {
|
|
||||||
final SharedPreferences.Editor editor = getPreferences(context).edit();
|
|
||||||
editor.putFloat(context.getString(R.string.screen_brightness_key), screenBrightness);
|
|
||||||
editor.putLong(context.getString(R.string.screen_brightness_timestamp_key), timestamp);
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float getScreenBrightness(@NonNull final Context context,
|
|
||||||
final float screenBrightness) {
|
|
||||||
final SharedPreferences sp = getPreferences(context);
|
|
||||||
final long timestamp = sp
|
|
||||||
.getLong(context.getString(R.string.screen_brightness_timestamp_key), 0);
|
|
||||||
// Hypothesis: 4h covers a viewing block, e.g. evening.
|
|
||||||
// External lightning conditions will change in the next
|
|
||||||
// viewing block so we fall back to the default brightness
|
|
||||||
if ((System.currentTimeMillis() - timestamp) > TimeUnit.HOURS.toMillis(4)) {
|
|
||||||
return screenBrightness;
|
|
||||||
} else {
|
|
||||||
return sp
|
|
||||||
.getFloat(context.getString(R.string.screen_brightness_key), screenBrightness);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getMinimizeOnExitAction(@NonNull final Context context,
|
|
||||||
final String key) {
|
|
||||||
return getPreferences(context)
|
|
||||||
.getString(context.getString(R.string.minimize_on_exit_key), key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getAutoplayType(@NonNull final Context context,
|
|
||||||
final String key) {
|
|
||||||
return getPreferences(context).getString(context.getString(R.string.autoplay_key),
|
|
||||||
key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SinglePlayQueue getAutoQueuedSinglePlayQueue(
|
private static SinglePlayQueue getAutoQueuedSinglePlayQueue(
|
||||||
final StreamInfoItem streamInfoItem) {
|
final StreamInfoItem streamInfoItem) {
|
||||||
final SinglePlayQueue singlePlayQueue = new SinglePlayQueue(streamInfoItem);
|
final SinglePlayQueue singlePlayQueue = new SinglePlayQueue(streamInfoItem);
|
||||||
|
@ -452,12 +447,168 @@ public final class PlayerHelper {
|
||||||
return singlePlayQueue;
|
return singlePlayQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(SOURCE)
|
|
||||||
@IntDef({MINIMIZE_ON_EXIT_MODE_NONE, MINIMIZE_ON_EXIT_MODE_BACKGROUND,
|
////////////////////////////////////////////////////////////////////////////
|
||||||
MINIMIZE_ON_EXIT_MODE_POPUP})
|
// Utils used by player
|
||||||
public @interface MinimizeMode {
|
////////////////////////////////////////////////////////////////////////////
|
||||||
int MINIMIZE_ON_EXIT_MODE_NONE = 0;
|
|
||||||
int MINIMIZE_ON_EXIT_MODE_BACKGROUND = 1;
|
public static MainPlayer.PlayerType retrievePlayerTypeFromIntent(final Intent intent) {
|
||||||
int MINIMIZE_ON_EXIT_MODE_POPUP = 2;
|
// If you want to open popup from the app just include Constants.POPUP_ONLY into an extra
|
||||||
|
return MainPlayer.PlayerType.values()[
|
||||||
|
intent.getIntExtra(PLAYER_TYPE, MainPlayer.PlayerType.VIDEO.ordinal())];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPlaybackResumeEnabled(final Player player) {
|
||||||
|
return player.getPrefs().getBoolean(
|
||||||
|
player.getContext().getString(R.string.enable_watch_history_key), true)
|
||||||
|
&& player.getPrefs().getBoolean(
|
||||||
|
player.getContext().getString(R.string.enable_playback_resume_key), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RepeatMode
|
||||||
|
public static int nextRepeatMode(@RepeatMode final int repeatMode) {
|
||||||
|
switch (repeatMode) {
|
||||||
|
case REPEAT_MODE_OFF:
|
||||||
|
return REPEAT_MODE_ONE;
|
||||||
|
case REPEAT_MODE_ONE:
|
||||||
|
return REPEAT_MODE_ALL;
|
||||||
|
case REPEAT_MODE_ALL: default:
|
||||||
|
return REPEAT_MODE_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ResizeMode
|
||||||
|
public static int retrieveResizeModeFromPrefs(final Player player) {
|
||||||
|
return player.getPrefs().getInt(player.getContext().getString(R.string.last_resize_mode),
|
||||||
|
AspectRatioFrameLayout.RESIZE_MODE_FIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SwitchIntDef") // only fit, fill and zoom are supported by NewPipe
|
||||||
|
@ResizeMode
|
||||||
|
public static int nextResizeModeAndSaveToPrefs(final Player player,
|
||||||
|
@ResizeMode final int resizeMode) {
|
||||||
|
final int newResizeMode;
|
||||||
|
switch (resizeMode) {
|
||||||
|
case AspectRatioFrameLayout.RESIZE_MODE_FIT:
|
||||||
|
newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL;
|
||||||
|
break;
|
||||||
|
case AspectRatioFrameLayout.RESIZE_MODE_FILL:
|
||||||
|
newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM;
|
||||||
|
break;
|
||||||
|
case AspectRatioFrameLayout.RESIZE_MODE_ZOOM:
|
||||||
|
default:
|
||||||
|
newResizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.getPrefs().edit().putInt(
|
||||||
|
player.getContext().getString(R.string.last_resize_mode), resizeMode).apply();
|
||||||
|
return newResizeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlaybackParameters retrievePlaybackParametersFromPrefs(final Player player) {
|
||||||
|
final float speed = player.getPrefs().getFloat(player.getContext().getString(
|
||||||
|
R.string.playback_speed_key), player.getPlaybackSpeed());
|
||||||
|
final float pitch = player.getPrefs().getFloat(player.getContext().getString(
|
||||||
|
R.string.playback_pitch_key), player.getPlaybackPitch());
|
||||||
|
final boolean skipSilence = player.getPrefs().getBoolean(player.getContext().getString(
|
||||||
|
R.string.playback_skip_silence_key), player.getPlaybackSkipSilence());
|
||||||
|
return new PlaybackParameters(speed, pitch, skipSilence);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void savePlaybackParametersToPrefs(final Player player,
|
||||||
|
final float speed,
|
||||||
|
final float pitch,
|
||||||
|
final boolean skipSilence) {
|
||||||
|
player.getPrefs().edit()
|
||||||
|
.putFloat(player.getContext().getString(R.string.playback_speed_key), speed)
|
||||||
|
.putFloat(player.getContext().getString(R.string.playback_pitch_key), pitch)
|
||||||
|
.putBoolean(player.getContext().getString(R.string.playback_skip_silence_key),
|
||||||
|
skipSilence)
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param player {@code screenWidth} and {@code screenHeight} must have been initialized
|
||||||
|
* @return the popup starting layout params
|
||||||
|
*/
|
||||||
|
@SuppressLint("RtlHardcoded")
|
||||||
|
public static WindowManager.LayoutParams retrievePopupLayoutParamsFromPrefs(
|
||||||
|
final Player player) {
|
||||||
|
final boolean popupRememberSizeAndPos = player.getPrefs().getBoolean(
|
||||||
|
player.getContext().getString(R.string.popup_remember_size_pos_key), true);
|
||||||
|
final float defaultSize =
|
||||||
|
player.getContext().getResources().getDimension(R.dimen.popup_default_width);
|
||||||
|
final float popupWidth = popupRememberSizeAndPos
|
||||||
|
? player.getPrefs().getFloat(player.getContext().getString(
|
||||||
|
R.string.popup_saved_width_key), defaultSize)
|
||||||
|
: defaultSize;
|
||||||
|
final float popupHeight = getMinimumVideoHeight(popupWidth);
|
||||||
|
|
||||||
|
final WindowManager.LayoutParams popupLayoutParams = new WindowManager.LayoutParams(
|
||||||
|
(int) popupWidth, (int) popupHeight,
|
||||||
|
popupLayoutParamType(),
|
||||||
|
IDLE_WINDOW_FLAGS,
|
||||||
|
PixelFormat.TRANSLUCENT);
|
||||||
|
popupLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
|
||||||
|
popupLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
|
||||||
|
|
||||||
|
final int centerX = (int) (player.getScreenWidth() / 2f - popupWidth / 2f);
|
||||||
|
final int centerY = (int) (player.getScreenHeight() / 2f - popupHeight / 2f);
|
||||||
|
popupLayoutParams.x = popupRememberSizeAndPos
|
||||||
|
? player.getPrefs().getInt(player.getContext().getString(
|
||||||
|
R.string.popup_saved_x_key), centerX) : centerX;
|
||||||
|
popupLayoutParams.y = popupRememberSizeAndPos
|
||||||
|
? player.getPrefs().getInt(player.getContext().getString(
|
||||||
|
R.string.popup_saved_y_key), centerY) : centerY;
|
||||||
|
|
||||||
|
return popupLayoutParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void savePopupPositionAndSizeToPrefs(final Player player) {
|
||||||
|
if (player.getPopupLayoutParams() != null) {
|
||||||
|
player.getPrefs().edit()
|
||||||
|
.putFloat(player.getContext().getString(R.string.popup_saved_width_key),
|
||||||
|
player.getPopupLayoutParams().width)
|
||||||
|
.putInt(player.getContext().getString(R.string.popup_saved_x_key),
|
||||||
|
player.getPopupLayoutParams().x)
|
||||||
|
.putInt(player.getContext().getString(R.string.popup_saved_y_key),
|
||||||
|
player.getPopupLayoutParams().y)
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getMinimumVideoHeight(final float width) {
|
||||||
|
return width / (16.0f / 9.0f); // Respect the 16:9 ratio that most videos have
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RtlHardcoded")
|
||||||
|
public static WindowManager.LayoutParams buildCloseOverlayLayoutParams() {
|
||||||
|
final int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|
||||||
|
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
|
||||||
|
|
||||||
|
final WindowManager.LayoutParams closeOverlayLayoutParams = new WindowManager.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
popupLayoutParamType(),
|
||||||
|
flags,
|
||||||
|
PixelFormat.TRANSLUCENT);
|
||||||
|
|
||||||
|
closeOverlayLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
|
||||||
|
closeOverlayLayoutParams.softInputMode =
|
||||||
|
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
|
||||||
|
return closeOverlayLayoutParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int popupLayoutParamType() {
|
||||||
|
return Build.VERSION.SDK_INT < Build.VERSION_CODES.O
|
||||||
|
? WindowManager.LayoutParams.TYPE_PHONE
|
||||||
|
: WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int retrieveSeekDurationFromPreferences(final Player player) {
|
||||||
|
return Integer.parseInt(Objects.requireNonNull(player.getPrefs().getString(
|
||||||
|
player.getContext().getString(R.string.seek_duration_key),
|
||||||
|
player.getContext().getString(R.string.seek_duration_default_value))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import org.schabi.newpipe.App;
|
||||||
import org.schabi.newpipe.MainActivity;
|
import org.schabi.newpipe.MainActivity;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||||
import org.schabi.newpipe.player.MainPlayer;
|
import org.schabi.newpipe.player.MainPlayer;
|
||||||
import org.schabi.newpipe.player.VideoPlayerImpl;
|
import org.schabi.newpipe.player.Player;
|
||||||
import org.schabi.newpipe.player.event.PlayerServiceEventListener;
|
import org.schabi.newpipe.player.event.PlayerServiceEventListener;
|
||||||
import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener;
|
import org.schabi.newpipe.player.event.PlayerServiceExtendedEventListener;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||||
|
@ -33,7 +33,7 @@ public final class PlayerHolder {
|
||||||
private static ServiceConnection serviceConnection;
|
private static ServiceConnection serviceConnection;
|
||||||
public static boolean bound;
|
public static boolean bound;
|
||||||
private static MainPlayer playerService;
|
private static MainPlayer playerService;
|
||||||
private static VideoPlayerImpl player;
|
private static Player player;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current {@link MainPlayer.PlayerType} of the {@link MainPlayer} service,
|
* Returns the current {@link MainPlayer.PlayerType} of the {@link MainPlayer} service,
|
||||||
|
|
|
@ -3,11 +3,11 @@ package org.schabi.newpipe.player.mediasession;
|
||||||
import android.support.v4.media.MediaDescriptionCompat;
|
import android.support.v4.media.MediaDescriptionCompat;
|
||||||
|
|
||||||
public interface MediaSessionCallback {
|
public interface MediaSessionCallback {
|
||||||
void onSkipToPrevious();
|
void playPrevious();
|
||||||
|
|
||||||
void onSkipToNext();
|
void playNext();
|
||||||
|
|
||||||
void onSkipToIndex(int index);
|
void playItemAtIndex(int index);
|
||||||
|
|
||||||
int getCurrentPlayingIndex();
|
int getCurrentPlayingIndex();
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ public interface MediaSessionCallback {
|
||||||
|
|
||||||
MediaDescriptionCompat getQueueMetadata(int index);
|
MediaDescriptionCompat getQueueMetadata(int index);
|
||||||
|
|
||||||
void onPlay();
|
void play();
|
||||||
|
|
||||||
void onPause();
|
void pause();
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,18 +65,18 @@ public class PlayQueueNavigator implements MediaSessionConnector.QueueNavigator
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToPrevious(final Player player, final ControlDispatcher controlDispatcher) {
|
public void onSkipToPrevious(final Player player, final ControlDispatcher controlDispatcher) {
|
||||||
callback.onSkipToPrevious();
|
callback.playPrevious();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToQueueItem(final Player player, final ControlDispatcher controlDispatcher,
|
public void onSkipToQueueItem(final Player player, final ControlDispatcher controlDispatcher,
|
||||||
final long id) {
|
final long id) {
|
||||||
callback.onSkipToIndex((int) id);
|
callback.playItemAtIndex((int) id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToNext(final Player player, final ControlDispatcher controlDispatcher) {
|
public void onSkipToNext(final Player player, final ControlDispatcher controlDispatcher) {
|
||||||
callback.onSkipToNext();
|
callback.playNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void publishFloatingQueueWindow() {
|
private void publishFloatingQueueWindow() {
|
||||||
|
|
|
@ -14,9 +14,9 @@ public class PlayQueuePlaybackController extends DefaultControlDispatcher {
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchSetPlayWhenReady(final Player player, final boolean playWhenReady) {
|
public boolean dispatchSetPlayWhenReady(final Player player, final boolean playWhenReady) {
|
||||||
if (playWhenReady) {
|
if (playWhenReady) {
|
||||||
callback.onPlay();
|
callback.play();
|
||||||
} else {
|
} else {
|
||||||
callback.onPause();
|
callback.pause();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,33 +5,33 @@ import android.os.Bundle;
|
||||||
import android.support.v4.media.MediaDescriptionCompat;
|
import android.support.v4.media.MediaDescriptionCompat;
|
||||||
import android.support.v4.media.MediaMetadataCompat;
|
import android.support.v4.media.MediaMetadataCompat;
|
||||||
|
|
||||||
import org.schabi.newpipe.player.BasePlayer;
|
import org.schabi.newpipe.player.Player;
|
||||||
import org.schabi.newpipe.player.mediasession.MediaSessionCallback;
|
import org.schabi.newpipe.player.mediasession.MediaSessionCallback;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
|
||||||
|
|
||||||
public class BasePlayerMediaSession implements MediaSessionCallback {
|
public class PlayerMediaSession implements MediaSessionCallback {
|
||||||
private final BasePlayer player;
|
private final Player player;
|
||||||
|
|
||||||
public BasePlayerMediaSession(final BasePlayer player) {
|
public PlayerMediaSession(final Player player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToPrevious() {
|
public void playPrevious() {
|
||||||
player.onPlayPrevious();
|
player.playPrevious();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToNext() {
|
public void playNext() {
|
||||||
player.onPlayNext();
|
player.playNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSkipToIndex(final int index) {
|
public void playItemAtIndex(final int index) {
|
||||||
if (player.getPlayQueue() == null) {
|
if (player.getPlayQueue() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player.onSelected(player.getPlayQueue().getItem(index));
|
player.selectQueueItem(player.getPlayQueue().getItem(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,11 +52,14 @@ public class BasePlayerMediaSession implements MediaSessionCallback {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaDescriptionCompat getQueueMetadata(final int index) {
|
public MediaDescriptionCompat getQueueMetadata(final int index) {
|
||||||
if (player.getPlayQueue() == null || player.getPlayQueue().getItem(index) == null) {
|
if (player.getPlayQueue() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final PlayQueueItem item = player.getPlayQueue().getItem(index);
|
||||||
|
if (item == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final PlayQueueItem item = player.getPlayQueue().getItem(index);
|
|
||||||
final MediaDescriptionCompat.Builder descriptionBuilder
|
final MediaDescriptionCompat.Builder descriptionBuilder
|
||||||
= new MediaDescriptionCompat.Builder()
|
= new MediaDescriptionCompat.Builder()
|
||||||
.setMediaId(String.valueOf(index))
|
.setMediaId(String.valueOf(index))
|
||||||
|
@ -83,12 +86,12 @@ public class BasePlayerMediaSession implements MediaSessionCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlay() {
|
public void play() {
|
||||||
player.onPlay();
|
player.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void pause() {
|
||||||
player.onPause();
|
player.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -351,4 +351,19 @@ public final class Localization {
|
||||||
private static double round(final double value, final int places) {
|
private static double round(final double value, final int places) {
|
||||||
return new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue();
|
return new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workaround to match normalized captions like english to English or deutsch to Deutsch.
|
||||||
|
* @param list the list to search into
|
||||||
|
* @param toFind the string to look for
|
||||||
|
* @return whether the string was found or not
|
||||||
|
*/
|
||||||
|
public static boolean containsCaseInsensitive(final List<String> list, final String toFind) {
|
||||||
|
for (final String i : list) {
|
||||||
|
if (i.equalsIgnoreCase(toFind)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,10 +46,9 @@ import org.schabi.newpipe.local.history.StatisticsPlaylistFragment;
|
||||||
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
|
import org.schabi.newpipe.local.playlist.LocalPlaylistFragment;
|
||||||
import org.schabi.newpipe.local.subscription.SubscriptionFragment;
|
import org.schabi.newpipe.local.subscription.SubscriptionFragment;
|
||||||
import org.schabi.newpipe.local.subscription.SubscriptionsImportFragment;
|
import org.schabi.newpipe.local.subscription.SubscriptionsImportFragment;
|
||||||
import org.schabi.newpipe.player.BackgroundPlayerActivity;
|
import org.schabi.newpipe.player.PlayQueueActivity;
|
||||||
import org.schabi.newpipe.player.BasePlayer;
|
import org.schabi.newpipe.player.Player;
|
||||||
import org.schabi.newpipe.player.MainPlayer;
|
import org.schabi.newpipe.player.MainPlayer;
|
||||||
import org.schabi.newpipe.player.VideoPlayer;
|
|
||||||
import org.schabi.newpipe.player.helper.PlayerHelper;
|
import org.schabi.newpipe.player.helper.PlayerHelper;
|
||||||
import org.schabi.newpipe.player.helper.PlayerHolder;
|
import org.schabi.newpipe.player.helper.PlayerHolder;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||||
|
@ -78,11 +77,11 @@ public final class NavigationHelper {
|
||||||
if (playQueue != null) {
|
if (playQueue != null) {
|
||||||
final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class);
|
final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class);
|
||||||
if (cacheKey != null) {
|
if (cacheKey != null) {
|
||||||
intent.putExtra(VideoPlayer.PLAY_QUEUE_KEY, cacheKey);
|
intent.putExtra(Player.PLAY_QUEUE_KEY, cacheKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
intent.putExtra(VideoPlayer.RESUME_PLAYBACK, resumePlayback);
|
intent.putExtra(Player.RESUME_PLAYBACK, resumePlayback);
|
||||||
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_VIDEO);
|
intent.putExtra(Player.PLAYER_TYPE, MainPlayer.PlayerType.VIDEO.ordinal());
|
||||||
|
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +93,7 @@ public final class NavigationHelper {
|
||||||
final boolean resumePlayback,
|
final boolean resumePlayback,
|
||||||
final boolean playWhenReady) {
|
final boolean playWhenReady) {
|
||||||
return getPlayerIntent(context, targetClazz, playQueue, resumePlayback)
|
return getPlayerIntent(context, targetClazz, playQueue, resumePlayback)
|
||||||
.putExtra(BasePlayer.PLAY_WHEN_READY, playWhenReady);
|
.putExtra(Player.PLAY_WHEN_READY, playWhenReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -104,8 +103,8 @@ public final class NavigationHelper {
|
||||||
final boolean selectOnAppend,
|
final boolean selectOnAppend,
|
||||||
final boolean resumePlayback) {
|
final boolean resumePlayback) {
|
||||||
return getPlayerIntent(context, targetClazz, playQueue, resumePlayback)
|
return getPlayerIntent(context, targetClazz, playQueue, resumePlayback)
|
||||||
.putExtra(BasePlayer.APPEND_ONLY, true)
|
.putExtra(Player.APPEND_ONLY, true)
|
||||||
.putExtra(BasePlayer.SELECT_ON_APPEND, selectOnAppend);
|
.putExtra(Player.SELECT_ON_APPEND, selectOnAppend);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void playOnMainPlayer(final AppCompatActivity activity,
|
public static void playOnMainPlayer(final AppCompatActivity activity,
|
||||||
|
@ -135,7 +134,7 @@ public final class NavigationHelper {
|
||||||
|
|
||||||
Toast.makeText(context, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
|
||||||
final Intent intent = getPlayerIntent(context, MainPlayer.class, queue, resumePlayback);
|
final Intent intent = getPlayerIntent(context, MainPlayer.class, queue, resumePlayback);
|
||||||
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_POPUP);
|
intent.putExtra(Player.PLAYER_TYPE, MainPlayer.PlayerType.POPUP.ordinal());
|
||||||
ContextCompat.startForegroundService(context, intent);
|
ContextCompat.startForegroundService(context, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +144,7 @@ public final class NavigationHelper {
|
||||||
Toast.makeText(context, R.string.background_player_playing_toast, Toast.LENGTH_SHORT)
|
Toast.makeText(context, R.string.background_player_playing_toast, Toast.LENGTH_SHORT)
|
||||||
.show();
|
.show();
|
||||||
final Intent intent = getPlayerIntent(context, MainPlayer.class, queue, resumePlayback);
|
final Intent intent = getPlayerIntent(context, MainPlayer.class, queue, resumePlayback);
|
||||||
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_AUDIO);
|
intent.putExtra(Player.PLAYER_TYPE, MainPlayer.PlayerType.AUDIO.ordinal());
|
||||||
ContextCompat.startForegroundService(context, intent);
|
ContextCompat.startForegroundService(context, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +161,7 @@ public final class NavigationHelper {
|
||||||
final Intent intent = getPlayerEnqueueIntent(
|
final Intent intent = getPlayerEnqueueIntent(
|
||||||
context, MainPlayer.class, queue, selectOnAppend, resumePlayback);
|
context, MainPlayer.class, queue, selectOnAppend, resumePlayback);
|
||||||
|
|
||||||
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_VIDEO);
|
intent.putExtra(Player.PLAYER_TYPE, MainPlayer.PlayerType.VIDEO.ordinal());
|
||||||
ContextCompat.startForegroundService(context, intent);
|
ContextCompat.startForegroundService(context, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +181,7 @@ public final class NavigationHelper {
|
||||||
Toast.makeText(context, R.string.enqueued, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.enqueued, Toast.LENGTH_SHORT).show();
|
||||||
final Intent intent = getPlayerEnqueueIntent(
|
final Intent intent = getPlayerEnqueueIntent(
|
||||||
context, MainPlayer.class, queue, selectOnAppend, resumePlayback);
|
context, MainPlayer.class, queue, selectOnAppend, resumePlayback);
|
||||||
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_POPUP);
|
intent.putExtra(Player.PLAYER_TYPE, MainPlayer.PlayerType.POPUP.ordinal());
|
||||||
ContextCompat.startForegroundService(context, intent);
|
ContextCompat.startForegroundService(context, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +197,7 @@ public final class NavigationHelper {
|
||||||
Toast.makeText(context, R.string.enqueued, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, R.string.enqueued, Toast.LENGTH_SHORT).show();
|
||||||
final Intent intent = getPlayerEnqueueIntent(
|
final Intent intent = getPlayerEnqueueIntent(
|
||||||
context, MainPlayer.class, queue, selectOnAppend, resumePlayback);
|
context, MainPlayer.class, queue, selectOnAppend, resumePlayback);
|
||||||
intent.putExtra(VideoPlayer.PLAYER_TYPE, VideoPlayer.PLAYER_TYPE_AUDIO);
|
intent.putExtra(Player.PLAYER_TYPE, MainPlayer.PlayerType.AUDIO.ordinal());
|
||||||
ContextCompat.startForegroundService(context, intent);
|
ContextCompat.startForegroundService(context, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,7 +492,7 @@ public final class NavigationHelper {
|
||||||
if (playQueue != null) {
|
if (playQueue != null) {
|
||||||
final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class);
|
final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class);
|
||||||
if (cacheKey != null) {
|
if (cacheKey != null) {
|
||||||
intent.putExtra(VideoPlayer.PLAY_QUEUE_KEY, cacheKey);
|
intent.putExtra(Player.PLAY_QUEUE_KEY, cacheKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
|
@ -531,7 +530,7 @@ public final class NavigationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Intent getPlayQueueActivityIntent(final Context context) {
|
public static Intent getPlayQueueActivityIntent(final Context context) {
|
||||||
final Intent intent = new Intent(context, BackgroundPlayerActivity.class);
|
final Intent intent = new Intent(context, PlayQueueActivity.class);
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
tools:context="org.schabi.newpipe.player.BackgroundPlayerActivity">
|
tools:context="org.schabi.newpipe.player.PlayQueueActivity">
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/appbar"
|
android:id="@+id/appbar"
|
||||||
|
|
|
@ -145,7 +145,7 @@
|
||||||
tools:text="The Video Artist LONG very LONG very Long" />
|
tools:text="The Video Artist LONG very LONG very Long" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<TextView
|
||||||
android:id="@+id/qualityTextView"
|
android:id="@+id/qualityTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
|
@ -154,13 +154,12 @@
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:minWidth="0dp"
|
android:minWidth="0dp"
|
||||||
android:padding="@dimen/player_main_buttons_padding"
|
android:padding="@dimen/player_main_buttons_padding"
|
||||||
android:text="720p"
|
|
||||||
android:textAllCaps="false"
|
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
tools:ignore="HardcodedText,RtlHardcoded" />
|
tools:ignore="HardcodedText,RtlHardcoded"
|
||||||
|
tools:text="720p" />
|
||||||
|
|
||||||
<Button
|
<TextView
|
||||||
android:id="@+id/playbackSpeed"
|
android:id="@+id/playbackSpeed"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
|
@ -169,7 +168,6 @@
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:minWidth="0dp"
|
android:minWidth="0dp"
|
||||||
android:padding="@dimen/player_main_buttons_padding"
|
android:padding="@dimen/player_main_buttons_padding"
|
||||||
android:textAllCaps="false"
|
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
tools:ignore="RtlHardcoded,RtlSymmetry"
|
tools:ignore="RtlHardcoded,RtlSymmetry"
|
||||||
|
@ -216,7 +214,7 @@
|
||||||
tools:ignore="RtlHardcoded"
|
tools:ignore="RtlHardcoded"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<Button
|
<TextView
|
||||||
android:id="@+id/resizeTextView"
|
android:id="@+id/resizeTextView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
tools:context="org.schabi.newpipe.player.BackgroundPlayerActivity">
|
tools:context="org.schabi.newpipe.player.PlayQueueActivity">
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/appbar"
|
android:id="@+id/appbar"
|
||||||
|
|
|
@ -156,11 +156,10 @@
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:minWidth="0dp"
|
android:minWidth="0dp"
|
||||||
android:padding="@dimen/player_main_buttons_padding"
|
android:padding="@dimen/player_main_buttons_padding"
|
||||||
android:text="720p"
|
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:visibility="visible"
|
tools:ignore="HardcodedText,RtlHardcoded"
|
||||||
tools:ignore="HardcodedText,RtlHardcoded" />
|
tools:text="720p" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/playbackSpeed"
|
android:id="@+id/playbackSpeed"
|
||||||
|
@ -350,7 +349,7 @@
|
||||||
tools:text="1:06:29" />
|
tools:text="1:06:29" />
|
||||||
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatSeekBar
|
<org.schabi.newpipe.views.FocusAwareSeekBar
|
||||||
android:id="@+id/playbackSeekBar"
|
android:id="@+id/playbackSeekBar"
|
||||||
style="@style/Widget.AppCompat.SeekBar"
|
style="@style/Widget.AppCompat.SeekBar"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context=".player.BackgroundPlayerActivity">
|
tools:context=".player.PlayQueueActivity">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_append_playlist"
|
android:id="@+id/action_append_playlist"
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
<string name="use_external_video_player_key" translatable="false">use_external_video_player</string>
|
<string name="use_external_video_player_key" translatable="false">use_external_video_player</string>
|
||||||
<string name="use_external_audio_player_key" translatable="false">use_external_audio_player</string>
|
<string name="use_external_audio_player_key" translatable="false">use_external_audio_player</string>
|
||||||
<string name="use_old_player_key" translatable="false">use_oldplayer</string>
|
|
||||||
|
|
||||||
<string name="volume_gesture_control_key" translatable="false">volume_gesture_control</string>
|
<string name="volume_gesture_control_key" translatable="false">volume_gesture_control</string>
|
||||||
<string name="brightness_gesture_control_key" translatable="false">brightness_gesture_control</string>
|
<string name="brightness_gesture_control_key" translatable="false">brightness_gesture_control</string>
|
||||||
|
@ -33,6 +32,10 @@
|
||||||
<string name="screen_brightness_timestamp_key" translatable="false">screen_brightness_timestamp_key</string>
|
<string name="screen_brightness_timestamp_key" translatable="false">screen_brightness_timestamp_key</string>
|
||||||
<string name="clear_queue_confirmation_key" translatable="false">clear_queue_confirmation_key</string>
|
<string name="clear_queue_confirmation_key" translatable="false">clear_queue_confirmation_key</string>
|
||||||
|
|
||||||
|
<string name="popup_saved_width_key" translatable="false">popup_saved_width</string>
|
||||||
|
<string name="popup_saved_x_key" translatable="false">popup_saved_x</string>
|
||||||
|
<string name="popup_saved_y_key" translatable="false">popup_saved_y</string>
|
||||||
|
|
||||||
<string name="seek_duration_key" translatable="false">seek_duration</string>
|
<string name="seek_duration_key" translatable="false">seek_duration</string>
|
||||||
<string name="seek_duration_default_value" translatable="false">10000</string>
|
<string name="seek_duration_default_value" translatable="false">10000</string>
|
||||||
<string-array name="seek_duration_description" translatable="false">
|
<string-array name="seek_duration_description" translatable="false">
|
||||||
|
@ -70,7 +73,6 @@
|
||||||
<item>@string/minimize_on_exit_popup_description</item>
|
<item>@string/minimize_on_exit_popup_description</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
|
||||||
<string name="autoplay_key" translatable="false">autoplay_key</string>
|
<string name="autoplay_key" translatable="false">autoplay_key</string>
|
||||||
<string name="autoplay_value" translatable="false">@string/autoplay_wifi_key</string>
|
<string name="autoplay_value" translatable="false">@string/autoplay_wifi_key</string>
|
||||||
<string name="autoplay_always_key" translatable="false">autoplay_always_key</string>
|
<string name="autoplay_always_key" translatable="false">autoplay_always_key</string>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
lines="156,158"/>
|
lines="156,158"/>
|
||||||
|
|
||||||
<suppress checks="FileLength"
|
<suppress checks="FileLength"
|
||||||
files="VideoPlayerImpl.java"/>
|
files="Player.java"/>
|
||||||
|
|
||||||
<suppress checks="FileLength"
|
<suppress checks="FileLength"
|
||||||
files="VideoDetailFragment.java"/>
|
files="VideoDetailFragment.java"/>
|
||||||
|
|
Loading…
Reference in a new issue