Improve code formatting, annotate more fields and methods
Also simplify logic in MediaBrowserConnector.extractPlayQueueFromMediaId, suppress some Sonar warnings as they could not be solved, and use explicit types in some variables.
This commit is contained in:
parent
fd0ca907aa
commit
f4e5920156
|
@ -431,6 +431,6 @@
|
||||||
<meta-data android:name="com.google.android.gms.car.application"
|
<meta-data android:name="com.google.android.gms.car.application"
|
||||||
android:resource="@xml/automotive_app_desc" />
|
android:resource="@xml/automotive_app_desc" />
|
||||||
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
|
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon"
|
||||||
android:resource="@mipmap/ic_launcher" />
|
android:resource="@mipmap/ic_launcher" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -31,7 +31,12 @@ data class StreamHistoryEntry(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toStreamInfoItem(): StreamInfoItem {
|
fun toStreamInfoItem(): StreamInfoItem {
|
||||||
val item = StreamInfoItem(streamEntity.serviceId, streamEntity.url, streamEntity.title, streamEntity.streamType)
|
val item = StreamInfoItem(
|
||||||
|
streamEntity.serviceId,
|
||||||
|
streamEntity.url,
|
||||||
|
streamEntity.title,
|
||||||
|
streamEntity.streamType
|
||||||
|
)
|
||||||
item.duration = streamEntity.duration
|
item.duration = streamEntity.duration
|
||||||
item.uploaderName = streamEntity.uploader
|
item.uploaderName = streamEntity.uploader
|
||||||
item.uploaderUrl = streamEntity.uploaderUrl
|
item.uploaderUrl = streamEntity.uploaderUrl
|
||||||
|
|
|
@ -43,8 +43,10 @@ import org.schabi.newpipe.util.ThemeHelper;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One service for all players.
|
* One service for all players.
|
||||||
|
@ -53,6 +55,7 @@ public final class PlayerService extends MediaBrowserServiceCompat {
|
||||||
private static final String TAG = PlayerService.class.getSimpleName();
|
private static final String TAG = PlayerService.class.getSimpleName();
|
||||||
private static final boolean DEBUG = Player.DEBUG;
|
private static final boolean DEBUG = Player.DEBUG;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Player player;
|
private Player player;
|
||||||
|
|
||||||
private final IBinder mBinder = new PlayerService.LocalBinder(this);
|
private final IBinder mBinder = new PlayerService.LocalBinder(this);
|
||||||
|
@ -79,7 +82,7 @@ public final class PlayerService extends MediaBrowserServiceCompat {
|
||||||
mediaBrowserConnector = new MediaBrowserConnector(this);
|
mediaBrowserConnector = new MediaBrowserConnector(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializePlayer() {
|
private void initializePlayerIfNeeded() {
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
player = new Player(this);
|
player = new Player(this);
|
||||||
/*
|
/*
|
||||||
|
@ -93,6 +96,9 @@ public final class PlayerService extends MediaBrowserServiceCompat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Suppress Sonar warning to not always return the same value, as we need to do some actions
|
||||||
|
// before returning
|
||||||
|
@SuppressWarnings("squid:S3516")
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(final Intent intent, final int flags, final int startId) {
|
public int onStartCommand(final Intent intent, final int flags, final int startId) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
@ -127,8 +133,8 @@ public final class PlayerService extends MediaBrowserServiceCompat {
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
initializePlayer();
|
initializePlayerIfNeeded();
|
||||||
player.handleIntent(intent);
|
Objects.requireNonNull(player).handleIntent(intent);
|
||||||
player.UIs().get(MediaSessionPlayerUi.class)
|
player.UIs().get(MediaSessionPlayerUi.class)
|
||||||
.ifPresent(ui -> ui.handleMediaButtonIntent(intent));
|
.ifPresent(ui -> ui.handleMediaButtonIntent(intent));
|
||||||
|
|
||||||
|
@ -164,11 +170,14 @@ public final class PlayerService extends MediaBrowserServiceCompat {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "destroy() called");
|
Log.d(TAG, "destroy() called");
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
if (mediaBrowserConnector != null) {
|
if (mediaBrowserConnector != null) {
|
||||||
mediaBrowserConnector.release();
|
mediaBrowserConnector.release();
|
||||||
mediaBrowserConnector = null;
|
mediaBrowserConnector = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
compositeDisposableLoadChildren.clear();
|
compositeDisposableLoadChildren.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,36 +199,23 @@ public final class PlayerService extends MediaBrowserServiceCompat {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(final Intent intent) {
|
public IBinder onBind(@NonNull final Intent intent) {
|
||||||
if (SERVICE_INTERFACE.equals(intent.getAction())) {
|
if (SERVICE_INTERFACE.equals(intent.getAction())) {
|
||||||
return super.onBind(intent);
|
return super.onBind(intent);
|
||||||
}
|
}
|
||||||
return mBinder;
|
return mBinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public MediaSessionConnector getSessionConnector() {
|
public MediaSessionConnector getSessionConnector() {
|
||||||
return mediaBrowserConnector.getSessionConnector();
|
return mediaBrowserConnector.getSessionConnector();
|
||||||
}
|
}
|
||||||
public static class LocalBinder extends Binder {
|
|
||||||
private final WeakReference<PlayerService> playerService;
|
|
||||||
|
|
||||||
LocalBinder(final PlayerService playerService) {
|
|
||||||
this.playerService = new WeakReference<>(playerService);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlayerService getService() {
|
|
||||||
return playerService.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Player getPlayer() {
|
|
||||||
return playerService.get().player;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MediaBrowserServiceCompat methods
|
// MediaBrowserServiceCompat methods
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public BrowserRoot onGetRoot(@NonNull final String clientPackageName, final int clientUid,
|
public BrowserRoot onGetRoot(@NonNull final String clientPackageName,
|
||||||
|
final int clientUid,
|
||||||
@Nullable final Bundle rootHints) {
|
@Nullable final Bundle rootHints) {
|
||||||
return mediaBrowserConnector.onGetRoot(clientPackageName, clientUid, rootHints);
|
return mediaBrowserConnector.onGetRoot(clientPackageName, clientUid, rootHints);
|
||||||
}
|
}
|
||||||
|
@ -228,8 +224,26 @@ public final class PlayerService extends MediaBrowserServiceCompat {
|
||||||
public void onLoadChildren(@NonNull final String parentId,
|
public void onLoadChildren(@NonNull final String parentId,
|
||||||
@NonNull final Result<List<MediaItem>> result) {
|
@NonNull final Result<List<MediaItem>> result) {
|
||||||
result.detach();
|
result.detach();
|
||||||
final var disposable = mediaBrowserConnector.onLoadChildren(parentId)
|
final Disposable disposable = mediaBrowserConnector.onLoadChildren(parentId)
|
||||||
.subscribe(result::sendResult);
|
.subscribe(result::sendResult);
|
||||||
compositeDisposableLoadChildren.add(disposable);
|
compositeDisposableLoadChildren.add(disposable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class LocalBinder extends Binder {
|
||||||
|
private final WeakReference<PlayerService> playerService;
|
||||||
|
|
||||||
|
LocalBinder(final PlayerService playerService) {
|
||||||
|
this.playerService = new WeakReference<>(playerService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public PlayerService getService() {
|
||||||
|
return playerService.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Player getPlayer() {
|
||||||
|
return playerService.get().player;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,14 @@ import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
|
||||||
import org.schabi.newpipe.NewPipeDatabase;
|
import org.schabi.newpipe.NewPipeDatabase;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.database.AppDatabase;
|
import org.schabi.newpipe.database.AppDatabase;
|
||||||
|
import org.schabi.newpipe.database.history.dao.StreamHistoryDAO;
|
||||||
import org.schabi.newpipe.database.history.model.StreamHistoryEntry;
|
import org.schabi.newpipe.database.history.model.StreamHistoryEntry;
|
||||||
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
|
import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry;
|
||||||
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
|
import org.schabi.newpipe.database.playlist.PlaylistStreamEntry;
|
||||||
import org.schabi.newpipe.error.ErrorInfo;
|
import org.schabi.newpipe.error.ErrorInfo;
|
||||||
import org.schabi.newpipe.error.UserAction;
|
import org.schabi.newpipe.error.UserAction;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
||||||
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
||||||
import org.schabi.newpipe.player.PlayerService;
|
import org.schabi.newpipe.player.PlayerService;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||||
|
@ -44,11 +46,15 @@ import io.reactivex.rxjava3.core.Single;
|
||||||
import io.reactivex.rxjava3.disposables.Disposable;
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
|
||||||
public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPreparer {
|
public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPreparer {
|
||||||
|
|
||||||
private static final String TAG = MediaBrowserConnector.class.getSimpleName();
|
private static final String TAG = MediaBrowserConnector.class.getSimpleName();
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private final PlayerService playerService;
|
private final PlayerService playerService;
|
||||||
private final @NonNull MediaSessionConnector sessionConnector;
|
@NonNull
|
||||||
private final @NonNull MediaSessionCompat mediaSession;
|
private final MediaSessionConnector sessionConnector;
|
||||||
|
@NonNull
|
||||||
|
private final MediaSessionCompat mediaSession;
|
||||||
|
|
||||||
private AppDatabase database;
|
private AppDatabase database;
|
||||||
private LocalPlaylistManager localPlaylistManager;
|
private LocalPlaylistManager localPlaylistManager;
|
||||||
|
@ -63,7 +69,8 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
playerService.setSessionToken(mediaSession.getSessionToken());
|
playerService.setSessionToken(mediaSession.getSessionToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull MediaSessionConnector getSessionConnector() {
|
@NonNull
|
||||||
|
public MediaSessionConnector getSessionConnector() {
|
||||||
return sessionConnector;
|
return sessionConnector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,32 +93,35 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
builder.setMediaId(mediaId);
|
builder.setMediaId(mediaId);
|
||||||
builder.setTitle(folderName);
|
builder.setTitle(folderName);
|
||||||
|
|
||||||
final var extras = new Bundle();
|
final Bundle extras = new Bundle();
|
||||||
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
|
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
|
||||||
playerService.getString(R.string.app_name));
|
playerService.getString(R.string.app_name));
|
||||||
builder.setExtras(extras);
|
builder.setExtras(extras);
|
||||||
return new MediaItem(builder.build(), MediaItem.FLAG_BROWSABLE);
|
return new MediaItem(builder.build(), MediaItem.FLAG_BROWSABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MediaItem createPlaylistMediaItem(final PlaylistMetadataEntry playlist) {
|
@NonNull
|
||||||
|
private MediaItem createPlaylistMediaItem(@NonNull final PlaylistMetadataEntry playlist) {
|
||||||
final var builder = new MediaDescriptionCompat.Builder();
|
final var builder = new MediaDescriptionCompat.Builder();
|
||||||
builder.setMediaId(createMediaIdForPlaylist(playlist.getUid()))
|
builder.setMediaId(createMediaIdForPlaylist(playlist.getUid()))
|
||||||
.setTitle(playlist.name)
|
.setTitle(playlist.name)
|
||||||
.setIconUri(Uri.parse(playlist.thumbnailUrl));
|
.setIconUri(Uri.parse(playlist.thumbnailUrl));
|
||||||
|
|
||||||
final var extras = new Bundle();
|
final Bundle extras = new Bundle();
|
||||||
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
|
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
|
||||||
playerService.getResources().getString(R.string.tab_bookmarks));
|
playerService.getResources().getString(R.string.tab_bookmarks));
|
||||||
builder.setExtras(extras);
|
builder.setExtras(extras);
|
||||||
return new MediaItem(builder.build(), MediaItem.FLAG_BROWSABLE);
|
return new MediaItem(builder.build(), MediaItem.FLAG_BROWSABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private String createMediaIdForPlaylist(final long playlistId) {
|
private String createMediaIdForPlaylist(final long playlistId) {
|
||||||
return ID_BOOKMARKS + '/' + playlistId;
|
return ID_BOOKMARKS + '/' + playlistId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private MediaItem createPlaylistStreamMediaItem(final long playlistId,
|
private MediaItem createPlaylistStreamMediaItem(final long playlistId,
|
||||||
final PlaylistStreamEntry item,
|
@NonNull final PlaylistStreamEntry item,
|
||||||
final int index) {
|
final int index) {
|
||||||
final var builder = new MediaDescriptionCompat.Builder();
|
final var builder = new MediaDescriptionCompat.Builder();
|
||||||
builder.setMediaId(createMediaIdForPlaylistIndex(playlistId, index))
|
builder.setMediaId(createMediaIdForPlaylistIndex(playlistId, index))
|
||||||
|
@ -121,6 +131,7 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
return new MediaItem(builder.build(), MediaItem.FLAG_PLAYABLE);
|
return new MediaItem(builder.build(), MediaItem.FLAG_PLAYABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private String createMediaIdForPlaylistIndex(final long playlistId, final int index) {
|
private String createMediaIdForPlaylistIndex(final long playlistId, final int index) {
|
||||||
return createMediaIdForPlaylist(playlistId) + '/' + index;
|
return createMediaIdForPlaylist(playlistId) + '/' + index;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +154,6 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<MediaItem> mediaItems = new ArrayList<>();
|
final List<MediaItem> mediaItems = new ArrayList<>();
|
||||||
final var parentIdUri = Uri.parse(parentId);
|
|
||||||
|
|
||||||
if (parentId.equals(ID_ROOT)) {
|
if (parentId.equals(ID_ROOT)) {
|
||||||
mediaItems.add(
|
mediaItems.add(
|
||||||
|
@ -153,14 +163,15 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
createRootMediaItem(ID_HISTORY,
|
createRootMediaItem(ID_HISTORY,
|
||||||
playerService.getResources().getString(R.string.action_history)));
|
playerService.getResources().getString(R.string.action_history)));
|
||||||
} else if (parentId.startsWith(ID_BOOKMARKS)) {
|
} else if (parentId.startsWith(ID_BOOKMARKS)) {
|
||||||
final var path = parentIdUri.getPathSegments();
|
final Uri parentIdUri = Uri.parse(parentId);
|
||||||
|
final List<String> path = parentIdUri.getPathSegments();
|
||||||
if (path.size() == 2) {
|
if (path.size() == 2) {
|
||||||
return populateBookmarks();
|
return populateBookmarks();
|
||||||
} else if (path.size() == 3) {
|
} else if (path.size() == 3) {
|
||||||
final var playlistId = Long.parseLong(path.get(2));
|
final long playlistId = Long.parseLong(path.get(2));
|
||||||
return populatePlaylist(playlistId);
|
return populatePlaylist(playlistId);
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Unknown playlist uri " + parentId);
|
Log.w(TAG, "Unknown playlist URI: " + parentId);
|
||||||
}
|
}
|
||||||
} else if (parentId.equals(ID_HISTORY)) {
|
} else if (parentId.equals(ID_HISTORY)) {
|
||||||
return populateHistory();
|
return populateHistory();
|
||||||
|
@ -169,17 +180,19 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
}
|
}
|
||||||
|
|
||||||
private Single<List<MediaItem>> populateHistory() {
|
private Single<List<MediaItem>> populateHistory() {
|
||||||
final var streamHistory = getDatabase().streamHistoryDAO();
|
final StreamHistoryDAO streamHistory = getDatabase().streamHistoryDAO();
|
||||||
final var history = streamHistory.getHistory().firstOrError();
|
final var history = streamHistory.getHistory().firstOrError();
|
||||||
return history.map(items ->
|
return history.map(items -> items.stream()
|
||||||
items.stream().map(this::createHistoryMediaItem).collect(Collectors.toList()));
|
.map(this::createHistoryMediaItem)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
private MediaItem createHistoryMediaItem(@NonNull final StreamHistoryEntry streamHistoryEntry) {
|
private MediaItem createHistoryMediaItem(@NonNull final StreamHistoryEntry streamHistoryEntry) {
|
||||||
final var builder = new MediaDescriptionCompat.Builder();
|
final var builder = new MediaDescriptionCompat.Builder();
|
||||||
builder.setMediaId(ID_STREAM + '/' + streamHistoryEntry.getStreamId())
|
builder.setMediaId(ID_STREAM + '/' + streamHistoryEntry.getStreamId())
|
||||||
.setTitle(streamHistoryEntry.getStreamEntity().getTitle())
|
.setTitle(streamHistoryEntry.getStreamEntity().getTitle())
|
||||||
.setIconUri(Uri.parse(streamHistoryEntry.getStreamEntity().getThumbnailUrl()));
|
.setIconUri(Uri.parse(streamHistoryEntry.getStreamEntity().getThumbnailUrl()));
|
||||||
|
|
||||||
return new MediaItem(builder.build(), MediaItem.FLAG_PLAYABLE);
|
return new MediaItem(builder.build(), MediaItem.FLAG_PLAYABLE);
|
||||||
}
|
}
|
||||||
|
@ -198,10 +211,14 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
return localPlaylistManager;
|
return localPlaylistManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Suppress Sonar warning replace list collection by Stream.toList call, as this method is only
|
||||||
|
// available in Android API 34 and not currently available with desugaring
|
||||||
|
@SuppressWarnings("squid:S6204")
|
||||||
private Single<List<MediaItem>> populateBookmarks() {
|
private Single<List<MediaItem>> populateBookmarks() {
|
||||||
final var playlists = getPlaylistManager().getPlaylists().firstOrError();
|
final var playlists = getPlaylistManager().getPlaylists().firstOrError();
|
||||||
return playlists.map(playlist ->
|
return playlists.map(playlist -> playlist.stream()
|
||||||
playlist.stream().map(this::createPlaylistMediaItem).collect(Collectors.toList()));
|
.map(this::createPlaylistMediaItem)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Single<List<MediaItem>> populatePlaylist(final long playlistId) {
|
private Single<List<MediaItem>> populatePlaylist(final long playlistId) {
|
||||||
|
@ -209,7 +226,7 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
return playlist.map(items -> {
|
return playlist.map(items -> {
|
||||||
final List<MediaItem> results = new ArrayList<>();
|
final List<MediaItem> results = new ArrayList<>();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (final var item : items) {
|
for (final PlaylistStreamEntry item : items) {
|
||||||
results.add(createPlaylistStreamMediaItem(playlistId, item, index));
|
results.add(createPlaylistStreamMediaItem(playlistId, item, index));
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
@ -231,36 +248,33 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
if (mediaIdUri == null) {
|
if (mediaIdUri == null) {
|
||||||
return Single.error(new ContentNotAvailableException("Media ID cannot be parsed"));
|
return Single.error(new ContentNotAvailableException("Media ID cannot be parsed"));
|
||||||
}
|
}
|
||||||
if (mediaId.startsWith(ID_BOOKMARKS)) {
|
|
||||||
final var path = mediaIdUri.getPathSegments();
|
|
||||||
if (path.size() == 4) {
|
|
||||||
final long playlistId = Long.parseLong(path.get(2));
|
|
||||||
final int index = Integer.parseInt(path.get(3));
|
|
||||||
|
|
||||||
return getPlaylistManager()
|
final List<String> path = mediaIdUri.getPathSegments();
|
||||||
.getPlaylistStreams(playlistId)
|
|
||||||
.firstOrError()
|
if (mediaId.startsWith(ID_BOOKMARKS) && path.size() == 4) {
|
||||||
.map(items -> {
|
final long playlistId = Long.parseLong(path.get(2));
|
||||||
final var infoItems = items.stream()
|
final int index = Integer.parseInt(path.get(3));
|
||||||
.map(PlaylistStreamEntry::toStreamInfoItem)
|
|
||||||
.collect(Collectors.toList());
|
return getPlaylistManager()
|
||||||
return new SinglePlayQueue(infoItems, index);
|
.getPlaylistStreams(playlistId)
|
||||||
});
|
.firstOrError()
|
||||||
}
|
.map(items -> {
|
||||||
} else if (mediaId.startsWith(ID_STREAM)) {
|
final List<StreamInfoItem> infoItems = items.stream()
|
||||||
final var path = mediaIdUri.getPathSegments();
|
.map(PlaylistStreamEntry::toStreamInfoItem)
|
||||||
if (path.size() == 3) {
|
.collect(Collectors.toList());
|
||||||
final long streamId = Long.parseLong(path.get(2));
|
return new SinglePlayQueue(infoItems, index);
|
||||||
return getDatabase().streamHistoryDAO().getHistory()
|
});
|
||||||
.firstOrError()
|
} else if (mediaId.startsWith(ID_STREAM) && path.size() == 3) {
|
||||||
.map(items -> {
|
final long streamId = Long.parseLong(path.get(2));
|
||||||
final var infoItems = items.stream()
|
return getDatabase().streamHistoryDAO().getHistory()
|
||||||
.filter(it -> it.getStreamId() == streamId)
|
.firstOrError()
|
||||||
.map(StreamHistoryEntry::toStreamInfoItem)
|
.map(items -> {
|
||||||
.collect(Collectors.toList());
|
final List<StreamInfoItem> infoItems = items.stream()
|
||||||
return new SinglePlayQueue(infoItems, 0);
|
.filter(it -> it.getStreamId() == streamId)
|
||||||
});
|
.map(StreamHistoryEntry::toStreamInfoItem)
|
||||||
}
|
.collect(Collectors.toList());
|
||||||
|
return new SinglePlayQueue(infoItems, 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Single.error(new ContentNotAvailableException("Media ID cannot be parsed"));
|
return Single.error(new ContentNotAvailableException("Media ID cannot be parsed"));
|
||||||
|
@ -285,7 +299,8 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrepareFromMediaId(@NonNull final String mediaId, final boolean playWhenReady,
|
public void onPrepareFromMediaId(@NonNull final String mediaId,
|
||||||
|
final boolean playWhenReady,
|
||||||
@Nullable final Bundle extras) {
|
@Nullable final Bundle extras) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, String.format("MediaBrowserConnector.onPrepareFromMediaId(%s, %s, %s)",
|
Log.d(TAG, String.format("MediaBrowserConnector.onPrepareFromMediaId(%s, %s, %s)",
|
||||||
|
@ -307,22 +322,26 @@ public class MediaBrowserConnector implements MediaSessionConnector.PlaybackPrep
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrepareFromSearch(@NonNull final String query, final boolean playWhenReady,
|
public void onPrepareFromSearch(@NonNull final String query,
|
||||||
|
final boolean playWhenReady,
|
||||||
@Nullable final Bundle extras) {
|
@Nullable final Bundle extras) {
|
||||||
disposePrepareOrPlayCommands();
|
disposePrepareOrPlayCommands();
|
||||||
playbackError(R.string.content_not_supported, PlaybackStateCompat.ERROR_CODE_NOT_SUPPORTED);
|
playbackError(R.string.content_not_supported, PlaybackStateCompat.ERROR_CODE_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPrepareFromUri(@NonNull final Uri uri, final boolean playWhenReady,
|
public void onPrepareFromUri(@NonNull final Uri uri,
|
||||||
|
final boolean playWhenReady,
|
||||||
@Nullable final Bundle extras) {
|
@Nullable final Bundle extras) {
|
||||||
disposePrepareOrPlayCommands();
|
disposePrepareOrPlayCommands();
|
||||||
playbackError(R.string.content_not_supported, PlaybackStateCompat.ERROR_CODE_NOT_SUPPORTED);
|
playbackError(R.string.content_not_supported, PlaybackStateCompat.ERROR_CODE_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(@NonNull final Player player, @NonNull final String command,
|
public boolean onCommand(@NonNull final Player player,
|
||||||
@Nullable final Bundle extras, @Nullable final ResultReceiver cb) {
|
@NonNull final String command,
|
||||||
|
@Nullable final Bundle extras,
|
||||||
|
@Nullable final ResultReceiver cb) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue