From 7db2ca32255d3d8ca1c4ddaaaf002076fc5e2fbd Mon Sep 17 00:00:00 2001 From: 1 <386029724@qq.com> Date: Thu, 14 May 2026 16:59:49 +0800 Subject: [PATCH] fix video player --- app/build.gradle.kts | 4 +- .../activity/video/player/BottomControl.kt | 111 ++++++++---------- .../activity/video/player/PlayerUtils.kt | 16 ++- 3 files changed, 63 insertions(+), 68 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6e484ef..15651b2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,8 +17,8 @@ android { applicationId = "com.donut.mixfile" minSdk = 26 targetSdk = 36 - versionCode = 160 - versionName = "2.0.11.1" + versionCode = 161 + versionName = "2.0.11.2" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/donut/mixfile/activity/video/player/BottomControl.kt b/app/src/main/java/com/donut/mixfile/activity/video/player/BottomControl.kt index 2391d94..7f3cae8 100644 --- a/app/src/main/java/com/donut/mixfile/activity/video/player/BottomControl.kt +++ b/app/src/main/java/com/donut/mixfile/activity/video/player/BottomControl.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.SkipNext import androidx.compose.material.icons.filled.SkipPrevious @@ -20,11 +21,11 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.scale import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.media3.common.C -import androidx.media3.common.TrackSelectionOverride import androidx.media3.exoplayer.ExoPlayer import com.donut.mixfile.ui.component.common.MixDialogBuilder import com.donut.mixfile.ui.component.common.SingleSelectItemList @@ -73,12 +74,41 @@ fun BottomControl( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(15.dp) ) { + var lastSeek = remember { System.currentTimeMillis() } if (player.mediaItemCount > 1) { - IconButton(onClick = { player.seekToPreviousMediaItem() }) { - Icon(Icons.Default.SkipPrevious, "Previous", tint = Color.White) + IconButton( + modifier = Modifier.scale(1f), + onClick = { + if (System.currentTimeMillis() - lastSeek < 500) { + return@IconButton + } + lastSeek = System.currentTimeMillis() + player.seekToPreviousMediaItem() + }, + ) { + Icon( + modifier = Modifier.size(100.dp), + imageVector = Icons.Default.SkipPrevious, + contentDescription = "Previous", + tint = Color.White + ) } - IconButton(onClick = { player.seekToNextMediaItem() }) { - Icon(Icons.Default.SkipNext, "Next", tint = Color.White) + IconButton( + modifier = Modifier.scale(1f), + onClick = { + if (System.currentTimeMillis() - lastSeek < 500) { + return@IconButton + } + lastSeek = System.currentTimeMillis() + player.seekToNextMediaItem() + }, + ) { + Icon( + modifier = Modifier.size(100.dp), + imageVector = Icons.Default.SkipNext, + contentDescription = "Next", + tint = Color.White + ) } } Text( @@ -103,33 +133,13 @@ fun BottomControl( remember(tracks) { tracks.groups.filter { it.type == C.TRACK_TYPE_AUDIO } } if (audioGroups.size > 1) { PlayerSettingChip("音轨") { - val infos = TrackUtils.getFormattedTracks(audioGroups, "音轨") - val options = infos.map { it.label } - val current = - infos.find { it.isSelected }?.label ?: options.firstOrNull() ?: "" - - MixDialogBuilder("选择音轨", colorScheme = playerColorScheme).apply { - setContent { - SingleSelectItemList( - options, - currentOption = current - ) { selected -> - val target = infos.find { it.label == selected }!! - player.trackSelectionParameters = - player.trackSelectionParameters - .buildUpon() - .setOverrideForType( - TrackSelectionOverride( - target.group, - target.index - ) - ) - .build() - closeDialog() - } - } - show() - } + showTrackSelector( + title = "选择音轨", + player = player, + trackType = C.TRACK_TYPE_AUDIO, + colorScheme = playerColorScheme, + hasDisableOption = false + ) } } @@ -137,37 +147,16 @@ fun BottomControl( val textGroups = remember(tracks) { tracks.groups.filter { it.type == C.TRACK_TYPE_TEXT } } + if (textGroups.isNotEmpty()) { PlayerSettingChip("字幕") { - val infos = TrackUtils.getFormattedTracks(textGroups, "字幕") - val options = listOf("关闭") + infos.map { it.label } - val current = infos.find { it.isSelected }?.label ?: "关闭" - - MixDialogBuilder("选择字幕", colorScheme = playerColorScheme).apply { - setContent { - SingleSelectItemList( - options, - currentOption = current - ) { selected -> - val builder = player.trackSelectionParameters.buildUpon() - if (selected == "关闭") { - builder.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, true) - } else { - val target = infos.find { it.label == selected }!! - builder.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, false) - .setOverrideForType( - TrackSelectionOverride( - target.group, - target.index - ) - ) - } - player.trackSelectionParameters = builder.build() - closeDialog() - } - } - show() - } + showTrackSelector( + title = "选择字幕", + player = player, + trackType = C.TRACK_TYPE_TEXT, + colorScheme = playerColorScheme, + hasDisableOption = true + ) } } diff --git a/app/src/main/java/com/donut/mixfile/activity/video/player/PlayerUtils.kt b/app/src/main/java/com/donut/mixfile/activity/video/player/PlayerUtils.kt index f7e2da7..8b58c08 100644 --- a/app/src/main/java/com/donut/mixfile/activity/video/player/PlayerUtils.kt +++ b/app/src/main/java/com/donut/mixfile/activity/video/player/PlayerUtils.kt @@ -77,16 +77,22 @@ fun showTrackSelector( colorScheme: ColorScheme, hasDisableOption: Boolean = false ) { + // 只保留指定类型的 track group val groups = player.currentTracks.groups.filter { it.type == trackType } val trackInfos = TrackUtils.getFormattedTracks( groups, if (trackType == C.TRACK_TYPE_TEXT) "字幕" else "音轨" ) - val options = - if (hasDisableOption) listOf("关闭") + trackInfos.map { it.label } else trackInfos.map { it.label } - val currentLabel = - trackInfos.find { it.isSelected }?.label ?: if (hasDisableOption) "关闭" else "" + // 构建选项列表 + val options = buildList { + if (hasDisableOption) add("关闭") + addAll(trackInfos.map { it.label }) + } + + // 获取当前选中的 label + val currentLabel = trackInfos.firstOrNull { it.isSelected }?.label + ?: if (hasDisableOption) "关闭" else options.firstOrNull().orEmpty() MixDialogBuilder(title, colorScheme = colorScheme).apply { setContent { @@ -95,7 +101,7 @@ fun showTrackSelector( if (selected == "关闭") { builder.setTrackTypeDisabled(trackType, true) } else { - val info = trackInfos.find { it.label == selected }!! + val info = trackInfos.first { it.label == selected } builder.setTrackTypeDisabled(trackType, false) .setOverrideForType(TrackSelectionOverride(info.group, info.index)) }