Merge pull request #7166 from litetex/various-fixes-for-mediasession-player

Various fixes related to MediasessionManager
This commit is contained in:
Robin 2021-09-27 23:45:38 +02:00 committed by GitHub
commit f48ff610a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 215 additions and 102 deletions

View File

@ -17,6 +17,7 @@ import org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM
import org.schabi.newpipe.extractor.stream.StreamType.VIDEO_STREAM import org.schabi.newpipe.extractor.stream.StreamType.VIDEO_STREAM
import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.Localization
import org.schabi.newpipe.util.PicassoHelper import org.schabi.newpipe.util.PicassoHelper
import org.schabi.newpipe.util.StreamTypeUtil
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
data class StreamItem( data class StreamItem(
@ -58,8 +59,6 @@ data class StreamItem(
viewBinding.itemVideoTitleView.text = stream.title viewBinding.itemVideoTitleView.text = stream.title
viewBinding.itemUploaderView.text = stream.uploader viewBinding.itemUploaderView.text = stream.uploader
val isLiveStream = stream.streamType == LIVE_STREAM || stream.streamType == AUDIO_LIVE_STREAM
if (stream.duration > 0) { if (stream.duration > 0) {
viewBinding.itemDurationView.text = Localization.getDurationString(stream.duration) viewBinding.itemDurationView.text = Localization.getDurationString(stream.duration)
viewBinding.itemDurationView.setBackgroundColor( viewBinding.itemDurationView.setBackgroundColor(
@ -77,7 +76,7 @@ data class StreamItem(
} else { } else {
viewBinding.itemProgressView.visibility = View.GONE viewBinding.itemProgressView.visibility = View.GONE
} }
} else if (isLiveStream) { } else if (StreamTypeUtil.isLiveStream(stream.streamType)) {
viewBinding.itemDurationView.setText(R.string.duration_live) viewBinding.itemDurationView.setText(R.string.duration_live)
viewBinding.itemDurationView.setBackgroundColor( viewBinding.itemDurationView.setBackgroundColor(
ContextCompat.getColor( ContextCompat.getColor(

View File

@ -1,5 +1,53 @@
package org.schabi.newpipe.player; package org.schabi.newpipe.player;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_AD_INSERTION;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_INTERNAL;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_PERIOD_TRANSITION;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT;
import static com.google.android.exoplayer2.Player.DiscontinuityReason;
import static com.google.android.exoplayer2.Player.EventListener;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
import static com.google.android.exoplayer2.Player.RepeatMode;
import static org.schabi.newpipe.QueueItemMenuUtil.openPopupMenu;
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.ktx.ViewUtils.animateRotation;
import static org.schabi.newpipe.player.MainPlayer.ACTION_CLOSE;
import static org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD;
import static org.schabi.newpipe.player.MainPlayer.ACTION_FAST_REWIND;
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_NEXT;
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PAUSE;
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS;
import static org.schabi.newpipe.player.MainPlayer.ACTION_RECREATE_NOTIFICATION;
import static org.schabi.newpipe.player.MainPlayer.ACTION_REPEAT;
import static org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE;
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_BACKGROUND;
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_NONE;
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_POPUP;
import static org.schabi.newpipe.player.helper.PlayerHelper.buildCloseOverlayLayoutParams;
import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed;
import static org.schabi.newpipe.player.helper.PlayerHelper.getMinimizeOnExitAction;
import static org.schabi.newpipe.player.helper.PlayerHelper.getMinimumVideoHeight;
import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString;
import static org.schabi.newpipe.player.helper.PlayerHelper.globalScreenOrientationLocked;
import static org.schabi.newpipe.player.helper.PlayerHelper.isPlaybackResumeEnabled;
import static org.schabi.newpipe.player.helper.PlayerHelper.nextRepeatMode;
import static org.schabi.newpipe.player.helper.PlayerHelper.nextResizeModeAndSaveToPrefs;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePlaybackParametersFromPrefs;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePlayerTypeFromIntent;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePopupLayoutParamsFromPrefs;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrieveSeekDurationFromPreferences;
import static org.schabi.newpipe.player.helper.PlayerHelper.savePlaybackParametersToPrefs;
import static org.schabi.newpipe.util.ListHelper.getPopupResolutionIndex;
import static org.schabi.newpipe.util.ListHelper.getResolutionIndex;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import static org.schabi.newpipe.util.Localization.containsCaseInsensitive;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
@ -94,7 +142,6 @@ import org.schabi.newpipe.databinding.PlayerPopupCloseOverlayBinding;
import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamSegment; import org.schabi.newpipe.extractor.stream.StreamSegment;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.stream.VideoStream; import org.schabi.newpipe.extractor.stream.VideoStream;
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.fragments.detail.VideoDetailFragment; import org.schabi.newpipe.fragments.detail.VideoDetailFragment;
@ -127,12 +174,13 @@ import org.schabi.newpipe.player.resolver.MediaSourceTag;
import org.schabi.newpipe.player.resolver.VideoPlaybackResolver; import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper; import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper;
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHolder; import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHolder;
import org.schabi.newpipe.util.StreamTypeUtil;
import org.schabi.newpipe.util.DeviceUtils; import org.schabi.newpipe.util.DeviceUtils;
import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.ListHelper; import org.schabi.newpipe.util.ListHelper;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.PicassoHelper; import org.schabi.newpipe.util.PicassoHelper;
import org.schabi.newpipe.util.SerializedCache; import org.schabi.newpipe.util.SerializedCache;
import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.external_communication.ShareUtils; import org.schabi.newpipe.util.external_communication.ShareUtils;
import org.schabi.newpipe.views.ExpandableSurfaceView; import org.schabi.newpipe.views.ExpandableSurfaceView;
@ -140,6 +188,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observable;
@ -147,54 +196,6 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.disposables.SerialDisposable; import io.reactivex.rxjava3.disposables.SerialDisposable;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_AD_INSERTION;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_INTERNAL;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_PERIOD_TRANSITION;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK;
import static com.google.android.exoplayer2.Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT;
import static com.google.android.exoplayer2.Player.DiscontinuityReason;
import static com.google.android.exoplayer2.Player.EventListener;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_OFF;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ONE;
import static com.google.android.exoplayer2.Player.RepeatMode;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.schabi.newpipe.QueueItemMenuUtil.openPopupMenu;
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import static org.schabi.newpipe.ktx.ViewUtils.animate;
import static org.schabi.newpipe.ktx.ViewUtils.animateRotation;
import static org.schabi.newpipe.player.MainPlayer.ACTION_CLOSE;
import static org.schabi.newpipe.player.MainPlayer.ACTION_FAST_FORWARD;
import static org.schabi.newpipe.player.MainPlayer.ACTION_FAST_REWIND;
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_NEXT;
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PAUSE;
import static org.schabi.newpipe.player.MainPlayer.ACTION_PLAY_PREVIOUS;
import static org.schabi.newpipe.player.MainPlayer.ACTION_RECREATE_NOTIFICATION;
import static org.schabi.newpipe.player.MainPlayer.ACTION_REPEAT;
import static org.schabi.newpipe.player.MainPlayer.ACTION_SHUFFLE;
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_BACKGROUND;
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_NONE;
import static org.schabi.newpipe.player.helper.PlayerHelper.MinimizeMode.MINIMIZE_ON_EXIT_MODE_POPUP;
import static org.schabi.newpipe.player.helper.PlayerHelper.buildCloseOverlayLayoutParams;
import static org.schabi.newpipe.player.helper.PlayerHelper.formatSpeed;
import static org.schabi.newpipe.player.helper.PlayerHelper.getMinimizeOnExitAction;
import static org.schabi.newpipe.player.helper.PlayerHelper.getMinimumVideoHeight;
import static org.schabi.newpipe.player.helper.PlayerHelper.getTimeString;
import static org.schabi.newpipe.player.helper.PlayerHelper.globalScreenOrientationLocked;
import static org.schabi.newpipe.player.helper.PlayerHelper.isPlaybackResumeEnabled;
import static org.schabi.newpipe.player.helper.PlayerHelper.nextRepeatMode;
import static org.schabi.newpipe.player.helper.PlayerHelper.nextResizeModeAndSaveToPrefs;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePlaybackParametersFromPrefs;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePlayerTypeFromIntent;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrievePopupLayoutParamsFromPrefs;
import static org.schabi.newpipe.player.helper.PlayerHelper.retrieveSeekDurationFromPreferences;
import static org.schabi.newpipe.player.helper.PlayerHelper.savePlaybackParametersToPrefs;
import static org.schabi.newpipe.util.ListHelper.getPopupResolutionIndex;
import static org.schabi.newpipe.util.ListHelper.getResolutionIndex;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
import static org.schabi.newpipe.util.Localization.containsCaseInsensitive;
public final class Player implements public final class Player implements
EventListener, EventListener,
PlaybackListener, PlaybackListener,
@ -1622,12 +1623,6 @@ public final class Player implements
if (isQueueVisible) { if (isQueueVisible) {
updateQueueTime(currentProgress); updateQueueTime(currentProgress);
} }
final boolean showThumbnail = prefs.getBoolean(
context.getString(R.string.show_thumbnail_key), true);
// setMetadata only updates the metadata when any of the metadata keys are null
mediaSessionManager.setMetadata(getVideoTitle(), getUploaderName(),
showThumbnail ? getThumbnail() : null, duration);
} }
private void startProgressLoop() { private void startProgressLoop() {
@ -1652,8 +1647,8 @@ public final class Player implements
// TODO: revert #6307 when introducing proper HLS support // TODO: revert #6307 when introducing proper HLS support
final int duration; final int duration;
if (currentItem != null if (currentItem != null
&& currentItem.getStreamType() != StreamType.AUDIO_LIVE_STREAM && !StreamTypeUtil.isLiveStream(currentItem.getStreamType())
&& currentItem.getStreamType() != StreamType.LIVE_STREAM) { ) {
// convert seconds to milliseconds // convert seconds to milliseconds
duration = (int) (currentItem.getDuration() * 1000); duration = (int) (currentItem.getDuration() * 1000);
} else { } else {
@ -2946,6 +2941,18 @@ public final class Player implements
tag.getMetadata().getPreviewFrames()); tag.getMetadata().getPreviewFrames());
NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false); NotificationUtil.getInstance().createNotificationIfNeededAndUpdate(this, false);
final boolean showThumbnail = prefs.getBoolean(
context.getString(R.string.show_thumbnail_key), true);
mediaSessionManager.setMetadata(
getVideoTitle(),
getUploaderName(),
showThumbnail ? Optional.ofNullable(getThumbnail()) : Optional.empty(),
StreamTypeUtil.isLiveStream(tag.getMetadata().getStreamType())
? -1
: tag.getMetadata().getDuration()
);
notifyMetadataUpdateToListeners(); notifyMetadataUpdateToListeners();
if (areSegmentsVisible) { if (areSegmentsVisible) {
@ -3023,9 +3030,11 @@ public final class Player implements
@Nullable @Nullable
public Bitmap getThumbnail() { public Bitmap getThumbnail() {
return currentThumbnail == null if (currentThumbnail == null) {
? BitmapFactory.decodeResource(context.getResources(), R.drawable.dummy_thumbnail) currentThumbnail = BitmapFactory.decodeResource(
: currentThumbnail; context.getResources(), R.drawable.dummy_thumbnail);
}
return currentThumbnail;
} }
//endregion //endregion

View File

@ -21,6 +21,8 @@ import org.schabi.newpipe.player.mediasession.MediaSessionCallback;
import org.schabi.newpipe.player.mediasession.PlayQueueNavigator; import org.schabi.newpipe.player.mediasession.PlayQueueNavigator;
import org.schabi.newpipe.player.mediasession.PlayQueuePlaybackController; import org.schabi.newpipe.player.mediasession.PlayQueuePlaybackController;
import java.util.Optional;
public class MediaSessionManager { public class MediaSessionManager {
private static final String TAG = MediaSessionManager.class.getSimpleName(); private static final String TAG = MediaSessionManager.class.getSimpleName();
public static final boolean DEBUG = MainActivity.DEBUG; public static final boolean DEBUG = MainActivity.DEBUG;
@ -30,6 +32,9 @@ public class MediaSessionManager {
@NonNull @NonNull
private final MediaSessionConnector sessionConnector; private final MediaSessionConnector sessionConnector;
private int lastTitleHashCode;
private int lastArtistHashCode;
private long lastDuration;
private int lastAlbumArtHashCode; private int lastAlbumArtHashCode;
public MediaSessionManager(@NonNull final Context context, public MediaSessionManager(@NonNull final Context context,
@ -65,46 +70,126 @@ public class MediaSessionManager {
return mediaSession.getSessionToken(); return mediaSession.getSessionToken();
} }
public void setMetadata(final String title, /**
final String artist, * sets the Metadata - if required.
final Bitmap albumArt, *
final long duration) { * @param title {@link MediaMetadataCompat#METADATA_KEY_TITLE}
if (albumArt == null || !mediaSession.isActive()) { * @param artist {@link MediaMetadataCompat#METADATA_KEY_ARTIST}
* @param optAlbumArt {@link MediaMetadataCompat#METADATA_KEY_ALBUM_ART}
* @param duration {@link MediaMetadataCompat#METADATA_KEY_DURATION}
* - should be a negative value for unknown durations, e.g. for livestreams
*/
public void setMetadata(@NonNull final String title,
@NonNull final String artist,
@NonNull final Optional<Bitmap> optAlbumArt,
final long duration
) {
if (DEBUG) {
Log.d(TAG, "setMetadata called:"
+ " t: " + title
+ " a: " + artist
+ " thumb: " + (
optAlbumArt.isPresent()
? optAlbumArt.get().hashCode()
: "<none>")
+ " d: " + duration);
}
if (!mediaSession.isActive()) {
if (DEBUG) {
Log.d(TAG, "setMetadata: mediaSession not active - exiting");
}
return;
}
if (!checkIfMetadataShouldBeSet(title, artist, optAlbumArt, duration)) {
if (DEBUG) {
Log.d(TAG, "setMetadata: No update required - exiting");
}
return; return;
} }
if (DEBUG) {
Log.d(TAG, "setMetadata: N_Metadata update:"
+ " t: " + title
+ " a: " + artist
+ " thumb: " + (
optAlbumArt.isPresent()
? optAlbumArt.get().hashCode()
: "<none>")
+ " d: " + duration);
}
final MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration);
if (optAlbumArt.isPresent()) {
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, optAlbumArt.get());
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, optAlbumArt.get());
}
mediaSession.setMetadata(builder.build());
lastTitleHashCode = title.hashCode();
lastArtistHashCode = artist.hashCode();
lastDuration = duration;
if (optAlbumArt.isPresent()) {
lastAlbumArtHashCode = optAlbumArt.get().hashCode();
}
}
private boolean checkIfMetadataShouldBeSet(
@NonNull final String title,
@NonNull final String artist,
@NonNull final Optional<Bitmap> optAlbumArt,
final long duration
) {
// Check if the values have changed since the last time
if (title.hashCode() != lastTitleHashCode
|| artist.hashCode() != lastArtistHashCode
|| duration != lastDuration
|| (optAlbumArt.isPresent() && optAlbumArt.get().hashCode() != lastAlbumArtHashCode)
) {
if (DEBUG) {
Log.d(TAG,
"checkIfMetadataShouldBeSet: true - reason: changed values since last");
}
return true;
}
// Check if the currently set metadata is valid
if (getMetadataTitle() == null
|| getMetadataArtist() == null
// Note that the duration can be <= 0 for live streams
) {
if (DEBUG) {
if (getMetadataTitle() == null) {
Log.d(TAG,
"N_getMetadataTitle: title == null");
} else if (getMetadataArtist() == null) {
Log.d(TAG,
"N_getMetadataArtist: artist == null");
}
}
return true;
}
// If we got an album art check if the current set AlbumArt is null
if (optAlbumArt.isPresent() && getMetadataAlbumArt() == null) {
if (DEBUG) { if (DEBUG) {
if (getMetadataAlbumArt() == null) { if (getMetadataAlbumArt() == null) {
Log.d(TAG, "N_getMetadataAlbumArt: thumb == null"); Log.d(TAG, "N_getMetadataAlbumArt: thumb == null");
} }
if (getMetadataTitle() == null) {
Log.d(TAG, "N_getMetadataTitle: title == null");
}
if (getMetadataArtist() == null) {
Log.d(TAG, "N_getMetadataArtist: artist == null");
}
if (getMetadataDuration() <= 1) {
Log.d(TAG, "N_getMetadataDuration: duration <= 1; " + getMetadataDuration());
} }
return true;
} }
if (getMetadataAlbumArt() == null || getMetadataTitle() == null // Default - no update required
|| getMetadataArtist() == null || getMetadataDuration() <= 1 return false;
|| albumArt.hashCode() != lastAlbumArtHashCode) {
if (DEBUG) {
Log.d(TAG, "setMetadata: N_Metadata update: t: " + title + " a: " + artist
+ " thumb: " + albumArt.hashCode() + " d: " + duration);
} }
mediaSession.setMetadata(new MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, albumArt)
.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, albumArt)
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration).build());
lastAlbumArtHashCode = albumArt.hashCode();
}
}
private Bitmap getMetadataAlbumArt() { private Bitmap getMetadataAlbumArt() {
return mediaSession.getController().getMetadata() return mediaSession.getController().getMetadata()
@ -121,11 +206,6 @@ public class MediaSessionManager {
.getString(MediaMetadataCompat.METADATA_KEY_ARTIST); .getString(MediaMetadataCompat.METADATA_KEY_ARTIST);
} }
private long getMetadataDuration() {
return mediaSession.getController().getMetadata()
.getLong(MediaMetadataCompat.METADATA_KEY_DURATION);
}
/** /**
* Should be called on player destruction to prevent leakage. * Should be called on player destruction to prevent leakage.
*/ */

View File

@ -14,6 +14,7 @@ import com.google.android.exoplayer2.util.Util;
import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.player.helper.PlayerDataSource; import org.schabi.newpipe.player.helper.PlayerDataSource;
import org.schabi.newpipe.util.StreamTypeUtil;
public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> { public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
@ -21,7 +22,7 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
default MediaSource maybeBuildLiveMediaSource(@NonNull final PlayerDataSource dataSource, default MediaSource maybeBuildLiveMediaSource(@NonNull final PlayerDataSource dataSource,
@NonNull final StreamInfo info) { @NonNull final StreamInfo info) {
final StreamType streamType = info.getStreamType(); final StreamType streamType = info.getStreamType();
if (!(streamType == StreamType.AUDIO_LIVE_STREAM || streamType == StreamType.LIVE_STREAM)) { if (!StreamTypeUtil.isLiveStream(streamType)) {
return null; return null;
} }

View File

@ -0,0 +1,24 @@
package org.schabi.newpipe.util;
import org.schabi.newpipe.extractor.stream.StreamType;
/**
* Utility class for {@link org.schabi.newpipe.extractor.stream.StreamType}.
*/
public final class StreamTypeUtil {
private StreamTypeUtil() {
// No impl pls
}
/**
* Checks if the streamType is a livestream.
*
* @param streamType
* @return <code>true</code> when the streamType is a
* {@link StreamType#LIVE_STREAM} or {@link StreamType#AUDIO_LIVE_STREAM}
*/
public static boolean isLiveStream(final StreamType streamType) {
return streamType == StreamType.LIVE_STREAM
|| streamType == StreamType.AUDIO_LIVE_STREAM;
}
}