Merge branch 'TeamNewPipe:dev' into dev

This commit is contained in:
Martin 2021-12-25 15:14:24 +01:00 committed by GitHub
commit 5134080f87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 71 additions and 54 deletions

View File

@ -16,8 +16,8 @@ android {
resValue "string", "app_name", "NewPipe" resValue "string", "app_name", "NewPipe"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 29 targetSdkVersion 29
versionCode 980 versionCode 981
versionName "0.21.14" versionName "0.21.15"
multiDexEnabled true multiDexEnabled true

View File

@ -63,6 +63,7 @@ public final class FlingBehavior extends AppBarLayout.Behavior {
return consumed == dy; return consumed == dy;
} }
@Override
public boolean onInterceptTouchEvent(@NonNull final CoordinatorLayout parent, public boolean onInterceptTouchEvent(@NonNull final CoordinatorLayout parent,
@NonNull final AppBarLayout child, @NonNull final AppBarLayout child,
@NonNull final MotionEvent ev) { @NonNull final MotionEvent ev) {

View File

@ -685,7 +685,7 @@ public final class VideoDetailFragment
}); });
setupBottomPlayer(); setupBottomPlayer();
if (!playerHolder.bound) { if (!playerHolder.isBound()) {
setHeightThumbnail(); setHeightThumbnail();
} else { } else {
playerHolder.startService(false, this); playerHolder.startService(false, this);
@ -1434,7 +1434,7 @@ public final class VideoDetailFragment
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
} }
// Rebound to the service if it was closed via notification or mini player // Rebound to the service if it was closed via notification or mini player
if (!playerHolder.bound) { if (!playerHolder.isBound()) {
playerHolder.startService( playerHolder.startService(
false, VideoDetailFragment.this); false, VideoDetailFragment.this);
} }

View File

