diff --git a/app/src/main/java/com/github/libretube/api/ExternalApi.kt b/app/src/main/java/com/github/libretube/api/ExternalApi.kt index f90de46a6..84a0b596c 100644 --- a/app/src/main/java/com/github/libretube/api/ExternalApi.kt +++ b/app/src/main/java/com/github/libretube/api/ExternalApi.kt @@ -1,6 +1,7 @@ package com.github.libretube.api import com.github.libretube.api.obj.DeArrowBody +import com.github.libretube.api.obj.DeArrowContent import com.github.libretube.api.obj.PipedConfig import com.github.libretube.api.obj.PipedInstance import com.github.libretube.api.obj.SegmentData @@ -64,4 +65,7 @@ interface ExternalApi { @Query("userID") userID: String, @Query("type") score: Int ) + + @GET("$SB_API_URL/api/branding/{videoId}") + suspend fun getDeArrowContent(@Path("videoId") videoId: String): Map } diff --git a/app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt b/app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt index 96445f9bb..bd6fea3bd 100644 --- a/app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt +++ b/app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt @@ -20,6 +20,8 @@ import com.github.libretube.api.obj.StreamItem.Companion.TYPE_PLAYLIST import com.github.libretube.api.obj.StreamItem.Companion.TYPE_STREAM import com.github.libretube.api.obj.Streams import com.github.libretube.api.obj.Subtitle +import com.github.libretube.extensions.parallelMap +import com.github.libretube.extensions.sha256Sum import com.github.libretube.extensions.toID import com.github.libretube.helpers.NewPipeExtractorInstance import com.github.libretube.helpers.PlayerHelper @@ -48,7 +50,6 @@ import org.schabi.newpipe.extractor.stream.AudioStream import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfoItem import org.schabi.newpipe.extractor.stream.VideoStream -import java.security.MessageDigest private fun VideoStream.toPipedStream() = PipedStream( @@ -320,27 +321,33 @@ class NewPipeMediaServiceRepository : MediaServiceRepository { ) } - @OptIn(ExperimentalStdlibApi::class) override suspend fun getSegments( - videoId: String, - category: List, - actionType: List? - ): SegmentData { + videoId: String, category: List, actionType: List? + ): SegmentData = RetrofitInstance.externalApi.getSegments( // use hashed video id for privacy // https://wiki.sponsor.ajay.app/w/API_Docs#GET_/api/skipSegments/:sha256HashPrefix - val hashedId = MessageDigest.getInstance("SHA-256") - .digest(videoId.toByteArray()) - .toHexString() - - return RetrofitInstance.externalApi.getSegments( - hashedId.substring(0..4), - category, - actionType - ).first { it.videoID == videoId } - } + videoId.sha256Sum().substring(0, 4), category, actionType + ).first { it.videoID == videoId } override suspend fun getDeArrowContent(videoIds: String): Map = - emptyMap() + videoIds.split(',').chunked(25).flatMap { + it.parallelMap { videoId -> + runCatching { + RetrofitInstance.externalApi.getDeArrowContent( + // use hashed video id for privacy + // https://wiki.sponsor.ajay.app/w/API_Docs/DeArrow#GET_/api/branding/:sha256HashPrefix + videoId.sha256Sum().substring(0, 4) + ) + }.getOrNull() + } + }.filterNotNull().reduce { acc, map -> acc + map }.mapValues { (videoId, value) -> + value.copy( + thumbnails = value.thumbnails.map { thumbnail -> + thumbnail.takeIf { it.original } ?: thumbnail.copy( + thumbnail = "${DEARROW_THUMBNAIL_URL}?videoID=$videoId&time=${thumbnail.timestamp}" + ) + }) + } override suspend fun getSearchResults(searchQuery: String, filter: String): SearchResult { val queryHandler = NewPipeExtractorInstance.extractor.searchQHFactory.fromQuery( @@ -494,4 +501,8 @@ class NewPipeMediaServiceRepository : MediaServiceRepository { comments = commentsInfo.items.map { it.toComment() } ) } + + companion object { + private const val DEARROW_THUMBNAIL_URL = "https://dearrow-thumb.ajay.app/api/v1/getThumbnail" + } } diff --git a/app/src/main/java/com/github/libretube/extensions/ShaSum.kt b/app/src/main/java/com/github/libretube/extensions/ShaSum.kt new file mode 100644 index 000000000..7750f2ed9 --- /dev/null +++ b/app/src/main/java/com/github/libretube/extensions/ShaSum.kt @@ -0,0 +1,11 @@ +package com.github.libretube.extensions + +import java.security.MessageDigest + +/** + * Calculates the SHA-256 hash of the String and returns the result in hexadecimal. + */ +@OptIn(ExperimentalStdlibApi::class) +fun String.sha256Sum(): String = MessageDigest.getInstance("SHA-256") + .digest(this.toByteArray()) + .toHexString()