From 5197af70a930865de150ad708796d2581f17ac42 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 29 Aug 2020 15:37:08 +0900 Subject: [PATCH] add useful information to song details dialog --- .../gramophone/dialogs/SongDetailDialog.java | 62 ++++++++++++++----- .../com/dkanada/gramophone/model/Song.java | 56 ++++++++++++++++- .../library/pager/SongsFragment.java | 2 + .../dkanada/gramophone/util/QueryUtil.java | 4 +- .../main/res/layout/dialog_file_details.xml | 20 +++++- app/src/main/res/values/strings.xml | 8 ++- 6 files changed, 132 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/dkanada/gramophone/dialogs/SongDetailDialog.java b/app/src/main/java/com/dkanada/gramophone/dialogs/SongDetailDialog.java index 5af56d67..d05613be 100644 --- a/app/src/main/java/com/dkanada/gramophone/dialogs/SongDetailDialog.java +++ b/app/src/main/java/com/dkanada/gramophone/dialogs/SongDetailDialog.java @@ -36,6 +36,19 @@ public class SongDetailDialog extends DialogFragment { return fileSizeInMB + " MB"; } + private static String getSampleRateString(int sampleRate) { + return sampleRate + " Hz"; + } + + private static String getBitRateString(int bitRate) { + int bitRateInKB = bitRate / 1000; + return bitRateInKB + " kb/s"; + } + + private static String getBitDepthString(int bitDepth) { + return bitDepth + "-bit"; + } + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { @@ -49,25 +62,46 @@ public class SongDetailDialog extends DialogFragment { .build(); View dialogView = dialog.getCustomView(); - final TextView filePath = dialogView.findViewById(R.id.file_path); - final TextView fileName = dialogView.findViewById(R.id.file_name); - final TextView fileSize = dialogView.findViewById(R.id.file_size); - final TextView fileFormat = dialogView.findViewById(R.id.file_format); - final TextView trackLength = dialogView.findViewById(R.id.track_length); - final TextView bitRate = dialogView.findViewById(R.id.bit_rate); + final TextView path = dialogView.findViewById(R.id.file_path); + final TextView name = dialogView.findViewById(R.id.file_name); + final TextView size = dialogView.findViewById(R.id.file_size); + final TextView format = dialogView.findViewById(R.id.file_format); + final TextView length = dialogView.findViewById(R.id.track_length); final TextView sampleRate = dialogView.findViewById(R.id.sample_rate); + final TextView bitRate = dialogView.findViewById(R.id.bit_rate); + final TextView bitDepth = dialogView.findViewById(R.id.bit_depth); + final TextView channels = dialogView.findViewById(R.id.channels); - filePath.setText(makeTextWithTitle(context, R.string.label_file_path, "-")); - fileName.setText(makeTextWithTitle(context, R.string.label_file_name, "-")); - fileSize.setText(makeTextWithTitle(context, R.string.label_file_size, "-")); - fileFormat.setText(makeTextWithTitle(context, R.string.label_file_format, "-")); - trackLength.setText(makeTextWithTitle(context, R.string.label_track_length, "-")); - bitRate.setText(makeTextWithTitle(context, R.string.label_bit_rate, "-")); + path.setText(makeTextWithTitle(context, R.string.label_file_path, "-")); + name.setText(makeTextWithTitle(context, R.string.label_file_name, "-")); + size.setText(makeTextWithTitle(context, R.string.label_file_size, "-")); + format.setText(makeTextWithTitle(context, R.string.label_file_format, "-")); + length.setText(makeTextWithTitle(context, R.string.label_track_length, "-")); sampleRate.setText(makeTextWithTitle(context, R.string.label_sample_rate, "-")); + bitRate.setText(makeTextWithTitle(context, R.string.label_bit_rate, "-")); + bitDepth.setText(makeTextWithTitle(context, R.string.label_bit_depth, "-")); + channels.setText(makeTextWithTitle(context, R.string.label_channels, "-")); if (song != null) { - fileName.setText(makeTextWithTitle(context, R.string.label_file_name, song.title)); - trackLength.setText(makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.duration))); + path.setText(makeTextWithTitle(context, R.string.label_file_path, song.path)); + name.setText(makeTextWithTitle(context, R.string.label_file_name, song.title)); + size.setText(makeTextWithTitle(context, R.string.label_file_size, getFileSizeString(song.size))); + + if (song.container.equals(song.codec)) { + format.setText(makeTextWithTitle(context, R.string.label_file_format, song.container.toUpperCase())); + } else { + format.setText(makeTextWithTitle(context, R.string.label_file_format, song.container.toUpperCase() + ":" + song.codec.toUpperCase())); + } + + length.setText(makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.duration))); + sampleRate.setText(makeTextWithTitle(context, R.string.label_sample_rate, getSampleRateString(song.sampleRate))); + bitRate.setText(makeTextWithTitle(context, R.string.label_bit_rate, getBitRateString(song.bitRate))); + bitDepth.setText(makeTextWithTitle(context, R.string.label_bit_depth, getBitDepthString(song.bitDepth))); + channels.setText(makeTextWithTitle(context, R.string.label_channels, Integer.toString(song.channels))); + + if (song.bitDepth == 0) { + bitDepth.setVisibility(View.GONE); + } } return dialog; diff --git a/app/src/main/java/com/dkanada/gramophone/model/Song.java b/app/src/main/java/com/dkanada/gramophone/model/Song.java index 601d5fc2..7388c467 100644 --- a/app/src/main/java/com/dkanada/gramophone/model/Song.java +++ b/app/src/main/java/com/dkanada/gramophone/model/Song.java @@ -4,6 +4,8 @@ import android.os.Parcel; import android.os.Parcelable; import org.jellyfin.apiclient.model.dto.BaseItemDto; +import org.jellyfin.apiclient.model.dto.MediaSourceInfo; +import org.jellyfin.apiclient.model.entities.MediaStream; public class Song implements Parcelable { public static final Song EMPTY_SONG = new Song(null, "", -1, -1, -1, -1, null, "", null, "", null, false); @@ -24,6 +26,17 @@ public class Song implements Parcelable { public String primary; public boolean favorite; + public String path; + public long size; + + public String container; + public String codec; + + public int sampleRate; + public int bitRate; + public int bitDepth; + public int channels; + public Song(BaseItemDto itemDto) { this.id = itemDto.getId(); this.title = itemDto.getName(); @@ -45,6 +58,25 @@ public class Song implements Parcelable { this.primary = itemDto.getAlbumPrimaryImageTag() != null ? albumId : null; this.favorite = itemDto.getUserData() != null && itemDto.getUserData().getIsFavorite(); + + if (itemDto.getMediaSources() != null && itemDto.getMediaSources().get(0) != null) { + MediaSourceInfo source = itemDto.getMediaSources().get(0); + + this.path = source.getPath(); + this.size = source.getSize(); + + this.container = source.getContainer(); + this.bitRate = source.getBitrate(); + + if (source.getMediaStreams() != null && source.getMediaStreams().get(0) != null) { + MediaStream stream = source.getMediaStreams().get(0); + + this.codec = stream.getCodec(); + this.sampleRate = stream.getSampleRate() != null ? stream.getSampleRate() : 0; + this.bitDepth = stream.getBitDepth() != null ? stream.getBitDepth() : 0; + this.channels = stream.getChannels() != null ? stream.getChannels() : 0; + } + } } public Song(String id, String title, int trackNumber, int discNumber, int year, long duration, String albumId, String albumName, String artistId, String artistName, String primary, boolean favorite) { @@ -106,6 +138,17 @@ public class Song implements Parcelable { dest.writeString(this.primary); dest.writeString(Boolean.toString(favorite)); + + dest.writeString(this.path); + dest.writeLong(this.size); + + dest.writeString(this.container); + dest.writeString(this.codec); + + dest.writeInt(this.sampleRate); + dest.writeInt(this.bitRate); + dest.writeInt(this.bitDepth); + dest.writeInt(this.channels); } protected Song(Parcel in) { @@ -123,7 +166,18 @@ public class Song implements Parcelable { this.artistName = in.readString(); this.primary = in.readString(); - this.favorite = Boolean.valueOf(in.readString()); + this.favorite = Boolean.parseBoolean(in.readString()); + + this.path = in.readString(); + this.size = in.readLong(); + + this.container = in.readString(); + this.codec = in.readString(); + + this.sampleRate = in.readInt(); + this.bitRate = in.readInt(); + this.bitDepth = in.readInt(); + this.channels = in.readInt(); } public static final Creator CREATOR = new Creator() { diff --git a/app/src/main/java/com/dkanada/gramophone/ui/fragments/mainactivity/library/pager/SongsFragment.java b/app/src/main/java/com/dkanada/gramophone/ui/fragments/mainactivity/library/pager/SongsFragment.java index 119597f0..495b0cd1 100644 --- a/app/src/main/java/com/dkanada/gramophone/ui/fragments/mainactivity/library/pager/SongsFragment.java +++ b/app/src/main/java/com/dkanada/gramophone/ui/fragments/mainactivity/library/pager/SongsFragment.java @@ -14,6 +14,7 @@ import com.dkanada.gramophone.util.QueryUtil; import org.jellyfin.apiclient.interaction.Response; import org.jellyfin.apiclient.model.dto.BaseItemDto; +import org.jellyfin.apiclient.model.querying.ItemFields; import org.jellyfin.apiclient.model.querying.ItemQuery; import org.jellyfin.apiclient.model.querying.ItemsResult; @@ -67,6 +68,7 @@ public class SongsFragment extends AbsLibraryPagerRecyclerViewCustomGridSizeFrag ItemQuery query = new ItemQuery(); query.setIncludeItemTypes(new String[]{"Audio"}); + query.setFields(new ItemFields[]{ItemFields.MediaSources}); query.setUserId(App.getApiClient().getCurrentUserId()); query.setRecursive(true); query.setLimit(PreferenceUtil.getInstance(App.getInstance()).getMaximumListSize()); diff --git a/app/src/main/java/com/dkanada/gramophone/util/QueryUtil.java b/app/src/main/java/com/dkanada/gramophone/util/QueryUtil.java index 47449033..6bfcba29 100644 --- a/app/src/main/java/com/dkanada/gramophone/util/QueryUtil.java +++ b/app/src/main/java/com/dkanada/gramophone/util/QueryUtil.java @@ -90,7 +90,8 @@ public class QueryUtil { } public static void getItems(ItemQuery query, MediaCallback callback) { - query.setIncludeItemTypes(new String[]{"MusicArtist", "MusicAlbum", "Audio"}); + query.setIncludeItemTypes(new String[]{"MusicAlbum", "Audio"}); + query.setFields(new ItemFields[]{ItemFields.MediaSources}); query.setUserId(App.getApiClient().getCurrentUserId()); query.setLimit(40); query.setRecursive(true); @@ -163,6 +164,7 @@ public class QueryUtil { public static void getSongs(ItemQuery query, MediaCallback callback) { query.setIncludeItemTypes(new String[]{"Audio"}); + query.setFields(new ItemFields[]{ItemFields.MediaSources}); applyProperties(query); applySortMethod(query, PreferenceUtil.getInstance(App.getInstance()).getSongSortMethod()); App.getApiClient().GetItemsAsync(query, new Response() { diff --git a/app/src/main/res/layout/dialog_file_details.xml b/app/src/main/res/layout/dialog_file_details.xml index 19e9b5ce..6de3c151 100644 --- a/app/src/main/res/layout/dialog_file_details.xml +++ b/app/src/main/res/layout/dialog_file_details.xml @@ -50,6 +50,15 @@ android:textAppearance="?android:textAppearanceMedium" android:textSize="16sp" /> + + + + Album Details - File Name - File Path + Path + Name Size Format Length - Bit Rate Sample Rate + Bit Rate + Bit Depth + Channels Battery Optimizations Please disable battery optimizations for media playback while the screen is off.