Removed Jellyfin dependencies

This commit is contained in:
CappielloAntonio 2021-07-27 14:53:03 +02:00
parent 737eaa1822
commit 9495fbd83d
16 changed files with 62 additions and 310 deletions

View file

@ -35,9 +35,6 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
// Jellyfin
implementation 'com.github.jellyfin.jellyfin-apiclient-java:android:0.7.7'
// AndroidX
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
@ -88,8 +85,6 @@ dependencies {
annotationProcessor 'com.tickaroo.tikxml:processor: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
// debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'

View file

@ -11,20 +11,9 @@ import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.SubsonicPreferences;
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 {
private static final String TAG = "App";
private static App instance;
private static ApiClient apiClient;
private static Subsonic subsonic;
@Override
@ -44,26 +33,6 @@ public class App extends Application {
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) {
if (subsonic == null || override) {
subsonic = getSubsonicClient(context);

View file

@ -18,9 +18,6 @@ import com.cappielloantonio.play.R;
import com.cappielloantonio.play.util.MusicUtil;
import com.wolt.blurhashkt.BlurHashDecoder;
import org.jellyfin.apiclient.model.dto.ImageOptions;
import org.jellyfin.apiclient.model.entities.ImageType;
import java.util.Map;
public class CustomGlideRequest {
@ -50,7 +47,7 @@ public class CustomGlideRequest {
String url = App.getSubsonicClientInstance(App.getInstance(), false).getUrl();
Map<String, String> params = App.getSubsonicClientInstance(App.getInstance(), false).getParams();
String sb = url + "/rest/" + "getCoverArt" +
String sb = url + "getCoverArt" +
"?u=" + params.get("u") +
"&s=" + params.get("s") +
"&t=" + params.get("t") +

View file

@ -2,7 +2,6 @@ package com.cappielloantonio.play.model;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
@ -12,13 +11,6 @@ import androidx.room.PrimaryKey;
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")
public class Album implements Parcelable {
private static final String TAG = "Album";

View file

@ -2,7 +2,6 @@ package com.cappielloantonio.play.model;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
@ -10,10 +9,6 @@ import androidx.room.Entity;
import androidx.room.Ignore;
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.List;
@ -56,39 +51,6 @@ public class Artist implements Parcelable {
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
public Artist(String id, String name) {
this.id = id;

View file

@ -6,15 +6,8 @@ import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
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")
public class Genre implements Parcelable {
@NonNull
@ -42,25 +35,6 @@ public class Genre implements Parcelable {
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
public String getId() {
return id;

View file

@ -6,12 +6,8 @@ import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
import org.jellyfin.apiclient.model.dto.BaseItemDto;
import org.jellyfin.apiclient.model.entities.ImageType;
@Entity(tableName = "playlist")
public class Playlist implements Parcelable {
@NonNull
@ -35,17 +31,6 @@ public class Playlist implements Parcelable {
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
public String getId() {
return id;

View file

@ -3,7 +3,6 @@ package com.cappielloantonio.play.model;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
@ -13,15 +12,7 @@ import androidx.room.PrimaryKey;
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.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Entity(tableName = "song")
@ -341,7 +332,9 @@ public class Song implements Parcelable {
this.playCount = playCount;
}
public void setOffline(boolean offline) { this.offline = offline; }
public void setOffline(boolean offline) {
this.offline = offline;
}
/*
Log.i(TAG, "increasePlayCount: " + isIncreased);
@ -354,7 +347,7 @@ public class Song implements Parcelable {
public boolean nowPlaying() {
long startPlayTime = Instant.now().toEpochMilli();
if(startPlayTime - (getDuration()/2) > getLastPlay()) {
if (startPlayTime - (getDuration() / 2) > getLastPlay()) {
this.playCount++;
this.lastPlay = startPlayTime;
return true;

View file

@ -6,17 +6,8 @@ import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
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")
public class SongGenreCross implements Parcelable {
@NonNull

View file

@ -13,6 +13,7 @@ import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.model.SongGenreCross;
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.SubsonicResponse;
import com.cappielloantonio.play.util.MappingUtil;
@ -29,6 +30,7 @@ public class SongRepository {
private static final String TAG = "SongRepository";
private AlbumSongListClient albumSongListClient;
private BrowsingClient browsingClient;
private SongDao songDao;
private SongGenreCrossDao songGenreCrossDao;
@ -50,6 +52,7 @@ public class SongRepository {
public SongRepository(Application application) {
albumSongListClient = App.getSubsonicClientInstance(application, false).getAlbumSongListClient();
browsingClient = App.getSubsonicClientInstance(application, false).getBrowsingClient();
AppDatabase database = AppDatabase.getInstance(application);
songDao = database.songDao();
@ -79,6 +82,33 @@ public class SongRepository {
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) {
searchListLiveSongs = songDao.searchSong(title, limit);
return searchListLiveSongs;

View file

@ -37,20 +37,12 @@ import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.ui.notification.PlayingNotification;
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.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
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_PLAYLIST_CHANGED;
@ -794,7 +786,6 @@ public class MusicService extends Service implements Playback.PlaybackCallbacks
private final WeakReference<MusicService> mService;
private ScheduledExecutorService executorService;
private Future<?> task;
public ProgressHandler(MusicService service, Looper looper) {
super(looper);
@ -806,67 +797,10 @@ public class MusicService extends Service implements Playback.PlaybackCallbacks
public void handleMessage(@NonNull final Message msg) {
switch (msg.what) {
case TRACK_STARTED:
onStart();
case TRACK_CHANGED:
onNext();
break;
case TRACK_CHANGED: break;
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 {

View file

@ -30,7 +30,7 @@ public class MediaRetrievalClient {
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()");
return mediaRetrievalService.stream(subsonic.getParams(), id, maxBitRate, format);
}

View file

@ -6,12 +6,13 @@ import java.util.Map;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
public interface MediaRetrievalService {
@GET("stream?id={id}?maxBitRate={maxBitRate}?format={format}")
Call<SubsonicResponse> stream(@QueryMap Map<String, String> params, String id, int maxBitRate, String format);
@GET("stream")
Call<SubsonicResponse> stream(@QueryMap Map<String, String> params, @Query("id") String id, @Query("maxBitRate") Integer maxBitRate, @Query("format") String format);
@GET("download?id={id}")
Call<SubsonicResponse> download(@QueryMap Map<String, String> params, String id);
@GET("download")
Call<SubsonicResponse> download(@QueryMap Map<String, String> params, @Query("id") String id);
}

View file

@ -3,9 +3,7 @@ package com.cappielloantonio.play.ui.activity;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
@ -14,25 +12,18 @@ import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.NavigationUI;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.broadcast.receiver.ConnectivityStatusBroadcastReceiver;
import com.cappielloantonio.play.databinding.ActivityMainBinding;
import com.cappielloantonio.play.service.MusicPlayerRemote;
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.fragment.PlayerBottomSheetFragment;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.util.SyncUtil;
import com.cappielloantonio.play.viewmodel.MainViewModel;
import com.google.android.material.bottomnavigation.BottomNavigationView;
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;
public class MainActivity extends BaseActivity {
@ -78,35 +69,12 @@ public class MainActivity extends BaseActivity {
initNavigation();
if (PreferenceUtil.getInstance(this).getToken() != null) {
checkPreviousSession();
goFromLogin();
} else {
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
private void initBottomSheet() {
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_SETTLING:
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
if (playerBottomSheetFragment != null) playerBottomSheetFragment.scrollOnTop();
if (playerBottomSheetFragment != null)
playerBottomSheetFragment.scrollOnTop();
break;
}
}
@ -186,8 +155,7 @@ public class MainActivity extends BaseActivity {
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
if (playerBottomSheetFragment == null) {
return;
}
else {
} else {
float condensedSlideOffset = Math.max(0.0f, Math.min(0.2f, slideOffset - 0.2f)) / 0.2f;
playerBottomSheetFragment.getPlayerHeader().setAlpha(1 - condensedSlideOffset);
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) {
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);
}
}

View file

@ -1,64 +1,34 @@
package com.cappielloantonio.play.util;
import android.content.Context;
import android.util.Log;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.glide.CustomGlideRequest;
import com.cappielloantonio.play.model.DirectPlayCodec;
import com.cappielloantonio.play.model.Song;
import com.google.android.exoplayer2.MediaItem;
import org.jellyfin.apiclient.interaction.ApiClient;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
public class MusicUtil {
private static final String TAG = "MusicUtil";
public static String getSongFileUri(Song song) {
ApiClient apiClient = App.getApiClientInstance(App.getInstance());
PreferenceUtil preferenceUtil = PreferenceUtil.getInstance(App.getInstance());
String url = App.getSubsonicClientInstance(App.getInstance(), false).getUrl();
StringBuilder builder = new StringBuilder(256);
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());
Map<String, String> params = App.getSubsonicClientInstance(App.getInstance(), false).getParams();
// web client maximum is 12444445 and 320kbps is 320000
builder.append("&MaxStreamingBitrate=").append(preferenceUtil.getMaximumBitrate());
boolean containerAdded = false;
for (DirectPlayCodec directPlayCodec : preferenceUtil.getDirectPlayCodecs()) {
if (directPlayCodec.selected) {
if (!containerAdded) {
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();
return url + "stream" +
"?u=" + params.get("u") +
"&s=" + params.get("s") +
"&t=" + params.get("t") +
"&v=" + params.get("v") +
"&c=" + params.get("c") +
"&id=" + song.getId();
}
public static String getReadableDurationString(long songDurationMillis) {

View file

@ -5,22 +5,14 @@ import android.os.Bundle;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.PlaylistSongCross;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.subsonic.models.AlbumID3;
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.MusicFolder;
import com.cappielloantonio.play.subsonic.models.ResponseStatus;
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.List;
import java.util.Map;
@ -203,7 +195,7 @@ public class SyncUtil {
}
public static void getSongsPerPlaylist(Context context, MediaCallback callback, String playlistId) {
PlaylistItemQuery query = new PlaylistItemQuery();
/*PlaylistItemQuery query = new PlaylistItemQuery();
query.setId(playlistId);
query.setUserId(App.getApiClientInstance(context).getCurrentUserId());
@ -227,7 +219,7 @@ public class SyncUtil {
public void onError(Exception exception) {
callback.onError(exception);
}
});
});*/
}
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) {
for (Song song: songs) {
for (Song song : songs) {
if (library.containsKey(song.hashCode())) {
Song oldSong = library.get(song.hashCode());
song.setFavorite(oldSong.isFavorite());