diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerHelper.kt b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerHelper.kt index e54617ff27..bd59304280 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerHelper.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackControllerHelper.kt @@ -7,11 +7,12 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.jellyfin.androidtv.ui.playback.segment.MediaSegmentAction import org.jellyfin.androidtv.ui.playback.segment.MediaSegmentRepository +import org.jellyfin.androidtv.util.sdk.end +import org.jellyfin.androidtv.util.sdk.start import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.extensions.liveTvApi import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.MediaSegmentDto -import org.jellyfin.sdk.model.extensions.ticks import org.koin.android.ext.android.inject import java.util.UUID @@ -62,11 +63,11 @@ private fun PlaybackController.addSkipAction(mediaSegment: MediaSegmentDto) { // the seek function in the PlaybackController checks this and optionally starts a transcode // at the requested position fragment.lifecycleScope.launch(Dispatchers.Main) { - seek(mediaSegment.endTicks.ticks.inWholeMilliseconds) + seek(mediaSegment.end.inWholeMilliseconds) } } // Segments at position 0 will never be hit by ExoPlayer so we need to add a minimum value - .setPosition(mediaSegment.startTicks.ticks.inWholeMilliseconds.coerceAtLeast(1)) + .setPosition(mediaSegment.start.inWholeMilliseconds.coerceAtLeast(1)) .setPayload(mediaSegment) .setDeleteAfterDelivery(false) .send() diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/segment/MediaSegmentRepository.kt b/app/src/main/java/org/jellyfin/androidtv/ui/playback/segment/MediaSegmentRepository.kt index fa98a12fc7..5115f49113 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/segment/MediaSegmentRepository.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/segment/MediaSegmentRepository.kt @@ -1,11 +1,13 @@ package org.jellyfin.androidtv.ui.playback.segment import org.jellyfin.androidtv.preference.UserPreferences +import org.jellyfin.androidtv.util.sdk.duration import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.extensions.mediaSegmentsApi import org.jellyfin.sdk.model.api.BaseItemDto import org.jellyfin.sdk.model.api.MediaSegmentDto import org.jellyfin.sdk.model.api.MediaSegmentType +import kotlin.time.Duration.Companion.seconds interface MediaSegmentRepository { companion object { @@ -19,6 +21,11 @@ interface MediaSegmentRepository { MediaSegmentType.RECAP, MediaSegmentType.COMMERCIAL, ) + + /** + * The minimum duration for a media segment to allow the [MediaSegmentAction.SKIP] action. + */ + val SkipMinDuration = 1.seconds } fun getDefaultSegmentTypeAction(type: MediaSegmentType): MediaSegmentAction @@ -74,7 +81,10 @@ class MediaSegmentRepositoryImpl( } override fun getMediaSegmentAction(segment: MediaSegmentDto): MediaSegmentAction { - return getDefaultSegmentTypeAction(segment.type) + val action = getDefaultSegmentTypeAction(segment.type) + // Skip the skip action if timespan is too short + if (action == MediaSegmentAction.SKIP && segment.duration < MediaSegmentRepository.SkipMinDuration) return MediaSegmentAction.NOTHING + return action } override suspend fun getSegmentsForItem(item: BaseItemDto): List = runCatching { diff --git a/app/src/main/java/org/jellyfin/androidtv/util/sdk/MediaSegmentExtensions.kt b/app/src/main/java/org/jellyfin/androidtv/util/sdk/MediaSegmentExtensions.kt new file mode 100644 index 0000000000..7f22213e80 --- /dev/null +++ b/app/src/main/java/org/jellyfin/androidtv/util/sdk/MediaSegmentExtensions.kt @@ -0,0 +1,10 @@ +package org.jellyfin.androidtv.util.sdk + +import org.jellyfin.sdk.model.api.MediaSegmentDto +import org.jellyfin.sdk.model.extensions.ticks +import kotlin.time.Duration + +val MediaSegmentDto.start get() = startTicks.ticks +val MediaSegmentDto.end get() = endTicks.ticks + +val MediaSegmentDto.duration get() = (endTicks - startTicks).ticks.coerceAtLeast(Duration.ZERO)