mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2026-05-16 04:52:39 +02:00
Fixed thumbnails acting up and added support for library content thumbnail when casting.
This commit is contained in:
@@ -444,15 +444,9 @@ fun addressScore(addr: InetAddress): Int {
|
|||||||
|
|
||||||
fun <T> Enumeration<T>.toList(): List<T> = Collections.list(this)
|
fun <T> Enumeration<T>.toList(): List<T> = Collections.list(this)
|
||||||
|
|
||||||
fun <T> RequestBuilder<T>.withMaxSizePx(maxSizePx: Int = 1920, useCenterCrop: Boolean = false): RequestBuilder<T> {
|
fun <T> RequestBuilder<T>.withMaxSizePx(maxSizePx: Int = 1920): RequestBuilder<T> {
|
||||||
var builder = this
|
return this
|
||||||
.downsample(DownsampleStrategy.AT_MOST)
|
.downsample(DownsampleStrategy.AT_MOST)
|
||||||
.override(maxSizePx, maxSizePx)
|
.override(maxSizePx, maxSizePx)
|
||||||
builder = if (useCenterCrop) {
|
.centerInside()
|
||||||
builder.centerCrop()
|
|
||||||
} else {
|
|
||||||
builder.fitCenter()
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder
|
|
||||||
}
|
}
|
||||||
+10
-9
@@ -137,14 +137,7 @@ class HttpContentUriHandler(
|
|||||||
var size: Long? = null
|
var size: Long? = null
|
||||||
var lastModifiedMillis: Long? = null
|
var lastModifiedMillis: Long? = null
|
||||||
|
|
||||||
val projection = arrayOf(
|
resolver.query(uri, null, null, null, null)?.use { cursor ->
|
||||||
OpenableColumns.DISPLAY_NAME,
|
|
||||||
OpenableColumns.SIZE,
|
|
||||||
MediaStore.MediaColumns.DATE_MODIFIED,
|
|
||||||
MediaStore.MediaColumns.DATE_ADDED
|
|
||||||
)
|
|
||||||
|
|
||||||
resolver.query(uri, projection, null, null, null)?.use { cursor ->
|
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||||
if (nameIndex != -1 && !cursor.isNull(nameIndex)) {
|
if (nameIndex != -1 && !cursor.isNull(nameIndex)) {
|
||||||
@@ -177,6 +170,10 @@ class HttpContentUriHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (displayName == null) {
|
||||||
|
displayName = uri.lastPathSegment
|
||||||
|
}
|
||||||
|
|
||||||
if (size == null) {
|
if (size == null) {
|
||||||
try {
|
try {
|
||||||
resolver.openAssetFileDescriptor(uri, "r")?.use { afd ->
|
resolver.openAssetFileDescriptor(uri, "r")?.use { afd ->
|
||||||
@@ -188,7 +185,11 @@ class HttpContentUriHandler(
|
|||||||
} catch (_: Exception) { }
|
} catch (_: Exception) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
return ContentMeta(displayName = displayName, size = size, lastModifiedMillis = lastModifiedMillis)
|
return ContentMeta(
|
||||||
|
displayName = displayName,
|
||||||
|
size = size,
|
||||||
|
lastModifiedMillis = lastModifiedMillis
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseRange(header: String, totalLength: Long): LongRange? {
|
private fun parseRange(header: String, totalLength: Long): LongRange? {
|
||||||
|
|||||||
@@ -239,9 +239,9 @@ abstract class StateCasting {
|
|||||||
Logger.i(TAG, "Connect to device ${device.name}")
|
Logger.i(TAG, "Connect to device ${device.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun metadataFromVideo(video: IPlatformVideoDetails): Metadata {
|
fun metadataFromVideo(video: IPlatformVideoDetails, videoThumbnailOverrideUrl: String? = null): Metadata {
|
||||||
return Metadata(
|
return Metadata(
|
||||||
title = video.name, thumbnailUrl = video.thumbnails.getHQThumbnail()
|
title = video.name, thumbnailUrl = videoThumbnailOverrideUrl ?: video.thumbnails.getHQThumbnail()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,6 +479,16 @@ abstract class StateCasting {
|
|||||||
val id = UUID.randomUUID();
|
val id = UUID.randomUUID();
|
||||||
val videoPath = "/video-${id}"
|
val videoPath = "/video-${id}"
|
||||||
val videoUrl = url + videoPath;
|
val videoUrl = url + videoPath;
|
||||||
|
val thumbnailPath = "/thumbnail-${id}"
|
||||||
|
val thumbnailUrl = url + thumbnailPath;
|
||||||
|
val thumbnailContentUrl = video.thumbnails.getHQThumbnail()
|
||||||
|
|
||||||
|
if (thumbnailContentUrl != null) {
|
||||||
|
_castServer.addHandlerWithAllowAllOptions(
|
||||||
|
HttpContentUriHandler("GET", thumbnailPath, contentResolver, thumbnailContentUrl.toUri())
|
||||||
|
.withHeader("Access-Control-Allow-Origin", "*"), true
|
||||||
|
).withTag("cast");
|
||||||
|
}
|
||||||
|
|
||||||
_castServer.addHandlerWithAllowAllOptions(
|
_castServer.addHandlerWithAllowAllOptions(
|
||||||
HttpContentUriHandler("GET", videoPath, contentResolver, videoSource.contentUrl.toUri())
|
HttpContentUriHandler("GET", videoPath, contentResolver, videoSource.contentUrl.toUri())
|
||||||
@@ -486,7 +496,7 @@ abstract class StateCasting {
|
|||||||
).withTag("cast");
|
).withTag("cast");
|
||||||
|
|
||||||
Logger.i(TAG, "Casting local video (videoUrl: $videoUrl).");
|
Logger.i(TAG, "Casting local video (videoUrl: $videoUrl).");
|
||||||
ad.loadVideo("BUFFERED", videoSource.container, videoUrl, resumePosition, video.duration.toDouble(), speed, metadataFromVideo(video));
|
ad.loadVideo("BUFFERED", videoSource.container, videoUrl, resumePosition, video.duration.toDouble(), speed, metadataFromVideo(video, if (thumbnailContentUrl != null) thumbnailUrl else null));
|
||||||
|
|
||||||
return listOf(videoUrl);
|
return listOf(videoUrl);
|
||||||
}
|
}
|
||||||
@@ -498,6 +508,16 @@ abstract class StateCasting {
|
|||||||
val id = UUID.randomUUID();
|
val id = UUID.randomUUID();
|
||||||
val audioPath = "/audio-${id}"
|
val audioPath = "/audio-${id}"
|
||||||
val audioUrl = url + audioPath;
|
val audioUrl = url + audioPath;
|
||||||
|
val thumbnailPath = "/thumbnail-${id}"
|
||||||
|
val thumbnailUrl = url + thumbnailPath;
|
||||||
|
val thumbnailContentUrl = video.thumbnails.getHQThumbnail()
|
||||||
|
|
||||||
|
if (thumbnailContentUrl != null) {
|
||||||
|
_castServer.addHandlerWithAllowAllOptions(
|
||||||
|
HttpContentUriHandler("GET", thumbnailPath, contentResolver, thumbnailContentUrl.toUri())
|
||||||
|
.withHeader("Access-Control-Allow-Origin", "*"), true
|
||||||
|
).withTag("cast");
|
||||||
|
}
|
||||||
|
|
||||||
_castServer.addHandlerWithAllowAllOptions(
|
_castServer.addHandlerWithAllowAllOptions(
|
||||||
HttpContentUriHandler("GET", audioPath, contentResolver, audioSource.contentUrl.toUri())
|
HttpContentUriHandler("GET", audioPath, contentResolver, audioSource.contentUrl.toUri())
|
||||||
@@ -505,7 +525,7 @@ abstract class StateCasting {
|
|||||||
).withTag("cast");
|
).withTag("cast");
|
||||||
|
|
||||||
Logger.i(TAG, "Casting local audio (audioUrl: $audioUrl).");
|
Logger.i(TAG, "Casting local audio (audioUrl: $audioUrl).");
|
||||||
ad.loadVideo("BUFFERED", audioSource.container, audioUrl, resumePosition, video.duration.toDouble(), speed, metadataFromVideo(video));
|
ad.loadVideo("BUFFERED", audioSource.container, audioUrl, resumePosition, video.duration.toDouble(), speed, metadataFromVideo(video, if (thumbnailContentUrl != null) thumbnailUrl else null));
|
||||||
|
|
||||||
return listOf(audioUrl);
|
return listOf(audioUrl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -488,9 +488,10 @@ class StateLibrary {
|
|||||||
"";
|
"";
|
||||||
|
|
||||||
|
|
||||||
val albumContentUrl = if(albumId > 0)
|
val albumArtBase = Uri.parse("content://media/external/audio/albumart")
|
||||||
ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, albumId)?.toString()
|
val albumContentUrl = if (albumId > 0)
|
||||||
else null;
|
ContentUris.withAppendedId(albumArtBase, albumId).toString()
|
||||||
|
else null
|
||||||
|
|
||||||
val dateObj = if(date > 0)
|
val dateObj = if(date > 0)
|
||||||
OffsetDateTime.ofInstant(Instant.ofEpochSecond(date), ZoneOffset.UTC)
|
OffsetDateTime.ofInstant(Instant.ofEpochSecond(date), ZoneOffset.UTC)
|
||||||
@@ -625,11 +626,12 @@ class Artist {
|
|||||||
val numTracks = cursor.getInt(2);
|
val numTracks = cursor.getInt(2);
|
||||||
val numAlbums = cursor.getInt(3);
|
val numAlbums = cursor.getInt(3);
|
||||||
|
|
||||||
val idLong = id.toLongOrNull();
|
val idLong = id.toLongOrNull()
|
||||||
val uri = if(idLong != null) ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, idLong) else null;
|
val uri = if (idLong != null)
|
||||||
|
ContentUris.withAppendedId(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, idLong)
|
||||||
|
else null
|
||||||
|
|
||||||
return Artist(artist, numTracks, numAlbums, null, id, uri?.toString());
|
return Artist(artist, numTracks, numAlbums, null, id, uri?.toString()) }
|
||||||
}
|
|
||||||
|
|
||||||
fun getArtist(id: Long): Artist? {
|
fun getArtist(id: Long): Artist? {
|
||||||
val resolver = StateApp.instance.contextOrNull?.contentResolver;
|
val resolver = StateApp.instance.contextOrNull?.contentResolver;
|
||||||
@@ -733,9 +735,10 @@ class Album {
|
|||||||
val numTracks = cursor.getInt(2);
|
val numTracks = cursor.getInt(2);
|
||||||
val artist = cursor.getString(3);
|
val artist = cursor.getString(3);
|
||||||
|
|
||||||
val idLong = id.toLongOrNull();
|
val idLong = id.toLongOrNull()
|
||||||
val uri = if(idLong != null) ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, idLong) else null;
|
val albumArtBase = Uri.parse("content://media/external/audio/albumart")
|
||||||
return Album(album, numTracks, artist, id, uri?.toString());
|
val uri = if (idLong != null) ContentUris.withAppendedId(albumArtBase, idLong) else null
|
||||||
|
return Album(album, numTracks, artist, id, uri?.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAlbumTracks(albumId: Long): List<IPlatformVideo> {
|
fun getAlbumTracks(albumId: Long): List<IPlatformVideo> {
|
||||||
|
|||||||
Reference in New Issue
Block a user