Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't skip media segments shorter than 1 second #4064

Merged
merged 1 commit into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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<MediaSegmentDto> = runCatching {
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
Loading