@ -724,7 +724,7 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
@Override @Override
public boolean onBackPressed() { public boolean onBackPressed() {
if (suggestionsPanelVisible if (suggestionsPanelVisible
&& infoListAdapter.getItemsList().size() > 0 && !infoListAdapter.getItemsList().isEmpty()
&& !isLoading.get()) { && !isLoading.get()) {
hideSuggestionsPanel(); hideSuggestionsPanel();
hideKeyboardSearch(); hideKeyboardSearch();

View File

@ -54,11 +54,9 @@ class ChannelItem(
context.getString(R.string.subscribers_count_not_available) context.getString(R.string.subscribers_count_not_available)
} }
if (itemVersion == ItemVersion.NORMAL) { if (itemVersion == ItemVersion.NORMAL && infoItem.streamCount >= 0) {
if (infoItem.streamCount >= 0) { val formattedVideoAmount = Localization.localizeStreamCount(context, infoItem.streamCount)
val formattedVideoAmount = Localization.localizeStreamCount(context, infoItem.streamCount) details = Localization.concatenateStrings(details, formattedVideoAmount)
details = Localization.concatenateStrings(details, formattedVideoAmount)
}
} }
return details return details
} }

View File

@ -2348,7 +2348,8 @@ public final class Player implements
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
} }
private void setRepeatModeButton(final AppCompatImageButton imageButton, final int repeatMode) { private void setRepeatModeButton(final AppCompatImageButton imageButton,
@RepeatMode final int repeatMode) {
switch (repeatMode) { switch (repeatMode) {
case REPEAT_MODE_OFF: case REPEAT_MODE_OFF:
imageButton.setImageResource(R.drawable.exo_controls_repeat_off); imageButton.setImageResource(R.drawable.exo_controls_repeat_off);
@ -2362,7 +2363,7 @@ public final class Player implements
} }
} }
private void setShuffleButton(final ImageButton button, final boolean shuffled) { private void setShuffleButton(@NonNull final ImageButton button, final boolean shuffled) {
button.setImageAlpha(shuffled ? 255 : 77); button.setImageAlpha(shuffled ? 255 : 77);
} }
//endregion //endregion
@ -2387,7 +2388,7 @@ public final class Player implements
return !exoPlayerIsNull() && simpleExoPlayer.getVolume() == 0; return !exoPlayerIsNull() && simpleExoPlayer.getVolume() == 0;
} }
private void setMuteButton(final ImageButton button, final boolean isMuted) { private void setMuteButton(@NonNull final ImageButton button, final boolean isMuted) {
button.setImageDrawable(AppCompatResources.getDrawable(context, isMuted button.setImageDrawable(AppCompatResources.getDrawable(context, isMuted
? R.drawable.ic_volume_off : R.drawable.ic_volume_up)); ? R.drawable.ic_volume_off : R.drawable.ic_volume_up));
} }
@ -2876,7 +2877,7 @@ public final class Player implements
databaseUpdateDisposable databaseUpdateDisposable
.add(recordManager.saveStreamState(currentMetadata.getMetadata(), progressMillis) .add(recordManager.saveStreamState(currentMetadata.getMetadata(), progressMillis)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnError((e) -> { .doOnError(e -> {
if (DEBUG) { if (DEBUG) {
e.printStackTrace(); e.printStackTrace();
} }
@ -3386,7 +3387,7 @@ public final class Player implements
playbackSpeedPopupMenu.setOnDismissListener(this); playbackSpeedPopupMenu.setOnDismissListener(this);
} }
private void buildCaptionMenu(final List<String> availableLanguages) { private void buildCaptionMenu(@NonNull final List<String> availableLanguages) {
if (captionPopupMenu == null) { if (captionPopupMenu == null) {
return; return;
} }
@ -3454,7 +3455,7 @@ public final class Player implements
* Called when an item of the quality selector or the playback speed selector is selected. * Called when an item of the quality selector or the playback speed selector is selected.
*/ */
@Override @Override
public boolean onMenuItemClick(final MenuItem menuItem) { public boolean onMenuItemClick(@NonNull final MenuItem menuItem) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onMenuItemClick() called with: " Log.d(TAG, "onMenuItemClick() called with: "
+ "menuItem = [" + menuItem + "], " + "menuItem = [" + menuItem + "], "
@ -3491,7 +3492,7 @@ public final class Player implements
* Called when some popup menu is dismissed. * Called when some popup menu is dismissed.
*/ */
@Override @Override
public void onDismiss(final PopupMenu menu) { public void onDismiss(@Nullable final PopupMenu menu) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onDismiss() called with: menu = [" + menu + "]"); Log.d(TAG, "onDismiss() called with: menu = [" + menu + "]");
} }
@ -3544,7 +3545,7 @@ public final class Player implements
isSomePopupMenuVisible = true; isSomePopupMenuVisible = true;
} }
private void setPlaybackQuality(final String quality) { private void setPlaybackQuality(@Nullable final String quality) {
videoResolver.setPlaybackQuality(quality); videoResolver.setPlaybackQuality(quality);
} }
//endregion //endregion
@ -3568,7 +3569,7 @@ public final class Player implements
final int minimumLength = Math.min(metrics.heightPixels, metrics.widthPixels); final int minimumLength = Math.min(metrics.heightPixels, metrics.widthPixels);
final float captionRatioInverse = 20f + 4f * (1.0f - captionScale); final float captionRatioInverse = 20f + 4f * (1.0f - captionScale);
binding.subtitleView.setFixedTextSize( binding.subtitleView.setFixedTextSize(
TypedValue.COMPLEX_UNIT_PX, (float) minimumLength / captionRatioInverse); TypedValue.COMPLEX_UNIT_PX, minimumLength / captionRatioInverse);
} }
binding.subtitleView.setApplyEmbeddedStyles(captionStyle == CaptionStyleCompat.DEFAULT); binding.subtitleView.setApplyEmbeddedStyles(captionStyle == CaptionStyleCompat.DEFAULT);
binding.subtitleView.setStyle(captionStyle); binding.subtitleView.setStyle(captionStyle);
@ -3845,7 +3846,7 @@ public final class Player implements
} }
@Override // exoplayer listener @Override // exoplayer listener
public void onVideoSizeChanged(final VideoSize videoSize) { public void onVideoSizeChanged(@NonNull final VideoSize videoSize) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onVideoSizeChanged() called with: " Log.d(TAG, "onVideoSizeChanged() called with: "
+ "width / height = [" + videoSize.width + " / " + videoSize.height + "width / height = [" + videoSize.width + " / " + videoSize.height
@ -3959,7 +3960,7 @@ public final class Player implements
} }
} }
private int distanceFromCloseButton(final MotionEvent popupMotionEvent) { private int distanceFromCloseButton(@NonNull final MotionEvent popupMotionEvent) {
final int closeOverlayButtonX = closeOverlayBinding.closeButton.getLeft() final int closeOverlayButtonX = closeOverlayBinding.closeButton.getLeft()
+ closeOverlayBinding.closeButton.getWidth() / 2; + closeOverlayBinding.closeButton.getWidth() / 2;
final int closeOverlayButtonY = closeOverlayBinding.closeButton.getTop() final int closeOverlayButtonY = closeOverlayBinding.closeButton.getTop()
@ -3978,7 +3979,7 @@ public final class Player implements
return buttonRadius * 1.2f; return buttonRadius * 1.2f;
} }
public boolean isInsideClosingRadius(final MotionEvent popupMotionEvent) { public boolean isInsideClosingRadius(@NonNull final MotionEvent popupMotionEvent) {
return distanceFromCloseButton(popupMotionEvent) <= getClosingRadius(); return distanceFromCloseButton(popupMotionEvent) <= getClosingRadius();
} }
//endregion //endregion
@ -4098,6 +4099,7 @@ public final class Player implements
} }
} }
@Nullable
public AppCompatActivity getParentActivity() { public AppCompatActivity getParentActivity() {
// ! instanceof ViewGroup means that view was added via windowManager for Popup // ! instanceof ViewGroup means that view was added via windowManager for Popup
if (binding == null || !(binding.getRoot().getParent() instanceof ViewGroup)) { if (binding == null || !(binding.getRoot().getParent() instanceof ViewGroup)) {

View File

@ -1,5 +1,12 @@
package org.schabi.newpipe.player.event; package org.schabi.newpipe.player.event;
import static org.schabi.newpipe.ktx.AnimationType.ALPHA;
import static org.schabi.newpipe.ktx.AnimationType.SCALE_AND_ALPHA;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.player.Player.DEFAULT_CONTROLS_DURATION;
import static org.schabi.newpipe.player.Player.DEFAULT_CONTROLS_HIDE_TIME;
import static org.schabi.newpipe.player.Player.STATE_PLAYING;
import android.app.Activity; import android.app.Activity;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -8,22 +15,15 @@ import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.content.res.AppCompatResources;
import org.jetbrains.annotations.NotNull;
import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.player.MainPlayer; import org.schabi.newpipe.player.MainPlayer;
import org.schabi.newpipe.player.Player; 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.ktx.AnimationType.ALPHA;
import static org.schabi.newpipe.ktx.AnimationType.SCALE_AND_ALPHA;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.player.Player.DEFAULT_CONTROLS_DURATION;
import static org.schabi.newpipe.player.Player.DEFAULT_CONTROLS_HIDE_TIME;
import static org.schabi.newpipe.player.Player.STATE_PLAYING;
/** /**
* GestureListener for the player * GestureListener for the player
* *
@ -45,8 +45,8 @@ public class PlayerGestureListener
} }
@Override @Override
public void onDoubleTap(@NotNull final MotionEvent event, public void onDoubleTap(@NonNull final MotionEvent event,
@NotNull final DisplayPortion portion) { @NonNull final DisplayPortion portion) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onDoubleTap called with playerType = [" Log.d(TAG, "onDoubleTap called with playerType = ["
+ player.getPlayerType() + "], portion = [" + portion + "]"); + player.getPlayerType() + "], portion = [" + portion + "]");
@ -65,7 +65,7 @@ public class PlayerGestureListener
} }
@Override @Override
public void onSingleTap(@NotNull final MainPlayer.PlayerType playerType) { public void onSingleTap(@NonNull final MainPlayer.PlayerType playerType) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onSingleTap called with playerType = [" + player.getPlayerType() + "]"); Log.d(TAG, "onSingleTap called with playerType = [" + player.getPlayerType() + "]");
} }
@ -85,10 +85,10 @@ public class PlayerGestureListener
} }
@Override @Override
public void onScroll(@NotNull final MainPlayer.PlayerType playerType, public void onScroll(@NonNull final MainPlayer.PlayerType playerType,
@NotNull final DisplayPortion portion, @NonNull final DisplayPortion portion,
@NotNull final MotionEvent initialEvent, @NonNull final MotionEvent initialEvent,
@NotNull final MotionEvent movingEvent, @NonNull final MotionEvent movingEvent,
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 = ["
@ -197,8 +197,8 @@ public class PlayerGestureListener
} }
@Override @Override
public void onScrollEnd(@NotNull final MainPlayer.PlayerType playerType, public void onScrollEnd(@NonNull final MainPlayer.PlayerType playerType,
@NotNull final MotionEvent event) { @NonNull final MotionEvent event) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onScrollEnd called with playerType = [" Log.d(TAG, "onScrollEnd called with playerType = ["
+ player.getPlayerType() + "]"); + player.getPlayerType() + "]");

View File

@ -35,13 +35,13 @@ public final class PlayerHolder {
return PlayerHolder.instance; return PlayerHolder.instance;
} }
private final boolean DEBUG = MainActivity.DEBUG; private static final boolean DEBUG = MainActivity.DEBUG;
private final String TAG = PlayerHolder.class.getSimpleName(); private static final String TAG = PlayerHolder.class.getSimpleName();
private PlayerServiceExtendedEventListener listener; private PlayerServiceExtendedEventListener listener;
private final PlayerServiceConnection serviceConnection = new PlayerServiceConnection(); private final PlayerServiceConnection serviceConnection = new PlayerServiceConnection();
public boolean bound; private boolean bound;
private MainPlayer playerService; private MainPlayer playerService;
private Player player; private Player player;
@ -70,6 +70,10 @@ public final class PlayerHolder {
return player != null; return player != null;
} }
public boolean isBound() {
return bound;
}
public int getQueueSize() { public int getQueueSize() {
return isPlayerOpen() ? player.getPlayQueue().size() : 0; return isPlayerOpen() ? player.getPlayQueue().size() : 0;
} }
@ -148,7 +152,7 @@ public final class PlayerHolder {
} }
startPlayerListener(); startPlayerListener();
} }
}; }
private void bind(final Context context) { private void bind(final Context context) {
if (DEBUG) { if (DEBUG) {

View File

@ -18,7 +18,7 @@ import java.util.Objects;
public abstract class BasePreferenceFragment extends PreferenceFragmentCompat { public abstract class BasePreferenceFragment extends PreferenceFragmentCompat {
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()); protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
protected final boolean DEBUG = MainActivity.DEBUG; protected static final boolean DEBUG = MainActivity.DEBUG;
SharedPreferences defaultPreferences; SharedPreferences defaultPreferences;

View File

@ -36,6 +36,10 @@ import java.util.Objects;
public abstract class Tab { public abstract class Tab {
private static final String JSON_TAB_ID_KEY = "tab_id"; private static final String JSON_TAB_ID_KEY = "tab_id";
private static final String NO_NAME = "<no-name>";
private static final String NO_ID = "<no-id>";
private static final String NO_URL = "<no-url>";
Tab() { Tab() {
} }
@ -185,7 +189,9 @@ public abstract class Tab {
@Override @Override
public String getTabName(final Context context) { public String getTabName(final Context context) {
return "NewPipe"; //context.getString(R.string.blank_page_summary); // TODO: find a better name for the blank tab (maybe "blank_tab") or replace it with
// context.getString(R.string.app_name);
return "NewPipe"; // context.getString(R.string.blank_page_summary);
} }
@DrawableRes @DrawableRes
@ -309,7 +315,7 @@ public abstract class Tab {
private String kioskId; private String kioskId;
private KioskTab() { private KioskTab() {
this(-1, "<no-id>"); this(-1, NO_ID);
} }
public KioskTab(final int kioskServiceId, final String kioskId) { public KioskTab(final int kioskServiceId, final String kioskId) {
@ -357,7 +363,7 @@ public abstract class Tab {
@Override @Override
protected void readDataFromJson(final JsonObject jsonObject) { protected void readDataFromJson(final JsonObject jsonObject) {
kioskServiceId = jsonObject.getInt(JSON_KIOSK_SERVICE_ID_KEY, -1); kioskServiceId = jsonObject.getInt(JSON_KIOSK_SERVICE_ID_KEY, -1);
kioskId = jsonObject.getString(JSON_KIOSK_ID_KEY, "<no-id>"); kioskId = jsonObject.getString(JSON_KIOSK_ID_KEY, NO_ID);
} }
@Override @Override
@ -395,7 +401,7 @@ public abstract class Tab {
private String channelName; private String channelName;
private ChannelTab() { private ChannelTab() {
this(-1, "<no-url>", "<no-name>"); this(-1, NO_URL, NO_NAME);
} }
public ChannelTab(final int channelServiceId, final String channelUrl, public ChannelTab(final int channelServiceId, final String channelUrl,
@ -440,8 +446,8 @@ public abstract class Tab {
@Override @Override
protected void readDataFromJson(final JsonObject jsonObject) { protected void readDataFromJson(final JsonObject jsonObject) {
channelServiceId = jsonObject.getInt(JSON_CHANNEL_SERVICE_ID_KEY, -1); channelServiceId = jsonObject.getInt(JSON_CHANNEL_SERVICE_ID_KEY, -1);
channelUrl = jsonObject.getString(JSON_CHANNEL_URL_KEY, "<no-url>"); channelUrl = jsonObject.getString(JSON_CHANNEL_URL_KEY, NO_URL);
channelName = jsonObject.getString(JSON_CHANNEL_NAME_KEY, "<no-name>"); channelName = jsonObject.getString(JSON_CHANNEL_NAME_KEY, NO_NAME);
} }
@Override @Override
@ -527,7 +533,7 @@ public abstract class Tab {
private LocalItemType playlistType; private LocalItemType playlistType;
private PlaylistTab() { private PlaylistTab() {
this(-1, "<no-name>"); this(-1, NO_NAME);
} }
public PlaylistTab(final long playlistId, final String playlistName) { public PlaylistTab(final long playlistId, final String playlistName) {
@ -535,7 +541,7 @@ public abstract class Tab {
this.playlistId = playlistId; this.playlistId = playlistId;
this.playlistType = LocalItemType.PLAYLIST_LOCAL_ITEM; this.playlistType = LocalItemType.PLAYLIST_LOCAL_ITEM;
this.playlistServiceId = -1; this.playlistServiceId = -1;
this.playlistUrl = "<no-url>"; this.playlistUrl = NO_URL;
} }
public PlaylistTab(final int playlistServiceId, final String playlistUrl, public PlaylistTab(final int playlistServiceId, final String playlistUrl,
@ -589,8 +595,8 @@ public abstract class Tab {
@Override @Override
protected void readDataFromJson(final JsonObject jsonObject) { protected void readDataFromJson(final JsonObject jsonObject) {
playlistServiceId = jsonObject.getInt(JSON_PLAYLIST_SERVICE_ID_KEY, -1); playlistServiceId = jsonObject.getInt(JSON_PLAYLIST_SERVICE_ID_KEY, -1);
playlistUrl = jsonObject.getString(JSON_PLAYLIST_URL_KEY, "<no-url>"); playlistUrl = jsonObject.getString(JSON_PLAYLIST_URL_KEY, NO_URL);
playlistName = jsonObject.getString(JSON_PLAYLIST_NAME_KEY, "<no-name>"); playlistName = jsonObject.getString(JSON_PLAYLIST_NAME_KEY, NO_NAME);
playlistId = jsonObject.getInt(JSON_PLAYLIST_ID_KEY, -1); playlistId = jsonObject.getInt(JSON_PLAYLIST_ID_KEY, -1);
playlistType = LocalItemType.valueOf( playlistType = LocalItemType.valueOf(
jsonObject.getString(JSON_PLAYLIST_TYPE_KEY, jsonObject.getString(JSON_PLAYLIST_TYPE_KEY,

View File

@ -108,10 +108,12 @@ public class FileStreamSAF extends SharpStream {
return true; return true;
} }
@Override
public boolean canSetLength() { public boolean canSetLength() {
return true; return true;
} }
@Override
public boolean canSeek() { public boolean canSeek() {
return true; return true;
} }
@ -131,10 +133,12 @@ public class FileStreamSAF extends SharpStream {
out.write(buffer, offset, count); out.write(buffer, offset, count);
} }
@Override
public void setLength(long length) throws IOException { public void setLength(long length) throws IOException {
channel.truncate(length); channel.truncate(length);
} }
@Override
public void seek(long offset) throws IOException { public void seek(long offset) throws IOException {
channel.position(offset); channel.position(offset);
} }

View File

@ -0,0 +1,2 @@
Removed MediaParser support to fix failing playback resume after buffering on Android 11+.
Disabled media tunneling on Philips QM16XE to fix playback problems.