Merge pull request 'Reset subtitle delay when the new track has none saved' (#73) from fm/sub-offset-reset into fm/tv-round2
This commit is contained in:
commit
709ca29170
2 changed files with 80 additions and 1 deletions
|
|
@ -1669,6 +1669,9 @@ class PlaybackViewModel
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the enabled subtitle track's saved delay, or zero if no delay is saved.
|
||||
*/
|
||||
suspend fun loadSubtitleDelay() {
|
||||
state.value.currentPlayback?.let {
|
||||
if (it.subtitleIndexEnabled) {
|
||||
|
|
@ -1681,7 +1684,9 @@ class PlaybackViewModel
|
|||
it.subtitleIndex,
|
||||
it.item.id,
|
||||
)
|
||||
updateCurrentPlayback { it?.copy(subtitleDelay = result.delayMs.milliseconds) }
|
||||
}
|
||||
updateCurrentPlayback {
|
||||
it?.copy(subtitleDelay = result?.delayMs?.milliseconds ?: Duration.ZERO)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,16 +3,19 @@ package com.github.damontecres.wholphin.ui.playback
|
|||
import android.content.Context
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.TrackSelectionParameters
|
||||
import com.github.damontecres.wholphin.data.ItemPlaybackDao
|
||||
import com.github.damontecres.wholphin.data.ItemPlaybackRepository
|
||||
import com.github.damontecres.wholphin.data.ServerRepository
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
import com.github.damontecres.wholphin.data.model.ItemTrackModification
|
||||
import com.github.damontecres.wholphin.data.model.JellyfinServer
|
||||
import com.github.damontecres.wholphin.data.model.JellyfinUser
|
||||
import com.github.damontecres.wholphin.data.model.Playlist
|
||||
import com.github.damontecres.wholphin.data.model.PlaylistItem
|
||||
import com.github.damontecres.wholphin.data.model.SeriesTrackChoiceType
|
||||
import com.github.damontecres.wholphin.data.model.ServerUserConfig
|
||||
import com.github.damontecres.wholphin.data.model.TrackIndex
|
||||
import com.github.damontecres.wholphin.preferences.AppPreferences
|
||||
import com.github.damontecres.wholphin.preferences.PlaybackPreferences
|
||||
import com.github.damontecres.wholphin.preferences.ShowNextUpWhen
|
||||
|
|
@ -82,6 +85,7 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
|
|
@ -292,6 +296,76 @@ class PlaybackViewModelTests {
|
|||
return viewModel
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Subtitle track switches load saved delays or zero and ignore disabled subtitles`() =
|
||||
runTest(testDispatcher) {
|
||||
setupPreferences { cinemaMode = false }
|
||||
val tracks =
|
||||
TestTracks
|
||||
.Builder()
|
||||
.addVideo()
|
||||
.addAudio()
|
||||
.addSubtitle(2)
|
||||
val source = tracks.buildMediaSourceInfo()
|
||||
val subtitles = source.mediaStreams!!.filter { it.type == MediaStreamType.SUBTITLE }
|
||||
val trackA = subtitles[0].index
|
||||
val trackB = subtitles[1].index
|
||||
coEvery { mockUserLibraryApi.getItem(movie.id) } returns successResponse(movie)
|
||||
coEvery { mockMediaInfoApi.getPostedPlaybackInfo(any(), any()) } returns
|
||||
successResponse(
|
||||
PlaybackInfoResponse(
|
||||
mediaSources = listOf(source),
|
||||
playSessionId = playSessionId,
|
||||
),
|
||||
)
|
||||
coEvery { mockStreamChoiceService.chooseSource(any(), any()) } returns source
|
||||
coEvery {
|
||||
mockStreamChoiceService.chooseAudioStream(any(), any(), any(), any(), any())
|
||||
} returns
|
||||
StreamChoiceResult(
|
||||
source.mediaStreams!!.first { it.type == MediaStreamType.AUDIO },
|
||||
StreamChoiceReason.Unknown,
|
||||
)
|
||||
coEvery {
|
||||
mockStreamChoiceService.chooseSubtitleStream(any(), any(), any(), any(), any(), any())
|
||||
} returns StreamChoiceResult(subtitles[0], StreamChoiceReason.Unknown)
|
||||
coEvery {
|
||||
mockStreamChoiceService.resolveSubtitleIndex(any(), any(), any(), any(), any())
|
||||
} answers { arg<Int>(3) }
|
||||
every { mockPlayer.currentTracks } returns tracks.buildForExoPlayer().toTracks()
|
||||
every { mockPlayer.trackSelectionParameters } returns TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT
|
||||
coEvery { mockItemPlaybackRepository.getTrackModifications(movie.id, trackA) } returns
|
||||
ItemTrackModification(user.rowId, movie.id, trackA, 2000L)
|
||||
|
||||
val cases =
|
||||
listOf(
|
||||
Triple(trackB, null, Duration.ZERO),
|
||||
Triple(trackB, -750L, (-750).milliseconds),
|
||||
Triple(TrackIndex.DISABLED, null, 2.seconds),
|
||||
)
|
||||
cases.forEach { (targetIndex, savedDelayMs, expectedDelay) ->
|
||||
coEvery { mockItemPlaybackRepository.getTrackModifications(movie.id, trackB) } returns
|
||||
savedDelayMs?.let {
|
||||
ItemTrackModification(user.rowId, movie.id, trackB, it)
|
||||
}
|
||||
val viewModel = createViewModel(Destination.Playback(movie.id, 0L))
|
||||
val initialPlayback = viewModel.state.value.currentPlayback
|
||||
Assert.assertEquals(trackA, initialPlayback?.subtitleIndex)
|
||||
Assert.assertEquals(2.seconds, initialPlayback?.subtitleDelay)
|
||||
|
||||
viewModel.changeSubtitleStream(targetIndex).join()
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
val playback = viewModel.state.value.currentPlayback
|
||||
Assert.assertEquals(targetIndex, playback?.subtitleIndex)
|
||||
Assert.assertEquals(expectedDelay, playback?.subtitleDelay)
|
||||
}
|
||||
coVerify(exactly = 0) {
|
||||
mockItemPlaybackRepository.getTrackModifications(movie.id, TrackIndex.DISABLED)
|
||||
}
|
||||
verify(exactly = cases.size) { mockPlayer.setMediaItem(any(), any<Long>()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Direct play includes the opened live stream ID`() =
|
||||
runTest(testDispatcher) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue