fix: dearrow for playing video and watch history

This commit is contained in:
Bnyro 2024-05-06 13:42:21 +02:00
parent 3cef1505f6
commit ccaedfafbc
5 changed files with 59 additions and 29 deletions

View File

@ -125,6 +125,6 @@ object SubscriptionHelper {
subscriptions.joinToString(",") subscriptions.joinToString(",")
) )
} }
}.deArrow() }
} }
} }

View File

@ -14,7 +14,7 @@ import kotlinx.serialization.Serializable
@Serializable @Serializable
data class Streams( data class Streams(
val title: String, var title: String,
val description: String, val description: String,
@Serializable(SafeInstantSerializer::class) @Serializable(SafeInstantSerializer::class)
@ -24,7 +24,7 @@ data class Streams(
val uploader: String, val uploader: String,
val uploaderUrl: String, val uploaderUrl: String,
val uploaderAvatar: String? = null, val uploaderAvatar: String? = null,
val thumbnailUrl: String, var thumbnailUrl: String,
val category: String, val category: String,
val license: String = "YouTube licence", val license: String = "YouTube licence",
val visibility: String = "public", val visibility: String = "public",

View File

@ -85,7 +85,7 @@ class HomeViewModel : ViewModel() {
private suspend fun loadFeed(subscriptionsViewModel: SubscriptionsViewModel) { private suspend fun loadFeed(subscriptionsViewModel: SubscriptionsViewModel) {
runSafely( runSafely(
onSuccess = { videos -> feed.updateIfChanged(videos) }, onSuccess = { videos -> feed.updateIfChanged(videos) },
ioBlock = { tryLoadFeed(subscriptionsViewModel) } ioBlock = { tryLoadFeed(subscriptionsViewModel).deArrow().take(20) }
) )
} }

View File

@ -60,9 +60,7 @@ class PlayerViewModel : ViewModel() {
if (isOrientationChangeInProgress && streamsInfo != null) return@withContext streamsInfo to null if (isOrientationChangeInProgress && streamsInfo != null) return@withContext streamsInfo to null
streamsInfo = try { streamsInfo = try {
RetrofitInstance.api.getStreams(videoId).apply { RetrofitInstance.api.getStreams(videoId).deArrow(videoId)
relatedStreams = relatedStreams.deArrow()
}
} catch (e: IOException) { } catch (e: IOException) {
return@withContext null to context.getString(R.string.unknown_error) return@withContext null to context.getString(R.string.unknown_error)
} catch (e: HttpException) { } catch (e: HttpException) {

View File

@ -5,6 +5,7 @@ import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.ContentItem import com.github.libretube.api.obj.ContentItem
import com.github.libretube.api.obj.DeArrowContent import com.github.libretube.api.obj.DeArrowContent
import com.github.libretube.api.obj.StreamItem import com.github.libretube.api.obj.StreamItem
import com.github.libretube.api.obj.Streams
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.extensions.toID import com.github.libretube.extensions.toID
import com.github.libretube.helpers.PreferenceHelper import com.github.libretube.helpers.PreferenceHelper
@ -19,26 +20,58 @@ object DeArrowUtil {
return newTitle to newThumbnail return newTitle to newThumbnail
} }
private suspend fun fetchDeArrowContent(videoIds: List<String>): Map<String, DeArrowContent>? {
val videoIdsString = videoIds.mapTo(TreeSet()) { it }.joinToString(",")
return try {
RetrofitInstance.api.getDeArrowContent(videoIdsString)
} catch (e: Exception) {
Log.e(this::class.java.name, e.toString())
null
}
}
/**
* Apply the new titles and thumbnails generated by DeArrow to the streams item
*/
suspend fun deArrowStreams(streams: Streams, vidId: String): Streams {
if (!PreferenceHelper.getBoolean(PreferenceKeys.DEARROW, false)) return streams
val videoIds = listOf(vidId) + streams.relatedStreams.map { it.url!!.toID() }
val response = fetchDeArrowContent(videoIds) ?: return streams
for ((videoId, data) in response.entries) {
val (newTitle, newThumbnail) = extractTitleAndThumbnail(data)
if (videoId == vidId) {
if (newTitle != null) streams.title = newTitle
if (newThumbnail != null) streams.thumbnailUrl = newThumbnail
} else {
val streamItem = streams.relatedStreams
.firstOrNull { it.url?.toID() == videoId } ?: continue
if (newTitle != null) streamItem.title = newTitle
if (newThumbnail != null) streamItem.thumbnail = newThumbnail
}
}
return streams
}
/** /**
* Apply the new titles and thumbnails generated by DeArrow to the stream items * Apply the new titles and thumbnails generated by DeArrow to the stream items
*/ */
suspend fun deArrowStreamItems(streamItems: List<StreamItem>): List<StreamItem> { suspend fun deArrowStreamItems(streamItems: List<StreamItem>): List<StreamItem> {
if (!PreferenceHelper.getBoolean(PreferenceKeys.DEARROW, false)) return streamItems if (!PreferenceHelper.getBoolean(PreferenceKeys.DEARROW, false)) return streamItems
val videoIds = streamItems.mapNotNullTo(TreeSet()) { it.url?.toID() } val response = fetchDeArrowContent(streamItems.map{ it.url!!.toID() }) ?: return streamItems
.joinToString(",")
val response = try {
RetrofitInstance.api.getDeArrowContent(videoIds)
} catch (e: Exception) {
Log.e(this::class.java.name, e.toString())
return streamItems
}
for ((videoId, data) in response.entries) { for ((videoId, data) in response.entries) {
val (newTitle, newThumbnail) = extractTitleAndThumbnail(data) val (newTitle, newThumbnail) = extractTitleAndThumbnail(data)
val streamItem = streamItems.firstOrNull { it.url?.toID() == videoId } val streamItem = streamItems.firstOrNull { it.url?.toID() == videoId } ?: continue
newTitle?.let { streamItem?.title = newTitle }
newThumbnail?.let { streamItem?.thumbnail = newThumbnail } if (newTitle != null) streamItem.title = newTitle
if (newThumbnail != null) streamItem.thumbnail = newThumbnail
} }
return streamItems return streamItems
} }
@ -50,22 +83,18 @@ object DeArrowUtil {
if (!PreferenceHelper.getBoolean(PreferenceKeys.DEARROW, false)) return contentItems if (!PreferenceHelper.getBoolean(PreferenceKeys.DEARROW, false)) return contentItems
val videoIds = contentItems.filter { it.type == "stream" } val videoIds = contentItems.filter { it.type == "stream" }
.mapTo(TreeSet()) { it.url.toID() } .map { it.url.toID() }
.joinToString(",")
if (videoIds.isEmpty()) return contentItems if (videoIds.isEmpty()) return contentItems
val response = try { val response = fetchDeArrowContent(videoIds) ?: return contentItems
RetrofitInstance.api.getDeArrowContent(videoIds)
} catch (e: Exception) {
Log.e(this::class.java.name, e.toString())
return contentItems
}
for ((videoId, data) in response.entries) { for ((videoId, data) in response.entries) {
val (newTitle, newThumbnail) = extractTitleAndThumbnail(data) val (newTitle, newThumbnail) = extractTitleAndThumbnail(data)
val contentItem = contentItems.firstOrNull { it.url.toID() == videoId } val contentItem = contentItems.firstOrNull { it.url.toID() == videoId } ?: continue
newTitle?.let { contentItem?.title = newTitle }
newThumbnail?.let { contentItem?.thumbnail = newThumbnail } if (newTitle != null) { contentItem.title = newTitle }
if (newThumbnail != null) { contentItem.thumbnail = newThumbnail }
} }
return contentItems return contentItems
} }
@ -84,3 +113,6 @@ suspend fun List<StreamItem>.deArrow() = DeArrowUtil.deArrowStreamItems(this)
*/ */
@JvmName("deArrowContentItems") @JvmName("deArrowContentItems")
suspend fun List<ContentItem>.deArrow() = DeArrowUtil.deArrowContentItems(this) suspend fun List<ContentItem>.deArrow() = DeArrowUtil.deArrowContentItems(this)
@JvmName("deArrowStreams")
suspend fun Streams.deArrow(videoId: String) = DeArrowUtil.deArrowStreams(this, videoId)