mirror of
https://github.com/antebudimir/tempus.git
synced 2025-12-31 17:43:32 +00:00
Removed Jellyfin dependencies
This commit is contained in:
parent
737eaa1822
commit
9495fbd83d
16 changed files with 62 additions and 310 deletions
|
|
@ -35,9 +35,6 @@ android {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
|
|
||||||
// Jellyfin
|
|
||||||
implementation 'com.github.jellyfin.jellyfin-apiclient-java:android:0.7.7'
|
|
||||||
|
|
||||||
// AndroidX
|
// AndroidX
|
||||||
implementation 'androidx.core:core-ktx:1.6.0'
|
implementation 'androidx.core:core-ktx:1.6.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||||
|
|
@ -88,8 +85,6 @@ dependencies {
|
||||||
annotationProcessor 'com.tickaroo.tikxml:processor:0.9.0_11-SNAPSHOT'
|
annotationProcessor 'com.tickaroo.tikxml:processor:0.9.0_11-SNAPSHOT'
|
||||||
implementation 'com.tickaroo.tikxml:converter-date-rfc3339:0.9.0_11-SNAPSHOT'
|
implementation 'com.tickaroo.tikxml:converter-date-rfc3339:0.9.0_11-SNAPSHOT'
|
||||||
|
|
||||||
// implementation 'net.beardbot:subsonic-client:0.2.0'
|
|
||||||
|
|
||||||
// Database debugger via adb
|
// Database debugger via adb
|
||||||
// debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
|
// debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,9 @@ import com.cappielloantonio.play.subsonic.Subsonic;
|
||||||
import com.cappielloantonio.play.subsonic.SubsonicPreferences;
|
import com.cappielloantonio.play.subsonic.SubsonicPreferences;
|
||||||
import com.cappielloantonio.play.util.PreferenceUtil;
|
import com.cappielloantonio.play.util.PreferenceUtil;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.AppInfo;
|
|
||||||
import org.jellyfin.apiclient.BuildConfig;
|
|
||||||
import org.jellyfin.apiclient.Jellyfin;
|
|
||||||
import org.jellyfin.apiclient.JellyfinAndroidKt;
|
|
||||||
import org.jellyfin.apiclient.JellyfinOptions;
|
|
||||||
import org.jellyfin.apiclient.interaction.AndroidDevice;
|
|
||||||
import org.jellyfin.apiclient.interaction.ApiClient;
|
|
||||||
import org.jellyfin.apiclient.interaction.ApiEventListener;
|
|
||||||
import org.jellyfin.apiclient.logging.NullLogger;
|
|
||||||
|
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
private static final String TAG = "App";
|
private static final String TAG = "App";
|
||||||
private static App instance;
|
private static App instance;
|
||||||
private static ApiClient apiClient;
|
|
||||||
private static Subsonic subsonic;
|
private static Subsonic subsonic;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -44,26 +33,6 @@ public class App extends Application {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ApiClient getApiClientInstance(Context context) {
|
|
||||||
if (apiClient == null) {
|
|
||||||
apiClient = getApiClient(context);
|
|
||||||
}
|
|
||||||
return apiClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ApiClient getApiClient(Context context) {
|
|
||||||
String server = "http://192.168.1.81:8096";
|
|
||||||
|
|
||||||
JellyfinOptions.Builder options = new JellyfinOptions.Builder();
|
|
||||||
options.setLogger(new NullLogger());
|
|
||||||
options.setAppInfo(new AppInfo(context.getString(R.string.app_name), BuildConfig.VERSION_NAME));
|
|
||||||
JellyfinAndroidKt.android(options, context);
|
|
||||||
|
|
||||||
Jellyfin jellyfin = new Jellyfin(options.build());
|
|
||||||
|
|
||||||
return jellyfin.createApi(server, null, AndroidDevice.fromContext(context), new ApiEventListener());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Subsonic getSubsonicClientInstance(Context context, boolean override) {
|
public static Subsonic getSubsonicClientInstance(Context context, boolean override) {
|
||||||
if (subsonic == null || override) {
|
if (subsonic == null || override) {
|
||||||
subsonic = getSubsonicClient(context);
|
subsonic = getSubsonicClient(context);
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@ import com.cappielloantonio.play.R;
|
||||||
import com.cappielloantonio.play.util.MusicUtil;
|
import com.cappielloantonio.play.util.MusicUtil;
|
||||||
import com.wolt.blurhashkt.BlurHashDecoder;
|
import com.wolt.blurhashkt.BlurHashDecoder;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.model.dto.ImageOptions;
|
|
||||||
import org.jellyfin.apiclient.model.entities.ImageType;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class CustomGlideRequest {
|
public class CustomGlideRequest {
|
||||||
|
|
@ -50,7 +47,7 @@ public class CustomGlideRequest {
|
||||||
String url = App.getSubsonicClientInstance(App.getInstance(), false).getUrl();
|
String url = App.getSubsonicClientInstance(App.getInstance(), false).getUrl();
|
||||||
Map<String, String> params = App.getSubsonicClientInstance(App.getInstance(), false).getParams();
|
Map<String, String> params = App.getSubsonicClientInstance(App.getInstance(), false).getParams();
|
||||||
|
|
||||||
String sb = url + "/rest/" + "getCoverArt" +
|
String sb = url + "getCoverArt" +
|
||||||
"?u=" + params.get("u") +
|
"?u=" + params.get("u") +
|
||||||
"&s=" + params.get("s") +
|
"&s=" + params.get("s") +
|
||||||
"&t=" + params.get("t") +
|
"&t=" + params.get("t") +
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.cappielloantonio.play.model;
|
||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.room.ColumnInfo;
|
import androidx.room.ColumnInfo;
|
||||||
|
|
@ -12,13 +11,6 @@ import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import com.cappielloantonio.play.subsonic.models.AlbumID3;
|
import com.cappielloantonio.play.subsonic.models.AlbumID3;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
|
||||||
import org.jellyfin.apiclient.model.entities.ImageType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Entity(tableName = "album")
|
@Entity(tableName = "album")
|
||||||
public class Album implements Parcelable {
|
public class Album implements Parcelable {
|
||||||
private static final String TAG = "Album";
|
private static final String TAG = "Album";
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.cappielloantonio.play.model;
|
||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.room.ColumnInfo;
|
import androidx.room.ColumnInfo;
|
||||||
|
|
@ -10,10 +9,6 @@ import androidx.room.Entity;
|
||||||
import androidx.room.Ignore;
|
import androidx.room.Ignore;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
|
||||||
import org.jellyfin.apiclient.model.dto.GenreDto;
|
|
||||||
import org.jellyfin.apiclient.model.entities.ImageType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -56,39 +51,6 @@ public class Artist implements Parcelable {
|
||||||
this.backdropBlurHash = backdropBlurHash;
|
this.backdropBlurHash = backdropBlurHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
public Artist(BaseItemDto itemDto) {
|
|
||||||
this.id = itemDto.getId();
|
|
||||||
this.name = itemDto.getName();
|
|
||||||
|
|
||||||
this.primary = itemDto.getImageTags().containsKey(ImageType.Primary) ? id : null;
|
|
||||||
if (itemDto.getImageBlurHashes() != null && itemDto.getImageBlurHashes().get(ImageType.Primary) != null) {
|
|
||||||
this.primaryBlurHash = (String) itemDto.getImageBlurHashes().get(ImageType.Primary).values().toArray()[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.backdrop = !itemDto.getBackdropImageTags().get(0).isEmpty() ? id : null;
|
|
||||||
if (itemDto.getImageBlurHashes() != null && itemDto.getBackdropImageTags().get(0) != null) {
|
|
||||||
this.backdropBlurHash = (String) itemDto.getImageBlurHashes().get(ImageType.Backdrop).values().toArray()[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IndexOutOfBoundsException exception) {
|
|
||||||
this.backdrop = null;
|
|
||||||
this.backdropBlurHash = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.genres = new ArrayList<>();
|
|
||||||
this.albums = new ArrayList<>();
|
|
||||||
this.songs = new ArrayList<>();
|
|
||||||
|
|
||||||
if (itemDto.getGenreItems() != null) {
|
|
||||||
for (GenreDto genre : itemDto.getGenreItems()) {
|
|
||||||
genres.add(new Genre(genre));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
public Artist(String id, String name) {
|
public Artist(String id, String name) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,8 @@ import android.os.Parcelable;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.room.ColumnInfo;
|
import androidx.room.ColumnInfo;
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.Ignore;
|
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
|
||||||
import org.jellyfin.apiclient.model.dto.GenreDto;
|
|
||||||
import org.jellyfin.apiclient.model.entities.ImageType;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Entity(tableName = "genre")
|
@Entity(tableName = "genre")
|
||||||
public class Genre implements Parcelable {
|
public class Genre implements Parcelable {
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
@ -42,25 +35,6 @@ public class Genre implements Parcelable {
|
||||||
this.blurHash = blurHash;
|
this.blurHash = blurHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
public Genre(GenreDto genreDto) {
|
|
||||||
this.id = genreDto.getId();
|
|
||||||
this.name = genreDto.getName();
|
|
||||||
this.songCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ignore
|
|
||||||
public Genre(BaseItemDto itemDto) {
|
|
||||||
this.id = itemDto.getId();
|
|
||||||
this.name = itemDto.getName();
|
|
||||||
this.songCount = itemDto.getSongCount() != null ? itemDto.getSongCount() : 0;
|
|
||||||
|
|
||||||
this.primary = itemDto.getImageTags().containsKey(ImageType.Primary) ? id : null;
|
|
||||||
if (itemDto.getImageBlurHashes() != null && itemDto.getImageBlurHashes().get(ImageType.Primary) != null) {
|
|
||||||
this.blurHash = (String) itemDto.getImageBlurHashes().get(ImageType.Primary).values().toArray()[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,8 @@ import android.os.Parcelable;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.room.ColumnInfo;
|
import androidx.room.ColumnInfo;
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.Ignore;
|
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
|
||||||
import org.jellyfin.apiclient.model.entities.ImageType;
|
|
||||||
|
|
||||||
@Entity(tableName = "playlist")
|
@Entity(tableName = "playlist")
|
||||||
public class Playlist implements Parcelable {
|
public class Playlist implements Parcelable {
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
@ -35,17 +31,6 @@ public class Playlist implements Parcelable {
|
||||||
this.blurHash = blurHash;
|
this.blurHash = blurHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
public Playlist(BaseItemDto itemDto) {
|
|
||||||
this.id = itemDto.getId();
|
|
||||||
this.name = itemDto.getName();
|
|
||||||
|
|
||||||
this.primary = itemDto.getImageTags().containsKey(ImageType.Primary) ? id : null;
|
|
||||||
if (itemDto.getImageBlurHashes() != null && itemDto.getImageBlurHashes().get(ImageType.Primary) != null) {
|
|
||||||
this.blurHash = (String) itemDto.getImageBlurHashes().get(ImageType.Primary).values().toArray()[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package com.cappielloantonio.play.model;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.room.ColumnInfo;
|
import androidx.room.ColumnInfo;
|
||||||
|
|
@ -13,15 +12,7 @@ import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import com.cappielloantonio.play.subsonic.models.Child;
|
import com.cappielloantonio.play.subsonic.models.Child;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
|
||||||
import org.jellyfin.apiclient.model.dto.MediaSourceInfo;
|
|
||||||
import org.jellyfin.apiclient.model.entities.ImageType;
|
|
||||||
import org.jellyfin.apiclient.model.entities.MediaStream;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Entity(tableName = "song")
|
@Entity(tableName = "song")
|
||||||
|
|
@ -341,7 +332,9 @@ public class Song implements Parcelable {
|
||||||
this.playCount = playCount;
|
this.playCount = playCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOffline(boolean offline) { this.offline = offline; }
|
public void setOffline(boolean offline) {
|
||||||
|
this.offline = offline;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Log.i(TAG, "increasePlayCount: " + isIncreased);
|
Log.i(TAG, "increasePlayCount: " + isIncreased);
|
||||||
|
|
@ -354,7 +347,7 @@ public class Song implements Parcelable {
|
||||||
public boolean nowPlaying() {
|
public boolean nowPlaying() {
|
||||||
long startPlayTime = Instant.now().toEpochMilli();
|
long startPlayTime = Instant.now().toEpochMilli();
|
||||||
|
|
||||||
if(startPlayTime - (getDuration()/2) > getLastPlay()) {
|
if (startPlayTime - (getDuration() / 2) > getLastPlay()) {
|
||||||
this.playCount++;
|
this.playCount++;
|
||||||
this.lastPlay = startPlayTime;
|
this.lastPlay = startPlayTime;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,8 @@ import android.os.Parcelable;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.room.ColumnInfo;
|
import androidx.room.ColumnInfo;
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.Ignore;
|
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
|
||||||
import org.jellyfin.apiclient.model.dto.MediaSourceInfo;
|
|
||||||
import org.jellyfin.apiclient.model.entities.ImageType;
|
|
||||||
import org.jellyfin.apiclient.model.entities.MediaStream;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Entity(tableName = "song_genre_cross")
|
@Entity(tableName = "song_genre_cross")
|
||||||
public class SongGenreCross implements Parcelable {
|
public class SongGenreCross implements Parcelable {
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import com.cappielloantonio.play.interfaces.MediaCallback;
|
||||||
import com.cappielloantonio.play.model.Song;
|
import com.cappielloantonio.play.model.Song;
|
||||||
import com.cappielloantonio.play.model.SongGenreCross;
|
import com.cappielloantonio.play.model.SongGenreCross;
|
||||||
import com.cappielloantonio.play.subsonic.api.albumsonglist.AlbumSongListClient;
|
import com.cappielloantonio.play.subsonic.api.albumsonglist.AlbumSongListClient;
|
||||||
|
import com.cappielloantonio.play.subsonic.api.browsing.BrowsingClient;
|
||||||
import com.cappielloantonio.play.subsonic.models.ResponseStatus;
|
import com.cappielloantonio.play.subsonic.models.ResponseStatus;
|
||||||
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
|
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
|
||||||
import com.cappielloantonio.play.util.MappingUtil;
|
import com.cappielloantonio.play.util.MappingUtil;
|
||||||
|
|
@ -29,6 +30,7 @@ public class SongRepository {
|
||||||
private static final String TAG = "SongRepository";
|
private static final String TAG = "SongRepository";
|
||||||
|
|
||||||
private AlbumSongListClient albumSongListClient;
|
private AlbumSongListClient albumSongListClient;
|
||||||
|
private BrowsingClient browsingClient;
|
||||||
|
|
||||||
private SongDao songDao;
|
private SongDao songDao;
|
||||||
private SongGenreCrossDao songGenreCrossDao;
|
private SongGenreCrossDao songGenreCrossDao;
|
||||||
|
|
@ -50,6 +52,7 @@ public class SongRepository {
|
||||||
|
|
||||||
public SongRepository(Application application) {
|
public SongRepository(Application application) {
|
||||||
albumSongListClient = App.getSubsonicClientInstance(application, false).getAlbumSongListClient();
|
albumSongListClient = App.getSubsonicClientInstance(application, false).getAlbumSongListClient();
|
||||||
|
browsingClient = App.getSubsonicClientInstance(application, false).getBrowsingClient();
|
||||||
|
|
||||||
AppDatabase database = AppDatabase.getInstance(application);
|
AppDatabase database = AppDatabase.getInstance(application);
|
||||||
songDao = database.songDao();
|
songDao = database.songDao();
|
||||||
|
|
@ -79,6 +82,33 @@ public class SongRepository {
|
||||||
return liveSongs;
|
return liveSongs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getInstantMix(Song song, int count, MediaCallback callback) {
|
||||||
|
browsingClient
|
||||||
|
.getSimilarSongs2(song.getId(), count)
|
||||||
|
.enqueue(new Callback<SubsonicResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<SubsonicResponse> call, Response<SubsonicResponse> response) {
|
||||||
|
if (response.body().getStatus().getValue().equals(ResponseStatus.OK)) {
|
||||||
|
List<Song> songs = new ArrayList<>(MappingUtil.mapSong(response.body().getSimilarSongs2().getSongs()));
|
||||||
|
if(songs.size() > 1) {
|
||||||
|
callback.onLoadMedia(songs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
songs.add(song);
|
||||||
|
callback.onLoadMedia(songs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
|
||||||
|
List<Song> songs = new ArrayList<>();
|
||||||
|
songs.add(song);
|
||||||
|
callback.onLoadMedia(songs);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public LiveData<List<Song>> searchListLiveSong(String title, int limit) {
|
public LiveData<List<Song>> searchListLiveSong(String title, int limit) {
|
||||||
searchListLiveSongs = songDao.searchSong(title, limit);
|
searchListLiveSongs = songDao.searchSong(title, limit);
|
||||||
return searchListLiveSongs;
|
return searchListLiveSongs;
|
||||||
|
|
|
||||||
|
|
@ -37,20 +37,12 @@ import com.cappielloantonio.play.repository.SongRepository;
|
||||||
import com.cappielloantonio.play.ui.notification.PlayingNotification;
|
import com.cappielloantonio.play.ui.notification.PlayingNotification;
|
||||||
import com.cappielloantonio.play.util.PreferenceUtil;
|
import com.cappielloantonio.play.util.PreferenceUtil;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.interaction.EmptyResponse;
|
|
||||||
import org.jellyfin.apiclient.interaction.Response;
|
|
||||||
import org.jellyfin.apiclient.model.session.PlaybackProgressInfo;
|
|
||||||
import org.jellyfin.apiclient.model.session.PlaybackStartInfo;
|
|
||||||
import org.jellyfin.apiclient.model.session.PlaybackStopInfo;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_AUTO;
|
import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_AUTO;
|
||||||
import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED;
|
import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED;
|
||||||
|
|
@ -794,7 +786,6 @@ public class MusicService extends Service implements Playback.PlaybackCallbacks
|
||||||
private final WeakReference<MusicService> mService;
|
private final WeakReference<MusicService> mService;
|
||||||
|
|
||||||
private ScheduledExecutorService executorService;
|
private ScheduledExecutorService executorService;
|
||||||
private Future<?> task;
|
|
||||||
|
|
||||||
public ProgressHandler(MusicService service, Looper looper) {
|
public ProgressHandler(MusicService service, Looper looper) {
|
||||||
super(looper);
|
super(looper);
|
||||||
|
|
@ -806,67 +797,10 @@ public class MusicService extends Service implements Playback.PlaybackCallbacks
|
||||||
public void handleMessage(@NonNull final Message msg) {
|
public void handleMessage(@NonNull final Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case TRACK_STARTED:
|
case TRACK_STARTED:
|
||||||
onStart();
|
case TRACK_CHANGED: break;
|
||||||
case TRACK_CHANGED:
|
|
||||||
onNext();
|
|
||||||
break;
|
|
||||||
case TRACK_ENDED:
|
case TRACK_ENDED:
|
||||||
onStop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStart() {
|
|
||||||
if (executorService != null) executorService.shutdownNow();
|
|
||||||
|
|
||||||
executorService = Executors.newScheduledThreadPool(1);
|
|
||||||
task = executorService.scheduleAtFixedRate(this::onProgress, 10, 10, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onNext() {
|
|
||||||
PlaybackStartInfo startInfo = new PlaybackStartInfo();
|
|
||||||
|
|
||||||
startInfo.setItemId(mService.get().getCurrentSong().getId());
|
|
||||||
startInfo.setVolumeLevel(mService.get().playback.getVolume());
|
|
||||||
startInfo.setCanSeek(true);
|
|
||||||
startInfo.setIsPaused(false);
|
|
||||||
|
|
||||||
App.getApiClientInstance(App.getInstance()).ensureWebSocket();
|
|
||||||
App.getApiClientInstance(App.getInstance()).ReportPlaybackStartAsync(startInfo, new EmptyResponse());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onProgress() {
|
|
||||||
PlaybackProgressInfo progressInfo = new PlaybackProgressInfo();
|
|
||||||
|
|
||||||
// TODO these cause a wrong thread error
|
|
||||||
long progress = mService.get().getSongProgressMillis();
|
|
||||||
double duration = mService.get().getSongDurationMillis();
|
|
||||||
if (progress / duration > 0.9) {
|
|
||||||
Song current = mService.get().getCurrentSong();
|
|
||||||
String user = App.getApiClientInstance(App.getInstance()).getCurrentUserId();
|
|
||||||
Date time = new Date(System.currentTimeMillis());
|
|
||||||
|
|
||||||
App.getApiClientInstance(App.getInstance()).MarkPlayedAsync(current.getId(), user, time, new Response<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
progressInfo.setItemId(mService.get().getCurrentSong().getId());
|
|
||||||
progressInfo.setPositionTicks(progress * 10000);
|
|
||||||
progressInfo.setVolumeLevel(mService.get().playback.getVolume());
|
|
||||||
progressInfo.setIsPaused(!mService.get().playback.isPlaying());
|
|
||||||
progressInfo.setCanSeek(true);
|
|
||||||
|
|
||||||
App.getApiClientInstance(App.getInstance()).ReportPlaybackProgressAsync(progressInfo, new EmptyResponse());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onStop() {
|
|
||||||
PlaybackStopInfo info = new PlaybackStopInfo();
|
|
||||||
long progress = mService.get().getSongProgressMillis();
|
|
||||||
|
|
||||||
info.setItemId(mService.get().getCurrentSong().getId());
|
|
||||||
info.setPositionTicks(progress * 10000);
|
|
||||||
|
|
||||||
if (task != null) task.cancel(true);
|
|
||||||
if (executorService != null) executorService.shutdownNow();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MusicBinder extends Binder {
|
public class MusicBinder extends Binder {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public class MediaRetrievalClient {
|
||||||
this.mediaRetrievalService = retrofit.create(MediaRetrievalService.class);
|
this.mediaRetrievalService = retrofit.create(MediaRetrievalService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Call<SubsonicResponse> stream(String id, int maxBitRate, String format) {
|
public Call<SubsonicResponse> stream(String id, Integer maxBitRate, String format) {
|
||||||
Log.d(TAG, "stream()");
|
Log.d(TAG, "stream()");
|
||||||
return mediaRetrievalService.stream(subsonic.getParams(), id, maxBitRate, format);
|
return mediaRetrievalService.stream(subsonic.getParams(), id, maxBitRate, format);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,13 @@ import java.util.Map;
|
||||||
|
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.Query;
|
||||||
import retrofit2.http.QueryMap;
|
import retrofit2.http.QueryMap;
|
||||||
|
|
||||||
public interface MediaRetrievalService {
|
public interface MediaRetrievalService {
|
||||||
@GET("stream?id={id}?maxBitRate={maxBitRate}?format={format}")
|
@GET("stream")
|
||||||
Call<SubsonicResponse> stream(@QueryMap Map<String, String> params, String id, int maxBitRate, String format);
|
Call<SubsonicResponse> stream(@QueryMap Map<String, String> params, @Query("id") String id, @Query("maxBitRate") Integer maxBitRate, @Query("format") String format);
|
||||||
|
|
||||||
@GET("download?id={id}")
|
@GET("download")
|
||||||
Call<SubsonicResponse> download(@QueryMap Map<String, String> params, String id);
|
Call<SubsonicResponse> download(@QueryMap Map<String, String> params, @Query("id") String id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,7 @@ package com.cappielloantonio.play.ui.activity;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
@ -14,25 +12,18 @@ import androidx.navigation.NavController;
|
||||||
import androidx.navigation.fragment.NavHostFragment;
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
import androidx.navigation.ui.NavigationUI;
|
import androidx.navigation.ui.NavigationUI;
|
||||||
|
|
||||||
import com.cappielloantonio.play.App;
|
|
||||||
import com.cappielloantonio.play.R;
|
import com.cappielloantonio.play.R;
|
||||||
import com.cappielloantonio.play.broadcast.receiver.ConnectivityStatusBroadcastReceiver;
|
import com.cappielloantonio.play.broadcast.receiver.ConnectivityStatusBroadcastReceiver;
|
||||||
import com.cappielloantonio.play.databinding.ActivityMainBinding;
|
import com.cappielloantonio.play.databinding.ActivityMainBinding;
|
||||||
import com.cappielloantonio.play.service.MusicPlayerRemote;
|
|
||||||
import com.cappielloantonio.play.model.Song;
|
import com.cappielloantonio.play.model.Song;
|
||||||
|
import com.cappielloantonio.play.service.MusicPlayerRemote;
|
||||||
import com.cappielloantonio.play.ui.activity.base.BaseActivity;
|
import com.cappielloantonio.play.ui.activity.base.BaseActivity;
|
||||||
import com.cappielloantonio.play.ui.fragment.PlayerBottomSheetFragment;
|
import com.cappielloantonio.play.ui.fragment.PlayerBottomSheetFragment;
|
||||||
import com.cappielloantonio.play.util.PreferenceUtil;
|
import com.cappielloantonio.play.util.PreferenceUtil;
|
||||||
import com.cappielloantonio.play.util.SyncUtil;
|
|
||||||
import com.cappielloantonio.play.viewmodel.MainViewModel;
|
import com.cappielloantonio.play.viewmodel.MainViewModel;
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.interaction.EmptyResponse;
|
|
||||||
import org.jellyfin.apiclient.interaction.Response;
|
|
||||||
import org.jellyfin.apiclient.model.session.ClientCapabilities;
|
|
||||||
import org.jellyfin.apiclient.model.system.SystemInfo;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MainActivity extends BaseActivity {
|
public class MainActivity extends BaseActivity {
|
||||||
|
|
@ -78,35 +69,12 @@ public class MainActivity extends BaseActivity {
|
||||||
initNavigation();
|
initNavigation();
|
||||||
|
|
||||||
if (PreferenceUtil.getInstance(this).getToken() != null) {
|
if (PreferenceUtil.getInstance(this).getToken() != null) {
|
||||||
checkPreviousSession();
|
|
||||||
goFromLogin();
|
goFromLogin();
|
||||||
} else {
|
} else {
|
||||||
goToLogin();
|
goToLogin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkPreviousSession() {
|
|
||||||
App.getApiClientInstance(getApplicationContext()).ChangeServerLocation(PreferenceUtil.getInstance(this).getServer());
|
|
||||||
App.getApiClientInstance(getApplicationContext()).SetAuthenticationInfo(PreferenceUtil.getInstance(this).getToken(), PreferenceUtil.getInstance(this).getUser());
|
|
||||||
App.getApiClientInstance(getApplicationContext()).GetSystemInfoAsync(new Response<SystemInfo>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(SystemInfo result) {
|
|
||||||
ClientCapabilities clientCapabilities = new ClientCapabilities();
|
|
||||||
clientCapabilities.setSupportsMediaControl(true);
|
|
||||||
clientCapabilities.setSupportsPersistentIdentifier(true);
|
|
||||||
|
|
||||||
App.getApiClientInstance(getApplicationContext()).ensureWebSocket();
|
|
||||||
App.getApiClientInstance(getApplicationContext()).ReportCapabilities(clientCapabilities, new EmptyResponse());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Exception exception) {
|
|
||||||
Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// BOTTOM SHEET/NAVIGATION
|
// BOTTOM SHEET/NAVIGATION
|
||||||
private void initBottomSheet() {
|
private void initBottomSheet() {
|
||||||
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.player_bottom_sheet));
|
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.player_bottom_sheet));
|
||||||
|
|
@ -176,7 +144,8 @@ public class MainActivity extends BaseActivity {
|
||||||
case BottomSheetBehavior.STATE_COLLAPSED:
|
case BottomSheetBehavior.STATE_COLLAPSED:
|
||||||
case BottomSheetBehavior.STATE_SETTLING:
|
case BottomSheetBehavior.STATE_SETTLING:
|
||||||
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
|
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
|
||||||
if (playerBottomSheetFragment != null) playerBottomSheetFragment.scrollOnTop();
|
if (playerBottomSheetFragment != null)
|
||||||
|
playerBottomSheetFragment.scrollOnTop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,8 +155,7 @@ public class MainActivity extends BaseActivity {
|
||||||
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
|
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
|
||||||
if (playerBottomSheetFragment == null) {
|
if (playerBottomSheetFragment == null) {
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
float condensedSlideOffset = Math.max(0.0f, Math.min(0.2f, slideOffset - 0.2f)) / 0.2f;
|
float condensedSlideOffset = Math.max(0.0f, Math.min(0.2f, slideOffset - 0.2f)) / 0.2f;
|
||||||
playerBottomSheetFragment.getPlayerHeader().setAlpha(1 - condensedSlideOffset);
|
playerBottomSheetFragment.getPlayerHeader().setAlpha(1 - condensedSlideOffset);
|
||||||
playerBottomSheetFragment.getPlayerHeader().setVisibility(condensedSlideOffset > 0.99 ? View.GONE : View.VISIBLE);
|
playerBottomSheetFragment.getPlayerHeader().setVisibility(condensedSlideOffset > 0.99 ? View.GONE : View.VISIBLE);
|
||||||
|
|
@ -217,8 +185,7 @@ public class MainActivity extends BaseActivity {
|
||||||
|
|
||||||
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment) {
|
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment) {
|
||||||
navController.navigate(R.id.action_landingFragment_to_homeFragment);
|
navController.navigate(R.id.action_landingFragment_to_homeFragment);
|
||||||
}
|
} else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.loginFragment) {
|
||||||
else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.loginFragment) {
|
|
||||||
navController.navigate(R.id.action_loginFragment_to_homeFragment);
|
navController.navigate(R.id.action_loginFragment_to_homeFragment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,34 @@
|
||||||
package com.cappielloantonio.play.util;
|
package com.cappielloantonio.play.util;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.cappielloantonio.play.App;
|
import com.cappielloantonio.play.App;
|
||||||
import com.cappielloantonio.play.R;
|
import com.cappielloantonio.play.R;
|
||||||
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
import com.cappielloantonio.play.glide.CustomGlideRequest;
|
||||||
import com.cappielloantonio.play.model.DirectPlayCodec;
|
|
||||||
import com.cappielloantonio.play.model.Song;
|
import com.cappielloantonio.play.model.Song;
|
||||||
import com.google.android.exoplayer2.MediaItem;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.interaction.ApiClient;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class MusicUtil {
|
public class MusicUtil {
|
||||||
|
private static final String TAG = "MusicUtil";
|
||||||
|
|
||||||
public static String getSongFileUri(Song song) {
|
public static String getSongFileUri(Song song) {
|
||||||
ApiClient apiClient = App.getApiClientInstance(App.getInstance());
|
String url = App.getSubsonicClientInstance(App.getInstance(), false).getUrl();
|
||||||
PreferenceUtil preferenceUtil = PreferenceUtil.getInstance(App.getInstance());
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder(256);
|
Map<String, String> params = App.getSubsonicClientInstance(App.getInstance(), false).getParams();
|
||||||
builder.append(apiClient.getApiUrl());
|
|
||||||
builder.append("/Audio/");
|
|
||||||
builder.append(song.getId());
|
|
||||||
builder.append("/universal");
|
|
||||||
builder.append("?UserId=").append(apiClient.getCurrentUserId());
|
|
||||||
builder.append("&DeviceId=").append(apiClient.getDeviceId());
|
|
||||||
|
|
||||||
// web client maximum is 12444445 and 320kbps is 320000
|
return url + "stream" +
|
||||||
builder.append("&MaxStreamingBitrate=").append(preferenceUtil.getMaximumBitrate());
|
"?u=" + params.get("u") +
|
||||||
|
"&s=" + params.get("s") +
|
||||||
boolean containerAdded = false;
|
"&t=" + params.get("t") +
|
||||||
for (DirectPlayCodec directPlayCodec : preferenceUtil.getDirectPlayCodecs()) {
|
"&v=" + params.get("v") +
|
||||||
if (directPlayCodec.selected) {
|
"&c=" + params.get("c") +
|
||||||
if (!containerAdded) {
|
"&id=" + song.getId();
|
||||||
builder.append("&Container=");
|
|
||||||
containerAdded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.append(directPlayCodec.codec.value).append(',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (containerAdded) {
|
|
||||||
// remove last comma
|
|
||||||
builder.deleteCharAt(builder.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.append("&TranscodingContainer=ts");
|
|
||||||
builder.append("&TranscodingProtocol=hls");
|
|
||||||
|
|
||||||
// preferred codec when transcoding
|
|
||||||
builder.append("&AudioCodec=").append(preferenceUtil.getTranscodeCodec());
|
|
||||||
builder.append("&api_key=").append(apiClient.getAccessToken());
|
|
||||||
|
|
||||||
Log.i(MusicUtil.class.getName(), "playing audio: " + builder);
|
|
||||||
return builder.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getReadableDurationString(long songDurationMillis) {
|
public static String getReadableDurationString(long songDurationMillis) {
|
||||||
|
|
|
||||||
|
|
@ -5,22 +5,14 @@ import android.os.Bundle;
|
||||||
|
|
||||||
import com.cappielloantonio.play.App;
|
import com.cappielloantonio.play.App;
|
||||||
import com.cappielloantonio.play.interfaces.MediaCallback;
|
import com.cappielloantonio.play.interfaces.MediaCallback;
|
||||||
import com.cappielloantonio.play.model.PlaylistSongCross;
|
|
||||||
import com.cappielloantonio.play.model.Song;
|
import com.cappielloantonio.play.model.Song;
|
||||||
import com.cappielloantonio.play.subsonic.models.AlbumID3;
|
import com.cappielloantonio.play.subsonic.models.AlbumID3;
|
||||||
import com.cappielloantonio.play.subsonic.models.ArtistID3;
|
import com.cappielloantonio.play.subsonic.models.ArtistID3;
|
||||||
import com.cappielloantonio.play.subsonic.models.Child;
|
|
||||||
import com.cappielloantonio.play.subsonic.models.IndexID3;
|
import com.cappielloantonio.play.subsonic.models.IndexID3;
|
||||||
import com.cappielloantonio.play.subsonic.models.MusicFolder;
|
import com.cappielloantonio.play.subsonic.models.MusicFolder;
|
||||||
import com.cappielloantonio.play.subsonic.models.ResponseStatus;
|
import com.cappielloantonio.play.subsonic.models.ResponseStatus;
|
||||||
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
|
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
|
||||||
|
|
||||||
import org.jellyfin.apiclient.interaction.Response;
|
|
||||||
import org.jellyfin.apiclient.model.dto.BaseItemDto;
|
|
||||||
import org.jellyfin.apiclient.model.playlists.PlaylistItemQuery;
|
|
||||||
import org.jellyfin.apiclient.model.querying.ItemFields;
|
|
||||||
import org.jellyfin.apiclient.model.querying.ItemsResult;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -203,7 +195,7 @@ public class SyncUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void getSongsPerPlaylist(Context context, MediaCallback callback, String playlistId) {
|
public static void getSongsPerPlaylist(Context context, MediaCallback callback, String playlistId) {
|
||||||
PlaylistItemQuery query = new PlaylistItemQuery();
|
/*PlaylistItemQuery query = new PlaylistItemQuery();
|
||||||
|
|
||||||
query.setId(playlistId);
|
query.setId(playlistId);
|
||||||
query.setUserId(App.getApiClientInstance(context).getCurrentUserId());
|
query.setUserId(App.getApiClientInstance(context).getCurrentUserId());
|
||||||
|
|
@ -227,7 +219,7 @@ public class SyncUtil {
|
||||||
public void onError(Exception exception) {
|
public void onError(Exception exception) {
|
||||||
callback.onError(exception);
|
callback.onError(exception);
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void getInstantMix(Context context, MediaCallback callback, String resultType, String itemID, int limit) {
|
public static void getInstantMix(Context context, MediaCallback callback, String resultType, String itemID, int limit) {
|
||||||
|
|
@ -308,7 +300,7 @@ public class SyncUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateSongData(Map<Integer, Song> library, List<Song> songs) {
|
private static void updateSongData(Map<Integer, Song> library, List<Song> songs) {
|
||||||
for (Song song: songs) {
|
for (Song song : songs) {
|
||||||
if (library.containsKey(song.hashCode())) {
|
if (library.containsKey(song.hashCode())) {
|
||||||
Song oldSong = library.get(song.hashCode());
|
Song oldSong = library.get(song.hashCode());
|
||||||
song.setFavorite(oldSong.isFavorite());
|
song.setFavorite(oldSong.isFavorite());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue