Skip to content

Commit e91404b

Browse files
FineFindusBnyro
authored andcommitted
feat(MediaService/Local): implement DeArrow support
1 parent 31613c8 commit e91404b

3 files changed

Lines changed: 43 additions & 17 deletions

File tree

app/src/main/java/com/github/libretube/api/ExternalApi.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.libretube.api
22

33
import com.github.libretube.api.obj.DeArrowBody
4+
import com.github.libretube.api.obj.DeArrowContent
45
import com.github.libretube.api.obj.PipedConfig
56
import com.github.libretube.api.obj.PipedInstance
67
import com.github.libretube.api.obj.SegmentData
@@ -64,4 +65,7 @@ interface ExternalApi {
6465
@Query("userID") userID: String,
6566
@Query("type") score: Int
6667
)
68+
69+
@GET("$SB_API_URL/api/branding/{videoId}")
70+
suspend fun getDeArrowContent(@Path("videoId") videoId: String): Map<String, DeArrowContent>
6771
}

app/src/main/java/com/github/libretube/api/NewPipeMediaServiceRepository.kt

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import com.github.libretube.api.obj.StreamItem.Companion.TYPE_PLAYLIST
2020
import com.github.libretube.api.obj.StreamItem.Companion.TYPE_STREAM
2121
import com.github.libretube.api.obj.Streams
2222
import com.github.libretube.api.obj.Subtitle
23+
import com.github.libretube.extensions.parallelMap
24+
import com.github.libretube.extensions.sha256Sum
2325
import com.github.libretube.extensions.toID
2426
import com.github.libretube.helpers.NewPipeExtractorInstance
2527
import com.github.libretube.helpers.PlayerHelper
@@ -48,7 +50,6 @@ import org.schabi.newpipe.extractor.stream.AudioStream
4850
import org.schabi.newpipe.extractor.stream.StreamInfo
4951
import org.schabi.newpipe.extractor.stream.StreamInfoItem
5052
import org.schabi.newpipe.extractor.stream.VideoStream
51-
import java.security.MessageDigest
5253

5354

5455
private fun VideoStream.toPipedStream() = PipedStream(
@@ -320,27 +321,33 @@ class NewPipeMediaServiceRepository : MediaServiceRepository {
320321
)
321322
}
322323

323-
@OptIn(ExperimentalStdlibApi::class)
324324
override suspend fun getSegments(
325-
videoId: String,
326-
category: List<String>,
327-
actionType: List<String>?
328-
): SegmentData {
325+
videoId: String, category: List<String>, actionType: List<String>?
326+
): SegmentData = RetrofitInstance.externalApi.getSegments(
329327
// use hashed video id for privacy
330328
// https://wiki.sponsor.ajay.app/w/API_Docs#GET_/api/skipSegments/:sha256HashPrefix
331-
val hashedId = MessageDigest.getInstance("SHA-256")
332-
.digest(videoId.toByteArray())
333-
.toHexString()
334-
335-
return RetrofitInstance.externalApi.getSegments(
336-
hashedId.substring(0..4),
337-
category,
338-
actionType
339-
).first { it.videoID == videoId }
340-
}
329+
videoId.sha256Sum().substring(0, 4), category, actionType
330+
).first { it.videoID == videoId }
341331

342332
override suspend fun getDeArrowContent(videoIds: String): Map<String, DeArrowContent> =
343-
emptyMap()
333+
videoIds.split(',').chunked(25).flatMap {
334+
it.parallelMap { videoId ->
335+
runCatching {
336+
RetrofitInstance.externalApi.getDeArrowContent(
337+
// use hashed video id for privacy
338+
// https://wiki.sponsor.ajay.app/w/API_Docs/DeArrow#GET_/api/branding/:sha256HashPrefix
339+
videoId.sha256Sum().substring(0, 4)
340+
)
341+
}.getOrNull()
342+
}
343+
}.filterNotNull().reduce { acc, map -> acc + map }.mapValues { (videoId, value) ->
344+
value.copy(
345+
thumbnails = value.thumbnails.map { thumbnail ->
346+
thumbnail.takeIf { it.original } ?: thumbnail.copy(
347+
thumbnail = "${DEARROW_THUMBNAIL_URL}?videoID=$videoId&time=${thumbnail.timestamp}"
348+
)
349+
})
350+
}
344351

345352
override suspend fun getSearchResults(searchQuery: String, filter: String): SearchResult {
346353
val queryHandler = NewPipeExtractorInstance.extractor.searchQHFactory.fromQuery(
@@ -494,4 +501,8 @@ class NewPipeMediaServiceRepository : MediaServiceRepository {
494501
comments = commentsInfo.items.map { it.toComment() }
495502
)
496503
}
504+
505+
companion object {
506+
private const val DEARROW_THUMBNAIL_URL = "https://dearrow-thumb.ajay.app/api/v1/getThumbnail"
507+
}
497508
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.github.libretube.extensions
2+
3+
import java.security.MessageDigest
4+
5+
/**
6+
* Calculates the SHA-256 hash of the String and returns the result in hexadecimal.
7+
*/
8+
@OptIn(ExperimentalStdlibApi::class)
9+
fun String.sha256Sum(): String = MessageDigest.getInstance("SHA-256")
10+
.digest(this.toByteArray())
11+
.toHexString()

0 commit comments

Comments
 (0)