refactor: re-use StreamInfoItem#toStreamItem from StreamsExtractor

This commit is contained in:
Bnyro 2025-01-11 12:08:29 +01:00
parent 48f230e9e0
commit 92dba354b6
2 changed files with 28 additions and 36 deletions

View File

@ -36,6 +36,26 @@ fun VideoStream.toPipedStream(): PipedStream = PipedStream(
contentLength = itagItem?.contentLength ?: 0L contentLength = itagItem?.contentLength ?: 0L
) )
fun StreamInfoItem.toStreamItem(
uploaderAvatarUrl: String? = null
): StreamItem = StreamItem(
type = StreamItem.TYPE_STREAM,
url = url.replace(YOUTUBE_FRONTEND_URL, ""),
title = name,
uploaded = uploadDate?.offsetDateTime()?.toEpochSecond()?.times(1000) ?: 0,
uploadedDate = textualUploadDate ?: uploadDate?.offsetDateTime()?.toLocalDateTime()?.toLocalDate()
?.toString(),
uploaderName = uploaderName,
uploaderUrl = uploaderUrl.replace(YOUTUBE_FRONTEND_URL, ""),
uploaderAvatar = uploaderAvatarUrl ?: uploaderAvatars.maxByOrNull { it.height }?.url,
thumbnail = thumbnails.maxByOrNull { it.height }?.url,
duration = duration,
views = viewCount,
uploaderVerified = isUploaderVerified,
shortDescription = shortDescription,
isShort = isShortFormContent
)
object StreamsExtractor { object StreamsExtractor {
suspend fun extractStreams(videoId: String): Streams { suspend fun extractStreams(videoId: String): Streams {
if (!PlayerHelper.disablePipedProxy || !PlayerHelper.localStreamExtraction) { if (!PlayerHelper.disablePipedProxy || !PlayerHelper.localStreamExtraction) {
@ -74,24 +94,7 @@ object StreamsExtractor {
uploadTimestamp = resp.uploadDate.offsetDateTime().toInstant().toKotlinInstant(), uploadTimestamp = resp.uploadDate.offsetDateTime().toInstant().toKotlinInstant(),
uploaded = resp.uploadDate.offsetDateTime().toEpochSecond() * 1000, uploaded = resp.uploadDate.offsetDateTime().toEpochSecond() * 1000,
thumbnailUrl = resp.thumbnails.maxBy { it.height }.url, thumbnailUrl = resp.thumbnails.maxBy { it.height }.url,
relatedStreams = resp.relatedItems.filterIsInstance<StreamInfoItem>().map { relatedStreams = resp.relatedItems.filterIsInstance<StreamInfoItem>().map(StreamInfoItem::toStreamItem),
StreamItem(
it.url.replace(YOUTUBE_FRONTEND_URL, ""),
StreamItem.TYPE_STREAM,
it.name,
it.thumbnails.maxBy { image -> image.height }.url,
it.uploaderName,
it.uploaderUrl.replace(YOUTUBE_FRONTEND_URL, ""),
it.uploaderAvatars.maxBy { image -> image.height }.url,
it.textualUploadDate,
it.duration,
it.viewCount,
it.isUploaderVerified,
it.uploadDate?.offsetDateTime()?.toEpochSecond()?.times(1000) ?: 0L,
it.shortDescription,
it.isShortFormContent,
)
},
chapters = resp.streamSegments.map { chapters = resp.streamSegments.map {
ChapterSegment( ChapterSegment(
title = it.title, title = it.title,

View File

@ -3,6 +3,7 @@ package com.github.libretube.repo
import android.util.Log import android.util.Log
import com.github.libretube.api.SubscriptionHelper import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.api.obj.StreamItem import com.github.libretube.api.obj.StreamItem
import com.github.libretube.api.toStreamItem
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.db.DatabaseHolder import com.github.libretube.db.DatabaseHolder
import com.github.libretube.db.obj.SubscriptionsFeedItem import com.github.libretube.db.obj.SubscriptionsFeedItem
@ -65,7 +66,10 @@ class LocalFeedRepository : FeedRepository {
} }
} }
private suspend fun getRelatedStreams(channelId: String, minimumDateMillis: Long): List<StreamItem> { private suspend fun getRelatedStreams(
channelId: String,
minimumDateMillis: Long
): List<StreamItem> {
val channelUrl = "$YOUTUBE_FRONTEND_URL/channel/${channelId}" val channelUrl = "$YOUTUBE_FRONTEND_URL/channel/${channelId}"
val feedInfo = FeedInfo.getInfo(channelUrl) val feedInfo = FeedInfo.getInfo(channelUrl)
@ -88,23 +92,8 @@ class LocalFeedRepository : FeedRepository {
}.flatten().filterIsInstance<StreamInfoItem>() }.flatten().filterIsInstance<StreamInfoItem>()
return related.map { item -> return related.map { item ->
StreamItem( // avatar is not always included in these info items, thus must be taken from channel info response
type = StreamItem.TYPE_STREAM, item.toStreamItem(channelInfo.avatars.maxByOrNull { it.height }?.url)
url = item.url.replace(YOUTUBE_FRONTEND_URL, ""),
title = item.name,
uploaded = item.uploadDate?.offsetDateTime()?.toEpochSecond()?.times(1000) ?: 0,
uploadedDate = item.uploadDate?.offsetDateTime()?.toLocalDateTime()?.toLocalDate()
?.toString(),
uploaderName = item.uploaderName,
uploaderUrl = item.uploaderUrl.replace(YOUTUBE_FRONTEND_URL, ""),
uploaderAvatar = channelInfo.avatars.maxByOrNull { it.height }?.url,
thumbnail = item.thumbnails.maxByOrNull { it.height }?.url,
duration = item.duration,
views = item.viewCount,
uploaderVerified = item.isUploaderVerified,
shortDescription = item.shortDescription,
isShort = item.isShortFormContent
)
}.filter { it.uploaded > minimumDateMillis } }.filter { it.uploaded > minimumDateMillis }
} }