2021-12-29 10:18:09 +01:00
|
|
|
package com.cappielloantonio.play.service;
|
|
|
|
|
|
2021-12-29 19:08:10 +01:00
|
|
|
import android.content.Context;
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
2021-12-30 20:07:20 +01:00
|
|
|
import androidx.media3.common.MediaItem;
|
2021-12-29 19:08:10 +01:00
|
|
|
import androidx.media3.session.MediaBrowser;
|
2021-12-29 10:18:09 +01:00
|
|
|
|
|
|
|
|
import com.cappielloantonio.play.App;
|
2021-12-30 20:25:51 +01:00
|
|
|
import com.cappielloantonio.play.interfaces.MediaIndexCallback;
|
2021-12-29 10:18:09 +01:00
|
|
|
import com.cappielloantonio.play.model.Song;
|
|
|
|
|
import com.cappielloantonio.play.repository.QueueRepository;
|
2022-01-04 15:31:52 +01:00
|
|
|
import com.cappielloantonio.play.repository.SongRepository;
|
2021-12-29 19:08:10 +01:00
|
|
|
import com.cappielloantonio.play.util.MappingUtil;
|
|
|
|
|
import com.google.common.util.concurrent.ListenableFuture;
|
|
|
|
|
import com.google.common.util.concurrent.MoreExecutors;
|
2021-12-29 10:18:09 +01:00
|
|
|
|
|
|
|
|
import java.util.List;
|
2021-12-29 19:08:10 +01:00
|
|
|
import java.util.concurrent.ExecutionException;
|
2021-12-29 10:18:09 +01:00
|
|
|
|
|
|
|
|
public class MediaManager {
|
2021-12-29 19:08:10 +01:00
|
|
|
private static final String TAG = "MediaManager";
|
|
|
|
|
|
2021-12-31 16:50:14 +01:00
|
|
|
public static void quit(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
if (mediaBrowserListenableFuture.get().isPlaying()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().pause();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-30 19:31:13 +01:00
|
|
|
public static void check(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, Context context) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
if (mediaBrowserListenableFuture.get().getMediaItemCount() < 1) {
|
|
|
|
|
List<Song> songs = getQueueRepository().getSongs();
|
|
|
|
|
if (songs.size() >= 1) {
|
|
|
|
|
init(mediaBrowserListenableFuture, context, songs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void init(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, Context context, List<Song> songs) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
2022-01-01 21:55:15 +01:00
|
|
|
mediaBrowserListenableFuture.get().setMediaItems(MappingUtil.mapMediaItems(context, songs, true));
|
2022-01-02 17:43:30 +01:00
|
|
|
mediaBrowserListenableFuture.get().seekTo(getQueueRepository().getLastPlayedSongIndex(), getQueueRepository().getLastPlayedSongTimestamp());
|
2021-12-30 19:31:13 +01:00
|
|
|
mediaBrowserListenableFuture.get().prepare();
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-29 19:08:10 +01:00
|
|
|
public static void prepare(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().prepare();
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void play(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().play();
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void pause(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().pause();
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void stop(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().stop();
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void clearQueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void startQueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, Context context, List<Song> songs, int startIndex) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
2022-01-01 21:55:15 +01:00
|
|
|
mediaBrowserListenableFuture.get().setMediaItems(MappingUtil.mapMediaItems(context, songs, true));
|
2021-12-29 19:08:10 +01:00
|
|
|
mediaBrowserListenableFuture.get().prepare();
|
|
|
|
|
mediaBrowserListenableFuture.get().seekTo(startIndex, 0);
|
|
|
|
|
mediaBrowserListenableFuture.get().play();
|
2021-12-30 18:13:50 +01:00
|
|
|
enqueueDatabase(songs, true, 0);
|
2021-12-29 19:08:10 +01:00
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void startQueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, Context context, Song song) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().clearMediaItems();
|
2022-01-01 21:55:15 +01:00
|
|
|
mediaBrowserListenableFuture.get().setMediaItem(MappingUtil.mapMediaItem(context, song, true));
|
2021-12-29 19:08:10 +01:00
|
|
|
mediaBrowserListenableFuture.get().prepare();
|
|
|
|
|
mediaBrowserListenableFuture.get().play();
|
2021-12-30 18:13:50 +01:00
|
|
|
enqueueDatabase(song, true, 0);
|
2021-12-29 19:08:10 +01:00
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
2021-12-29 10:18:09 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-29 21:22:52 +01:00
|
|
|
public static void enqueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, Context context, List<Song> songs, boolean playImmediatelyAfter) {
|
2021-12-29 19:08:10 +01:00
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
2021-12-31 16:50:14 +01:00
|
|
|
if (playImmediatelyAfter && mediaBrowserListenableFuture.get().getNextMediaItemIndex() != -1) {
|
2021-12-30 18:13:50 +01:00
|
|
|
enqueueDatabase(songs, false, mediaBrowserListenableFuture.get().getNextMediaItemIndex());
|
2022-01-01 21:55:15 +01:00
|
|
|
mediaBrowserListenableFuture.get().addMediaItems(mediaBrowserListenableFuture.get().getNextMediaItemIndex(), MappingUtil.mapMediaItems(context, songs, true));
|
2021-12-29 19:08:10 +01:00
|
|
|
} else {
|
2021-12-30 18:13:50 +01:00
|
|
|
enqueueDatabase(songs, false, mediaBrowserListenableFuture.get().getMediaItemCount());
|
2022-01-01 21:55:15 +01:00
|
|
|
mediaBrowserListenableFuture.get().addMediaItems(MappingUtil.mapMediaItems(context, songs, true));
|
2021-12-29 19:08:10 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
2021-12-29 10:18:09 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-29 21:22:52 +01:00
|
|
|
public static void enqueue(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, Context context, Song song, boolean playImmediatelyAfter) {
|
2021-12-29 19:08:10 +01:00
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
2021-12-30 20:49:28 +01:00
|
|
|
if (playImmediatelyAfter && mediaBrowserListenableFuture.get().getNextMediaItemIndex() != -1) {
|
2021-12-30 18:13:50 +01:00
|
|
|
enqueueDatabase(song, false, mediaBrowserListenableFuture.get().getNextMediaItemIndex());
|
2022-01-01 21:55:15 +01:00
|
|
|
mediaBrowserListenableFuture.get().addMediaItem(mediaBrowserListenableFuture.get().getNextMediaItemIndex(), MappingUtil.mapMediaItem(context, song, true));
|
2021-12-29 19:08:10 +01:00
|
|
|
} else {
|
2021-12-30 18:13:50 +01:00
|
|
|
enqueueDatabase(song, false, mediaBrowserListenableFuture.get().getMediaItemCount());
|
2022-01-01 21:55:15 +01:00
|
|
|
mediaBrowserListenableFuture.get().addMediaItem(MappingUtil.mapMediaItem(context, song, true));
|
2021-12-29 19:08:10 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
2021-12-29 10:18:09 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-30 18:13:50 +01:00
|
|
|
public static void swap(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Song> songs, int from, int to) {
|
|
|
|
|
if (mediaBrowserListenableFuture != null) {
|
|
|
|
|
mediaBrowserListenableFuture.addListener(() -> {
|
|
|
|
|
try {
|
|
|
|
|
if (mediaBrowserListenableFuture.isDone()) {
|
|
|
|
|
mediaBrowserListenableFuture.get().moveMediaItem(from, to);
|
|
|
|
|
swapDatabase(songs);
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void remove(ListenableFuture<MediaBrowser> mediaBrowserListenableFuture, List<Song> songs, 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(songs, toRemove);
|
|
|
|
|
} else {
|
|
|
|
|
removeDatabase(songs, -1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (ExecutionException | InterruptedException e) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
2021-12-30 20:25:51 +01:00
|
|
|
}
|
|
|
|
|
}, 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) {
|
|
|
|
|
Log.e(TAG, e.getMessage());
|
2021-12-30 18:13:50 +01:00
|
|
|
}
|
|
|
|
|
}, MoreExecutors.directExecutor());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-30 20:27:08 +01:00
|
|
|
public static void setLastPlayedTimestamp(MediaItem mediaItem) {
|
2022-01-02 17:43:30 +01:00
|
|
|
if (mediaItem != null) getQueueRepository().setLastPlayedTimestamp(mediaItem.mediaId);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-02 17:45:11 +01:00
|
|
|
public static void setPlayingPausedTimestamp(MediaItem mediaItem, long ms) {
|
|
|
|
|
if (mediaItem != null) getQueueRepository().setPlayingPausedTimestamp(mediaItem.mediaId, ms);
|
2021-12-30 20:07:20 +01:00
|
|
|
}
|
|
|
|
|
|
2022-01-04 15:31:52 +01:00
|
|
|
public static void scrobble(MediaItem mediaItem) {
|
|
|
|
|
if (mediaItem != null) getSongRepository().scrobble(mediaItem.mediaMetadata.extras.getString("id"));
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-29 10:18:09 +01:00
|
|
|
private static QueueRepository getQueueRepository() {
|
|
|
|
|
return new QueueRepository(App.getInstance());
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-04 15:31:52 +01:00
|
|
|
private static SongRepository getSongRepository() {
|
|
|
|
|
return new SongRepository(App.getInstance());
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-30 18:13:50 +01:00
|
|
|
private static void enqueueDatabase(List<Song> songs, boolean reset, int afterIndex) {
|
|
|
|
|
getQueueRepository().insertAll(songs, reset, afterIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void enqueueDatabase(Song song, boolean reset, int afterIndex) {
|
|
|
|
|
getQueueRepository().insert(song, reset, afterIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void swapDatabase(List<Song> songs) {
|
|
|
|
|
getQueueRepository().insertAll(songs, true, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void removeDatabase(List<Song> songs, int toRemove) {
|
|
|
|
|
if (toRemove != -1) {
|
|
|
|
|
songs.remove(toRemove);
|
|
|
|
|
getQueueRepository().insertAll(songs, true, 0);
|
|
|
|
|
}
|
2021-12-29 10:18:09 +01:00
|
|
|
}
|
|
|
|
|
}
|