Merge pull request #5300 from Bnyro/master

fix: improve download speeds and anonymity
This commit is contained in:
Bnyro 2023-12-06 14:40:10 +01:00 committed by GitHub
commit 593dd9ed4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 10 deletions

View File

@ -2,7 +2,6 @@ package com.github.libretube.api.obj
import com.github.libretube.db.obj.DownloadItem
import com.github.libretube.enums.FileType
import com.github.libretube.helpers.ProxyHelper
import kotlin.io.path.Path
import kotlinx.serialization.Serializable
@ -38,7 +37,7 @@ data class PipedStream(
videoId = videoId,
fileName = getQualityString(fileName),
path = Path(""),
url = url?.let { ProxyHelper.unwrapUrl(it) },
url = url,
format = format,
quality = quality,
language = audioTrackLocale,

View File

@ -60,15 +60,17 @@ object ProxyHelper {
* Convert a proxied Piped url to a YouTube url that's not proxied
*/
fun unwrapUrl(url: String, unwrap: Boolean = true) = url.toHttpUrlOrNull()
?.takeIf { unwrap }?.let {
?.takeIf { unwrap }
?.let {
val host = it.queryParameter("host")
// if there's no host parameter specified, there's no way to unwrap the URL
// and the proxied one must be used. That's the case if using LBRY.
if (host.isNullOrEmpty()) return@let url
it.newBuilder()
.host(host)
.removeAllQueryParameters("host")
.removeAllQueryParameters("ump")
// .removeAllQueryParameters("ump")
.removeAllQueryParameters("qhash")
.build()
.toString()

View File

@ -32,6 +32,7 @@ import com.github.libretube.extensions.toastFromMainThread
import com.github.libretube.helpers.DownloadHelper
import com.github.libretube.helpers.DownloadHelper.getNotificationId
import com.github.libretube.helpers.ImageHelper
import com.github.libretube.helpers.ProxyHelper
import com.github.libretube.obj.DownloadStatus
import com.github.libretube.parcelable.DownloadData
import com.github.libretube.receivers.NotificationReceiver
@ -162,9 +163,9 @@ class DownloadService : LifecycleService() {
downloadQueue[item.id] = true
val notificationBuilder = getNotificationBuilder(item)
setResumeNotification(notificationBuilder, item)
val path = item.path
var totalRead = path.fileSize()
val url = URL(item.url ?: return)
var totalRead = item.path.fileSize()
val url = URL(ProxyHelper.unwrapStreamUrl(item.url ?: return))
// only fetch the content length if it's not been returned by the API
if (item.downloadSize <= 0L) {
@ -179,7 +180,7 @@ class DownloadService : LifecycleService() {
val con = startConnection(item, url, totalRead, item.downloadSize) ?: return
@Suppress("NewApi") // The StandardOpenOption enum is desugared.
val sink = path.sink(StandardOpenOption.APPEND).buffer()
val sink = item.path.sink(StandardOpenOption.APPEND).buffer()
val sourceByte = con.inputStream.source()
var lastTime = System.currentTimeMillis() / 1000
@ -269,7 +270,9 @@ class DownloadService : LifecycleService() {
val limit = if (readLimit == null) {
""
} else {
min(readLimit, alreadyRead + BYTES_PER_REQUEST)
// generate a random byte distance to make it more difficult to fingerprint
val nextBytesToReadSize = (BYTES_PER_REQUEST_MIN..BYTES_PER_REQUEST_MAX).random()
min(readLimit, alreadyRead + nextBytesToReadSize)
}
con.setRequestProperty("Range", "bytes=$alreadyRead-$limit")
con.connectTimeout = DownloadHelper.DEFAULT_TIMEOUT
@ -536,7 +539,12 @@ class DownloadService : LifecycleService() {
"com.github.libretube.services.DownloadService.ACTION_SERVICE_STARTED"
const val ACTION_SERVICE_STOPPED =
"com.github.libretube.services.DownloadService.ACTION_SERVICE_STOPPED"
// any values that are not in that range are strictly rate limited by YT or are very slow due
// to the amount of requests that's being made
private const val BYTES_PER_REQUEST_MIN = 500_000L
private const val BYTES_PER_REQUEST_MAX = 3_000_000L
var IS_DOWNLOAD_RUNNING = false
private const val BYTES_PER_REQUEST = 10000000L
}
}