486 lines
22 KiB
Java
486 lines
22 KiB
Java
|
|
package com.cappielloantonio.tempo.service;
|
||
|
|
|
||
|
|
import android.content.ComponentName;
|
||
|
|
import android.util.Log;
|
||
|
|
|
||
|
|
import androidx.annotation.NonNull;
|
||
|
|
import androidx.annotation.Nullable;
|
||
|
|
import androidx.annotation.OptIn;
|
||
|
|
import androidx.lifecycle.LifecycleOwner;
|
||
|
|
import androidx.lifecycle.LiveData;
|
||
|
|
import androidx.lifecycle.Observer;
|
||
|
|
import androidx.media3.common.MediaItem;
|
||
|
|
import androidx.media3.common.Player;
|
||
|
|
import androidx.media3.common.Timeline;
|
||
|
|
import androidx.media3.common.util.UnstableApi;
|
||
|
|
import androidx.media3.session.MediaBrowser;
|
||
|
|
import androidx.media3.session.SessionToken;
|
||
|
|
|
||
|
|
import com.cappielloantonio.tempo.App;
|
||
|
|
import com.cappielloantonio.tempo.interfaces.MediaIndexCallback;
|
||
|
|
import com.cappielloantonio.tempo.model.Chronology;
|
||
|
|
import com.cappielloantonio.tempo.repository.ChronologyRepository;
|
||
|
|
import com.cappielloantonio.tempo.repository.QueueRepository;
|
||
|
|
import com.cappielloantonio.tempo.repository.SongRepository;
|
||
|
|
import com.cappielloantonio.tempo.subsonic.models.Child;
|
||
|
|
import com.cappielloantonio.tempo.subsonic.models.InternetRadioStation;
|
||
|
|
import com.cappielloantonio.tempo.subsonic.models.PodcastEpisode;
|
||
|
|
import com.cappielloantonio.tempo.util.MappingUtil;
|
||
|
|
import com.cappielloantonio.tempo.util.Preferences;
|
||
|
|
import com.cappielloantonio.tempo.viewmodel.PlaybackViewModel;
|
||
|
|
import com.google.common.util.concurrent.FutureCallback;
|
||
|
|
import com.google.common.util.concurrent.Futures;
|
||
|
|
import com.google.common.util.concurrent.ListenableFuture;
|
||
|
|
import com.google.common.util.concurrent.MoreExecutors;
|
||
|
|
|
||
|
|
import java.lang.ref.WeakReference;
|
||
|
|
import java.util.List;
|
||
|
|
import java.util.concurrent.ExecutionException;
|
||
|
|
|
||
|
|
public class MediaManager {
|
||
|
|
private static final String TAG = "MediaManager";
|
||
|
|
private static WeakReference<MediaBrowser> attachedBrowserRef = new WeakReference<>(null);
|
||
|
|
|
||
|
|
public static void registerPlaybackObserver(
|
||
|
|
ListenableFuture<MediaBrowser> browserFuture,
|
||
|
|
PlaybackViewModel playbackViewModel
|
||
|
|
) {
|
||
|
|
if (browserFuture == null) return;
|
||
|
|
|
||
|
|
Futures.addCallback(browserFuture, new FutureCallback<MediaBrowser>() {
|
||
|
|
@Override
|
||
|
|
public void onSuccess(MediaBrowser browser) {
|
||
|
|
MediaBrowser current = attachedBrowserRef.get();
|
||
|
|
if (current != browser) {
|
||
|
|
browser.addListener(new Player.Listener() {
|
||
|
|
@Override
|
||
|
|
public void onEvents(@NonNull Player player, @NonNull Player.Events events) {
|
||
|
|
if (events.contains(Player.EVENT_MEDIA_ITEM_TRANSITION)
|
||
|
|
|| events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED)
|
||
|
|
|| events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED)) {
|
||
|
|
|
||
|
|
String mediaId = player.getCurrentMediaItem() != null
|
||
|
|
? player.getCurrentMediaItem().mediaId
|
||
|
|
: null;
|
||
|
|
|
||
|
|
boolean playing = player.getPlaybackState() == Player.STATE_READY
|
||
|
|
&& player.getPlayWhenReady();
|
||
|
|
|
||
|
|
playbackViewModel.update(mediaId, playing);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
String mediaId = browser.getCurrentMediaItem() != null
|
||
|
|
? browser.getCurrentMediaItem().mediaId
|
||
|
|
: null;
|
||
|
|
boolean playing = browser.getPlaybackState() == Player.STATE_READY && browser.getPlayWhenReady();
|
||
|
|
playbackViewModel.update(mediaId, playing);
|
||
|
|
|
||
|
|
attachedBrowserRef = new WeakReference<>(browser);
|
||
|
|
} else {
|
||
|
|
String mediaId = browser.getCurrentMediaItem() != null
|
||
|
|
? browser.getCurrentMediaItem().mediaId
|
||
|
|
: null;
|
||
|
|
boolean playing = browser.getPlaybackState() == Player.STATE_READY && browser.getPlayWhenReady();
|
||
|
|
playbackViewModel.update(mediaId, playing);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public void onFailure(@NonNull Throwable t) {
|
||
|
|
Log.e(TAG, "Failed to get MediaBrowser instance", t);
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void onBrowserReleased(@Nullable MediaBrowser released) {
|
||
|
|
MediaBrowser attached = attachedBrowserRef.get();
|
||
|
|
if (attached == released) {
|
||
|
|
attachedBrowserRef.clear();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void reset(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
if (mediaBrowserListenableFuture.get().isPlaying()) {
|
||
|
|
mediaBrowserListenableFuture.get().pause();
|
||
|
|
}
|
||
|
|
|
||
|
|
mediaBrowserListenableFuture.get().stop();
|
||
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
||
|
|
clearDatabase();
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void hide(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
if (mediaBrowserListenableFuture.get().isPlaying()) {
|
||
|
|
mediaBrowserListenableFuture.get().pause();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void check(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
if (mediaBrowserListenableFuture.get().getMediaItemCount() < 1) {
|
||
|
|
List<Child> media = getQueueRepository().getMedia();
|
||
|
|
if (media != null && media.size() >= 1) {
|
||
|
|
init(mediaBrowserListenableFuture, media);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void init(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Child> media) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
||
|
|
mediaBrowserListenableFuture.get().setMediaItems(MappingUtil.mapMediaItems(media));
|
||
|
|
mediaBrowserListenableFuture.get().seekTo(getQueueRepository().getLastPlayedMediaIndex(), getQueueRepository().getLastPlayedMediaTimestamp());
|
||
|
|
mediaBrowserListenableFuture.get().prepare();
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void startQueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Child> media, int startIndex) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
MediaBrowser browser = mediaBrowserListenableFuture.get();
|
||
|
|
browser.clearMediaItems();
|
||
|
|
browser.setMediaItems(MappingUtil.mapMediaItems(media));
|
||
|
|
browser.prepare();
|
||
|
|
|
||
|
|
Player.Listener timelineListener = new Player.Listener() {
|
||
|
|
@Override
|
||
|
|
public void onTimelineChanged(Timeline timeline, int reason) {
|
||
|
|
int itemCount = browser.getMediaItemCount();
|
||
|
|
if (itemCount > 0 && startIndex >= 0 && startIndex < itemCount) {
|
||
|
|
browser.seekTo(startIndex, 0);
|
||
|
|
browser.play();
|
||
|
|
browser.removeListener(this);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
};
|
||
|
|
browser.addListener(timelineListener);
|
||
|
|
|
||
|
|
enqueueDatabase(media, true, 0);
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void startQueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, Child media) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
||
|
|
mediaBrowserListenableFuture.get().setMediaItem(MappingUtil.mapMediaItem(media));
|
||
|
|
mediaBrowserListenableFuture.get().prepare();
|
||
|
|
mediaBrowserListenableFuture.get().play();
|
||
|
|
enqueueDatabase(media, true, 0);
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void playDownloadedMediaItem(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, MediaItem mediaItem) {
|
||
|
|
if (mediaBrowserListenableFuture != null && mediaItem != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
MediaBrowser mediaBrowser = mediaBrowserListenableFuture.get();
|
||
|
|
mediaBrowser.clearMediaItems();
|
||
|
|
mediaBrowser.setMediaItem(mediaItem);
|
||
|
|
mediaBrowser.prepare();
|
||
|
|
mediaBrowser.play();
|
||
|
|
clearDatabase();
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void startRadio(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, InternetRadioStation internetRadioStation) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
||
|
|
mediaBrowserListenableFuture.get().setMediaItem(MappingUtil.mapInternetRadioStation(internetRadioStation));
|
||
|
|
mediaBrowserListenableFuture.get().prepare();
|
||
|
|
mediaBrowserListenableFuture.get().play();
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void startPodcast(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, PodcastEpisode podcastEpisode) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
||
|
|
mediaBrowserListenableFuture.get().setMediaItem(MappingUtil.mapMediaItem(podcastEpisode));
|
||
|
|
mediaBrowserListenableFuture.get().prepare();
|
||
|
|
mediaBrowserListenableFuture.get().play();
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void enqueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Child> media, boolean playImmediatelyAfter) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
if (playImmediatelyAfter && mediaBrowserListenableFuture.get().getNextMediaItemIndex() != -1) {
|
||
|
|
enqueueDatabase(media, false, mediaBrowserListenableFuture.get().getNextMediaItemIndex());
|
||
|
|
mediaBrowserListenableFuture.get().addMediaItems(mediaBrowserListenableFuture.get().getNextMediaItemIndex(), MappingUtil.mapMediaItems(media));
|
||
|
|
} else {
|
||
|
|
enqueueDatabase(media, false, mediaBrowserListenableFuture.get().getMediaItemCount());
|
||
|
|
mediaBrowserListenableFuture.get().addMediaItems(MappingUtil.mapMediaItems(media));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void enqueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, Child media, boolean playImmediatelyAfter) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
if (playImmediatelyAfter && mediaBrowserListenableFuture.get().getNextMediaItemIndex() != -1) {
|
||
|
|
enqueueDatabase(media, false, mediaBrowserListenableFuture.get().getNextMediaItemIndex());
|
||
|
|
mediaBrowserListenableFuture.get().addMediaItem(mediaBrowserListenableFuture.get().getNextMediaItemIndex(), MappingUtil.mapMediaItem(media));
|
||
|
|
} else {
|
||
|
|
enqueueDatabase(media, false, mediaBrowserListenableFuture.get().getMediaItemCount());
|
||
|
|
mediaBrowserListenableFuture.get().addMediaItem(MappingUtil.mapMediaItem(media));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void shuffle(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Child> media, int startIndex, int endIndex) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
mediaBrowserListenableFuture.get().removeMediaItems(startIndex, endIndex + 1);
|
||
|
|
mediaBrowserListenableFuture.get().addMediaItems(MappingUtil.mapMediaItems(media).subList(startIndex, endIndex + 1));
|
||
|
|
swapDatabase(media);
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void swap(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Child> media, int from, int to) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
mediaBrowserListenableFuture.get().moveMediaItem(from, to);
|
||
|
|
swapDatabase(media);
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void remove(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Child> media, int toRemove) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
if (mediaBrowserListenableFuture.get().getMediaItemCount() > 1 && mediaBrowserListenableFuture.get().getCurrentMediaItemIndex() != toRemove) {
|
||
|
|
mediaBrowserListenableFuture.get().removeMediaItem(toRemove);
|
||
|
|
removeDatabase(media, toRemove);
|
||
|
|
} else {
|
||
|
|
removeDatabase(media, -1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void removeRange(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Child> media, int fromItem, int toItem) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
mediaBrowserListenableFuture.get().removeMediaItems(fromItem, toItem);
|
||
|
|
removeRangeDatabase(media, fromItem, toItem);
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void getCurrentIndex(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, MediaIndexCallback callback) {
|
||
|
|
if (mediaBrowserListenableFuture != null) {
|
||
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
||
|
|
try {
|
||
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
||
|
|
callback.onRecovery(mediaBrowserListenableFuture.get().getCurrentMediaItemIndex());
|
||
|
|
}
|
||
|
|
} catch (ExecutionException | InterruptedException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}, MoreExecutors.directExecutor());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void setLastPlayedTimestamp(MediaItem mediaItem) {
|
||
|
|
if (mediaItem != null) getQueueRepository().setLastPlayedTimestamp(mediaItem.mediaId);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void setPlayingPausedTimestamp(MediaItem mediaItem, long ms) {
|
||
|
|
if (mediaItem != null)
|
||
|
|
getQueueRepository().setPlayingPausedTimestamp(mediaItem.mediaId, ms);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void scrobble(MediaItem mediaItem, boolean submission) {
|
||
|
|
if (mediaItem != null && Preferences.isScrobblingEnabled()) {
|
||
|
|
getSongRepository().scrobble(mediaItem.mediaMetadata.extras.getString("id"), submission);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@OptIn(markerClass = UnstableApi.class)
|
||
|
|
public static void continuousPlay(MediaItem mediaItem) {
|
||
|
|
if (mediaItem != null && Preferences.isContinuousPlayEnabled() && Preferences.isInstantMixUsable()) {
|
||
|
|
Preferences.setLastInstantMix();
|
||
|
|
|
||
|
|
LiveData<List<Child>> instantMix = getSongRepository().getInstantMix(mediaItem.mediaId, 10);
|
||
|
|
instantMix.observeForever(new Observer<List<Child>>() {
|
||
|
|
@Override
|
||
|
|
public void onChanged(List<Child> media) {
|
||
|
|
if (media != null) {
|
||
|
|
ListenableFuture<MediaBrowser> mediaBrowserListenableFuture = new MediaBrowser.Builder(
|
||
|
|
App.getContext(),
|
||
|
|
new SessionToken(App.getContext(), new ComponentName(App.getContext(), MediaService.class))
|
||
|
|
).buildAsync();
|
||
|
|
|
||
|
|
enqueue(mediaBrowserListenableFuture, media, true);
|
||
|
|
}
|
||
|
|
|
||
|
|
instantMix.removeObserver(this);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void saveChronology(MediaItem mediaItem) {
|
||
|
|
if (mediaItem != null) {
|
||
|
|
getChronologyRepository().insert(new Chronology(mediaItem));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static QueueRepository getQueueRepository() {
|
||
|
|
return new QueueRepository();
|
||
|
|
}
|
||
|
|
|
||
|
|
private static SongRepository getSongRepository() {
|
||
|
|
return new SongRepository();
|
||
|
|
}
|
||
|
|
|
||
|
|
private static ChronologyRepository getChronologyRepository() {
|
||
|
|
return new ChronologyRepository();
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void enqueueDatabase(List<Child> media, boolean reset, int afterIndex) {
|
||
|
|
getQueueRepository().insertAll(media, reset, afterIndex);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void enqueueDatabase(Child media, boolean reset, int afterIndex) {
|
||
|
|
getQueueRepository().insert(media, reset, afterIndex);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void swapDatabase(List<Child> media) {
|
||
|
|
getQueueRepository().insertAll(media, true, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void removeDatabase(List<Child> media, int toRemove) {
|
||
|
|
if (toRemove != -1) {
|
||
|
|
media.remove(toRemove);
|
||
|
|
getQueueRepository().insertAll(media, true, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void removeRangeDatabase(List<Child> media, int fromItem, int toItem) {
|
||
|
|
List<Child> toRemove = media.subList(fromItem, toItem);
|
||
|
|
|
||
|
|
media.removeAll(toRemove);
|
||
|
|
|
||
|
|
getQueueRepository().insertAll(media, true, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static void clearDatabase() {
|
||
|
|
getQueueRepository().deleteAll();
|
||
|
|
}
|
||
|
|
}
|