mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Better choose audio/subtitles by user preferences
This commit is contained in:
parent
dd08bb3e13
commit
ca7dd3797a
3 changed files with 86 additions and 17 deletions
|
|
@ -12,6 +12,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
|||
import dagger.hilt.components.SingletonComponent
|
||||
import okhttp3.OkHttpClient
|
||||
import org.jellyfin.sdk.Jellyfin
|
||||
import org.jellyfin.sdk.api.client.util.AuthorizationHeaderBuilder
|
||||
import org.jellyfin.sdk.api.okhttp.OkHttpFactory
|
||||
import org.jellyfin.sdk.createJellyfin
|
||||
import org.jellyfin.sdk.model.ClientInfo
|
||||
|
|
@ -30,6 +31,27 @@ annotation class StandardOkHttpClient
|
|||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object AppModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun clientInfo(): ClientInfo =
|
||||
ClientInfo(
|
||||
name = "Dolphin",
|
||||
version = BuildConfig.VERSION_NAME,
|
||||
)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun deviceInfo(
|
||||
@ApplicationContext context: Context,
|
||||
): DeviceInfo =
|
||||
DeviceInfo(
|
||||
id = @SuppressLint("HardwareIds") Settings.Secure.getString(
|
||||
context.contentResolver,
|
||||
Settings.Secure.ANDROID_ID,
|
||||
),
|
||||
name = Settings.Global.getString(context.contentResolver, Settings.Global.DEVICE_NAME),
|
||||
)
|
||||
|
||||
@StandardOkHttpClient
|
||||
@Provides
|
||||
@Singleton
|
||||
|
|
@ -46,6 +68,8 @@ object AppModule {
|
|||
fun authOkHttpClient(
|
||||
serverRepository: ServerRepository,
|
||||
@StandardOkHttpClient okHttpClient: OkHttpClient,
|
||||
clientInfo: ClientInfo,
|
||||
deviceInfo: DeviceInfo,
|
||||
) = okHttpClient
|
||||
.newBuilder()
|
||||
.addInterceptor {
|
||||
|
|
@ -56,7 +80,13 @@ object AppModule {
|
|||
.newBuilder()
|
||||
.addHeader(
|
||||
"Authorization",
|
||||
"MediaBrowser Token=\"$token\"",
|
||||
AuthorizationHeaderBuilder.buildHeader(
|
||||
clientName = clientInfo.name,
|
||||
clientVersion = clientInfo.version,
|
||||
deviceId = deviceInfo.id,
|
||||
deviceName = deviceInfo.name,
|
||||
accessToken = serverRepository.currentUser?.accessToken,
|
||||
),
|
||||
).build()
|
||||
}
|
||||
it.proceed(newRequest ?: request)
|
||||
|
|
@ -73,19 +103,13 @@ object AppModule {
|
|||
fun jellyfin(
|
||||
okHttpFactory: OkHttpFactory,
|
||||
@ApplicationContext context: Context,
|
||||
clientInfo: ClientInfo,
|
||||
deviceInfo: DeviceInfo,
|
||||
): Jellyfin =
|
||||
createJellyfin {
|
||||
this.context = context
|
||||
clientInfo =
|
||||
ClientInfo(
|
||||
name = "Dolphin",
|
||||
version = BuildConfig.VERSION_NAME,
|
||||
)
|
||||
deviceInfo =
|
||||
DeviceInfo(
|
||||
id = @SuppressLint("HardwareIds") Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID),
|
||||
name = Settings.Global.getString(context.contentResolver, Settings.Global.DEVICE_NAME),
|
||||
)
|
||||
this.clientInfo = clientInfo
|
||||
this.deviceInfo = deviceInfo
|
||||
apiClientFactory = okHttpFactory
|
||||
socketConnectionFactory = okHttpFactory
|
||||
minimumServerVersion = Jellyfin.minimumVersion
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ data class SubtitleStream(
|
|||
val codec: String?,
|
||||
val codecTag: String?,
|
||||
val external: Boolean,
|
||||
val forced: Boolean,
|
||||
val default: Boolean,
|
||||
) {
|
||||
val displayName: String
|
||||
get() =
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import org.jellyfin.sdk.model.api.DeviceProfile
|
|||
import org.jellyfin.sdk.model.api.MediaSourceInfo
|
||||
import org.jellyfin.sdk.model.api.MediaStreamType
|
||||
import org.jellyfin.sdk.model.api.PlaybackInfoDto
|
||||
import org.jellyfin.sdk.model.api.SubtitlePlaybackMode
|
||||
import org.jellyfin.sdk.model.api.TrickplayInfo
|
||||
import org.jellyfin.sdk.model.extensions.ticks
|
||||
import org.jellyfin.sdk.model.serializer.toUUIDOrNull
|
||||
|
|
@ -103,7 +104,6 @@ class PlaybackViewModel
|
|||
viewModelScope.launch(ExceptionHandler() + Dispatchers.IO) {
|
||||
val base = item?.data ?: api.userLibraryApi.getItem(itemId).content
|
||||
dto = base
|
||||
|
||||
val title =
|
||||
if (base.type == BaseItemKind.EPISODE) {
|
||||
base.seriesName
|
||||
|
|
@ -143,6 +143,8 @@ class PlaybackViewModel
|
|||
it.codec,
|
||||
it.codecTag,
|
||||
it.isExternal,
|
||||
it.isForced,
|
||||
it.isDefault,
|
||||
)
|
||||
}.orEmpty()
|
||||
val audioStreams =
|
||||
|
|
@ -160,12 +162,54 @@ class PlaybackViewModel
|
|||
)
|
||||
}?.sortedWith(compareBy<AudioStream> { it.language }.thenByDescending { it.channels })
|
||||
.orEmpty()
|
||||
// TODO use preferences to select audio/subtitle
|
||||
|
||||
// TODO audio selection based on channel layout, etc
|
||||
val subtitleIndex = subtitleStreams.firstOrNull { it.language == "eng" }?.index
|
||||
val audioLanguage = preferences.userConfig.audioLanguagePreference
|
||||
val audioIndex =
|
||||
audioStreams.firstOrNull { it.language == "eng" }?.index
|
||||
?: audioStreams.firstOrNull()?.index
|
||||
if (audioLanguage != null) {
|
||||
audioStreams.firstOrNull { it.language == audioLanguage }?.index
|
||||
?: audioStreams.firstOrNull()?.index
|
||||
} else {
|
||||
audioStreams.firstOrNull()?.index
|
||||
}
|
||||
val subtitleMode = preferences.userConfig.subtitleMode
|
||||
val subtitleLanguage = preferences.userConfig.subtitleLanguagePreference
|
||||
val subtitleIndex =
|
||||
when (subtitleMode) {
|
||||
SubtitlePlaybackMode.ALWAYS -> {
|
||||
if (subtitleLanguage != null) {
|
||||
subtitleStreams.firstOrNull { it.language == subtitleLanguage }?.index
|
||||
} else {
|
||||
subtitleStreams.firstOrNull()?.index
|
||||
}
|
||||
}
|
||||
|
||||
SubtitlePlaybackMode.ONLY_FORCED ->
|
||||
if (subtitleLanguage != null) {
|
||||
subtitleStreams.firstOrNull { it.language == subtitleLanguage && it.forced }?.index
|
||||
} else {
|
||||
subtitleStreams.firstOrNull { it.forced }?.index
|
||||
}
|
||||
|
||||
SubtitlePlaybackMode.SMART -> {
|
||||
if (audioLanguage != null && subtitleLanguage != null && audioLanguage != subtitleLanguage) {
|
||||
subtitleStreams.firstOrNull { it.language == subtitleLanguage }?.index
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
SubtitlePlaybackMode.DEFAULT -> {
|
||||
// TODO check for language?
|
||||
(
|
||||
subtitleStreams.firstOrNull { it.default && it.forced }
|
||||
?: subtitleStreams.firstOrNull { it.default }
|
||||
?: subtitleStreams.firstOrNull { it.forced }
|
||||
)?.index
|
||||
}
|
||||
|
||||
SubtitlePlaybackMode.NONE -> null
|
||||
}
|
||||
|
||||
Timber.v("base.mediaStreams=${base.mediaStreams}")
|
||||
Timber.v("subtitleTracks=$subtitleStreams")
|
||||
|
|
@ -213,7 +257,6 @@ class PlaybackViewModel
|
|||
api.mediaInfoApi
|
||||
.getPostedPlaybackInfo(
|
||||
itemId,
|
||||
// TODO device profile, etc
|
||||
PlaybackInfoDto(
|
||||
startTimeTicks = null,
|
||||
deviceProfile = deviceProfile,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue