Addressed review comments
This commit is contained in:
parent
c8ccc60047
commit
9d750edf5f
|
@ -45,7 +45,6 @@ import static org.schabi.newpipe.player.notification.NotificationConstants.ACTIO
|
||||||
import static org.schabi.newpipe.util.ListHelper.getPopupResolutionIndex;
|
import static org.schabi.newpipe.util.ListHelper.getPopupResolutionIndex;
|
||||||
import static org.schabi.newpipe.util.ListHelper.getResolutionIndex;
|
import static org.schabi.newpipe.util.ListHelper.getResolutionIndex;
|
||||||
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
|
@ -87,8 +86,8 @@ import org.schabi.newpipe.databinding.PlayerBinding;
|
||||||
import org.schabi.newpipe.error.ErrorInfo;
|
import org.schabi.newpipe.error.ErrorInfo;
|
||||||
import org.schabi.newpipe.error.ErrorUtil;
|
import org.schabi.newpipe.error.ErrorUtil;
|
||||||
import org.schabi.newpipe.error.UserAction;
|
import org.schabi.newpipe.error.UserAction;
|
||||||
import org.schabi.newpipe.extractor.stream.AudioStream;
|
|
||||||
import org.schabi.newpipe.extractor.Image;
|
import org.schabi.newpipe.extractor.Image;
|
||||||
|
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||||
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.extractor.stream.VideoStream;
|
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||||
|
@ -119,9 +118,9 @@ import org.schabi.newpipe.player.ui.VideoPlayerUi;
|
||||||
import org.schabi.newpipe.util.DependentPreferenceHelper;
|
import org.schabi.newpipe.util.DependentPreferenceHelper;
|
||||||
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.image.PicassoHelper;
|
|
||||||
import org.schabi.newpipe.util.SerializedCache;
|
import org.schabi.newpipe.util.SerializedCache;
|
||||||
import org.schabi.newpipe.util.StreamTypeUtil;
|
import org.schabi.newpipe.util.StreamTypeUtil;
|
||||||
|
import org.schabi.newpipe.util.image.PicassoHelper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -416,9 +415,12 @@ public final class Player implements PlaybackListener, Listener {
|
||||||
== com.google.android.exoplayer2.Player.STATE_IDLE) {
|
== com.google.android.exoplayer2.Player.STATE_IDLE) {
|
||||||
simpleExoPlayer.prepare();
|
simpleExoPlayer.prepare();
|
||||||
}
|
}
|
||||||
|
// Seeks to a specific index and position in the player if the queue index has changed.
|
||||||
if (playQueue.getIndex() != newQueue.getIndex()) {
|
if (playQueue.getIndex() != newQueue.getIndex()) {
|
||||||
simpleExoPlayer.seekTo(newQueue.getIndex(),
|
final PlayQueueItem queueItem = newQueue.getItem();
|
||||||
requireNonNull(newQueue.getItem()).getRecoveryPosition());
|
if (queueItem != null) {
|
||||||
|
simpleExoPlayer.seekTo(newQueue.getIndex(), queueItem.getRecoveryPosition());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
simpleExoPlayer.setPlayWhenReady(playWhenReady);
|
simpleExoPlayer.setPlayWhenReady(playWhenReady);
|
||||||
|
|
||||||
|
|
|
@ -39,28 +39,18 @@ import java.lang.ref.WeakReference
|
||||||
* One service for all players.
|
* One service for all players.
|
||||||
*/
|
*/
|
||||||
class PlayerService : MediaBrowserServiceCompat() {
|
class PlayerService : MediaBrowserServiceCompat() {
|
||||||
private val player: Player by lazy {
|
private var player: Player? = null
|
||||||
Player(this).apply {
|
|
||||||
/*
|
|
||||||
Create the player notification and start immediately the service in foreground,
|
|
||||||
otherwise if nothing is played or initializing the player and its components (especially
|
|
||||||
loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the
|
|
||||||
service would never be put in the foreground while we said to the system we would do so
|
|
||||||
*/
|
|
||||||
UIs()[NotificationPlayerUi::class.java].ifPresent {
|
|
||||||
it.createNotificationAndStartForeground()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val mBinder: IBinder = LocalBinder(this)
|
private val mBinder: IBinder = LocalBinder(this)
|
||||||
private val compositeDisposableLoadChildren = CompositeDisposable()
|
private val disposables = CompositeDisposable()
|
||||||
private var mediaBrowserConnector: MediaBrowserConnector? = null
|
private var _mediaBrowserConnector: MediaBrowserConnector? = null
|
||||||
|
private val mediaBrowserConnector: MediaBrowserConnector
|
||||||
get() {
|
get() {
|
||||||
if (field == null) {
|
return _mediaBrowserConnector ?: run {
|
||||||
field = MediaBrowserConnector(this)
|
val newMediaBrowserConnector = MediaBrowserConnector(this)
|
||||||
|
_mediaBrowserConnector = newMediaBrowserConnector
|
||||||
|
newMediaBrowserConnector
|
||||||
}
|
}
|
||||||
return field
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val sessionConnector: MediaSessionConnector?
|
val sessionConnector: MediaSessionConnector?
|
||||||
|
@ -78,13 +68,14 @@ class PlayerService : MediaBrowserServiceCompat() {
|
||||||
Localization.assureCorrectAppLanguage(this)
|
Localization.assureCorrectAppLanguage(this)
|
||||||
ThemeHelper.setTheme(this)
|
ThemeHelper.setTheme(this)
|
||||||
|
|
||||||
|
player = Player(this)
|
||||||
/*
|
/*
|
||||||
Create the player notification and start immediately the service in foreground,
|
Create the player notification and start immediately the service in foreground,
|
||||||
otherwise if nothing is played or initializing the player and its components (especially
|
otherwise if nothing is played or initializing the player and its components (especially
|
||||||
loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the
|
loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the
|
||||||
service would never be put in the foreground while we said to the system we would do so
|
service would never be put in the foreground while we said to the system we would do so
|
||||||
*/
|
*/
|
||||||
player.UIs()[NotificationPlayerUi::class.java].ifPresent {
|
player!!.UIs()[NotificationPlayerUi::class.java].ifPresent {
|
||||||
it.createNotificationAndStartForeground()
|
it.createNotificationAndStartForeground()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,11 +103,11 @@ class PlayerService : MediaBrowserServiceCompat() {
|
||||||
If the service is already started in foreground, requesting it to be started shouldn't
|
If the service is already started in foreground, requesting it to be started shouldn't
|
||||||
do anything
|
do anything
|
||||||
*/
|
*/
|
||||||
player.UIs()[NotificationPlayerUi::class.java].ifPresent {
|
player?.UIs()?.get(NotificationPlayerUi::class.java)?.ifPresent {
|
||||||
it.createNotificationAndStartForeground()
|
it.createNotificationAndStartForeground()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Intent.ACTION_MEDIA_BUTTON == intent.action && (player.playQueue == null)) {
|
if (Intent.ACTION_MEDIA_BUTTON == intent.action && (player?.playQueue == null)) {
|
||||||
/*
|
/*
|
||||||
No need to process media button's actions if the player is not working, otherwise
|
No need to process media button's actions if the player is not working, otherwise
|
||||||
the player service would strangely start with nothing to play
|
the player service would strangely start with nothing to play
|
||||||
|
@ -127,8 +118,8 @@ class PlayerService : MediaBrowserServiceCompat() {
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
player.handleIntent(intent)
|
player?.handleIntent(intent)
|
||||||
player.UIs()[MediaSessionPlayerUi::class.java].ifPresent {
|
player?.UIs()?.get(MediaSessionPlayerUi::class.java)?.ifPresent {
|
||||||
it.handleMediaButtonIntent(intent)
|
it.handleMediaButtonIntent(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,17 +131,17 @@ class PlayerService : MediaBrowserServiceCompat() {
|
||||||
Log.d(TAG, "stopForImmediateReusing() called")
|
Log.d(TAG, "stopForImmediateReusing() called")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!player.exoPlayerIsNull()) {
|
if (player != null && !player!!.exoPlayerIsNull()) {
|
||||||
// Releases wifi & cpu, disables keepScreenOn, etc.
|
// Releases wifi & cpu, disables keepScreenOn, etc.
|
||||||
// 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
|
||||||
player.smoothStopForImmediateReusing()
|
player?.smoothStopForImmediateReusing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTaskRemoved(rootIntent: Intent) {
|
override fun onTaskRemoved(rootIntent: Intent) {
|
||||||
super.onTaskRemoved(rootIntent)
|
super.onTaskRemoved(rootIntent)
|
||||||
if (!player.videoPlayerSelected()) {
|
if (player != null && !player!!.videoPlayerSelected()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
onDestroy()
|
onDestroy()
|
||||||
|
@ -166,14 +157,15 @@ class PlayerService : MediaBrowserServiceCompat() {
|
||||||
|
|
||||||
cleanup()
|
cleanup()
|
||||||
|
|
||||||
mediaBrowserConnector?.release()
|
mediaBrowserConnector.release()
|
||||||
mediaBrowserConnector = null
|
_mediaBrowserConnector = null
|
||||||
|
|
||||||
compositeDisposableLoadChildren.clear()
|
disposables.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cleanup() {
|
private fun cleanup() {
|
||||||
player.destroy()
|
player?.destroy()
|
||||||
|
player = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopService() {
|
fun stopService() {
|
||||||
|
@ -187,7 +179,7 @@ class PlayerService : MediaBrowserServiceCompat() {
|
||||||
|
|
||||||
override fun onBind(intent: Intent): IBinder = mBinder
|
override fun onBind(intent: Intent): IBinder = mBinder
|
||||||
|
|
||||||
// MediaBrowserServiceCompat methods
|
// MediaBrowserServiceCompat methods (they defer function calls to mediaBrowserConnector)
|
||||||
override fun onGetRoot(
|
override fun onGetRoot(
|
||||||
clientPackageName: String,
|
clientPackageName: String,
|
||||||
clientUid: Int,
|
clientUid: Int,
|
||||||
|
@ -204,7 +196,7 @@ class PlayerService : MediaBrowserServiceCompat() {
|
||||||
it.onLoadChildren(parentId).subscribe { mediaItems ->
|
it.onLoadChildren(parentId).subscribe { mediaItems ->
|
||||||
result.sendResult(mediaItems)
|
result.sendResult(mediaItems)
|
||||||
}
|
}
|
||||||
compositeDisposableLoadChildren.add(disposable)
|
disposables.add(disposable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,20 +125,20 @@ class MediaBrowserConnector(
|
||||||
|
|
||||||
private fun createPlaylistMediaItem(playlist: PlaylistLocalItem): MediaBrowserCompat.MediaItem {
|
private fun createPlaylistMediaItem(playlist: PlaylistLocalItem): MediaBrowserCompat.MediaItem {
|
||||||
val builder = MediaDescriptionCompat.Builder()
|
val builder = MediaDescriptionCompat.Builder()
|
||||||
val isRemote = playlist is PlaylistRemoteEntity
|
builder
|
||||||
builder.setMediaId(createMediaIdForInfoItem(isRemote, playlist.uid))
|
.setMediaId(createMediaIdForInfoItem(playlist is PlaylistRemoteEntity, playlist.uid))
|
||||||
.setTitle(playlist.orderingName)
|
.setTitle(playlist.orderingName)
|
||||||
.setIconUri(Uri.parse(playlist.thumbnailUrl))
|
.setIconUri(playlist.thumbnailUrl?.let { Uri.parse(it) })
|
||||||
|
|
||||||
val extras = Bundle()
|
val extras = Bundle()
|
||||||
extras.putString(
|
extras.putString(
|
||||||
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
|
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
|
||||||
playerService.resources.getString(R.string.tab_bookmarks)
|
playerService.resources.getString(R.string.tab_bookmarks),
|
||||||
)
|
)
|
||||||
builder.setExtras(extras)
|
builder.setExtras(extras)
|
||||||
return MediaBrowserCompat.MediaItem(
|
return MediaBrowserCompat.MediaItem(
|
||||||
builder.build(),
|
builder.build(),
|
||||||
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE
|
MediaBrowserCompat.MediaItem.FLAG_BROWSABLE,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue