mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-06 10:09:39 +00:00
fix(downloads): passing resume position
This commit is contained in:
parent
7437f54ab8
commit
7c2cad51b9
6 changed files with 33 additions and 5 deletions
|
|
@ -1,20 +1,24 @@
|
|||
package com.nuvio.app.features.player
|
||||
|
||||
import android.content.Context
|
||||
import androidx.media3.datasource.DataSource
|
||||
import androidx.media3.datasource.DefaultDataSource
|
||||
import androidx.media3.datasource.DefaultHttpDataSource
|
||||
import com.nuvio.app.features.trailer.YoutubeChunkedDataSourceFactory
|
||||
|
||||
internal object PlatformPlaybackDataSourceFactory {
|
||||
fun create(
|
||||
context: Context,
|
||||
defaultRequestHeaders: Map<String, String>,
|
||||
defaultResponseHeaders: Map<String, String>,
|
||||
useYoutubeChunkedPlayback: Boolean,
|
||||
): DataSource.Factory {
|
||||
val baseFactory: DataSource.Factory = if (useYoutubeChunkedPlayback) {
|
||||
val networkFactory: DataSource.Factory = if (useYoutubeChunkedPlayback) {
|
||||
YoutubeChunkedDataSourceFactory(defaultRequestHeaders = defaultRequestHeaders)
|
||||
} else {
|
||||
DefaultHttpDataSource.Factory().setDefaultRequestProperties(defaultRequestHeaders)
|
||||
}
|
||||
val baseFactory: DataSource.Factory = DefaultDataSource.Factory(context, networkFactory)
|
||||
return if (defaultResponseHeaders.isEmpty()) {
|
||||
baseFactory
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,8 @@ internal actual object DownloadsPlatformDownloader {
|
|||
tempFile.delete()
|
||||
}
|
||||
|
||||
onSuccess(destination.toURI().toString(), totalBytes)
|
||||
val finalSize = destination.length()
|
||||
onSuccess(destination.toURI().toString(), totalBytes ?: finalSize)
|
||||
}
|
||||
} catch (_: CancellationException) {
|
||||
tempFile.delete()
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ actual fun PlatformPlayerSurface(
|
|||
.setTsExtractorTimestampSearchBytes(1500 * TsExtractor.TS_PACKET_SIZE)
|
||||
|
||||
val dataSourceFactory = PlatformPlaybackDataSourceFactory.create(
|
||||
context = context,
|
||||
defaultRequestHeaders = sanitizedSourceHeaders,
|
||||
defaultResponseHeaders = sanitizedSourceResponseHeaders,
|
||||
useYoutubeChunkedPlayback = useYoutubeChunkedPlayback,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
package com.nuvio.app.features.player
|
||||
|
||||
import android.content.Context
|
||||
import androidx.media3.datasource.DataSource
|
||||
import androidx.media3.datasource.DefaultDataSource
|
||||
import androidx.media3.datasource.DefaultHttpDataSource
|
||||
|
||||
internal object PlatformPlaybackDataSourceFactory {
|
||||
fun create(
|
||||
context: Context,
|
||||
defaultRequestHeaders: Map<String, String>,
|
||||
defaultResponseHeaders: Map<String, String>,
|
||||
useYoutubeChunkedPlayback: Boolean,
|
||||
): DataSource.Factory {
|
||||
val baseFactory = DefaultHttpDataSource.Factory()
|
||||
val httpFactory = DefaultHttpDataSource.Factory()
|
||||
.setDefaultRequestProperties(defaultRequestHeaders)
|
||||
val baseFactory: DataSource.Factory = DefaultDataSource.Factory(context, httpFactory)
|
||||
return if (defaultResponseHeaders.isEmpty()) {
|
||||
baseFactory
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1250,6 +1250,11 @@ private fun MainAppContent(
|
|||
onBack = onBack,
|
||||
onOpenDownload = { item ->
|
||||
val sourceUrl = item.localFileUri ?: return@DownloadsScreen
|
||||
val resumeEntry = item.videoId
|
||||
.takeIf { it.isNotBlank() }
|
||||
?.let(WatchProgressRepository::progressForVideo)
|
||||
?.takeIf { it.isResumable }
|
||||
|
||||
val launchId = PlayerLaunchStore.put(
|
||||
PlayerLaunch(
|
||||
title = item.title,
|
||||
|
|
@ -1271,7 +1276,8 @@ private fun MainAppContent(
|
|||
videoId = item.videoId,
|
||||
parentMetaId = item.parentMetaId,
|
||||
parentMetaType = item.parentMetaType,
|
||||
initialPositionMs = 0L,
|
||||
initialPositionMs = resumeEntry?.lastPositionMs?.takeIf { it > 0L } ?: 0L,
|
||||
initialProgressFraction = resumeEntry?.progressFraction?.takeIf { it > 0f },
|
||||
),
|
||||
)
|
||||
navController.navigate(PlayerRoute(launchId = launchId))
|
||||
|
|
|
|||
|
|
@ -88,7 +88,8 @@ internal actual object DownloadsPlatformDownloader {
|
|||
}
|
||||
|
||||
val localFileUri = NSURL.fileURLWithPath(destinationPath).absoluteString ?: "file://$destinationPath"
|
||||
onSuccess(localFileUri, totalBytes)
|
||||
val finalSize = fileSizeOrNull(destinationPath)
|
||||
onSuccess(localFileUri, totalBytes ?: finalSize)
|
||||
} catch (_: CancellationException) {
|
||||
removePathIfExists(tempPath)
|
||||
} catch (error: Throwable) {
|
||||
|
|
@ -174,6 +175,17 @@ private suspend fun writeChannelToFile(
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
private fun fileSizeOrNull(path: String): Long? {
|
||||
val attrs = NSFileManager.defaultManager.attributesOfItemAtPath(path, error = null)
|
||||
val value = attrs?.get("NSFileSize")
|
||||
return when (value) {
|
||||
is Long -> value
|
||||
is Number -> value.toLong()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.toLocalPath(): String? {
|
||||
if (startsWith("file://")) {
|
||||
return removePrefix("file://")
|
||||
|
|
|
|||
Loading…
Reference in a new issue