@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Column
1010import androidx.compose.foundation.layout.Row
1111import androidx.compose.foundation.layout.fillMaxWidth
1212import androidx.compose.foundation.layout.padding
13+ import androidx.compose.foundation.layout.size
1314import androidx.compose.material.icons.Icons
1415import androidx.compose.material.icons.filled.SkipNext
1516import androidx.compose.material.icons.filled.SkipPrevious
@@ -20,11 +21,11 @@ import androidx.compose.runtime.Composable
2021import androidx.compose.runtime.remember
2122import androidx.compose.ui.Alignment
2223import androidx.compose.ui.Modifier
24+ import androidx.compose.ui.draw.scale
2325import androidx.compose.ui.graphics.Color
2426import androidx.compose.ui.unit.dp
2527import androidx.compose.ui.unit.sp
2628import androidx.media3.common.C
27- import androidx.media3.common.TrackSelectionOverride
2829import androidx.media3.exoplayer.ExoPlayer
2930import com.donut.mixfile.ui.component.common.MixDialogBuilder
3031import com.donut.mixfile.ui.component.common.SingleSelectItemList
@@ -73,12 +74,41 @@ fun BottomControl(
7374 verticalAlignment = Alignment .CenterVertically ,
7475 horizontalArrangement = Arrangement .spacedBy(15 .dp)
7576 ) {
77+ var lastSeek = remember { System .currentTimeMillis() }
7678 if (player.mediaItemCount > 1 ) {
77- IconButton (onClick = { player.seekToPreviousMediaItem() }) {
78- Icon (Icons .Default .SkipPrevious , " Previous" , tint = Color .White )
79+ IconButton (
80+ modifier = Modifier .scale(1f ),
81+ onClick = {
82+ if (System .currentTimeMillis() - lastSeek < 500 ) {
83+ return @IconButton
84+ }
85+ lastSeek = System .currentTimeMillis()
86+ player.seekToPreviousMediaItem()
87+ },
88+ ) {
89+ Icon (
90+ modifier = Modifier .size(100 .dp),
91+ imageVector = Icons .Default .SkipPrevious ,
92+ contentDescription = " Previous" ,
93+ tint = Color .White
94+ )
7995 }
80- IconButton (onClick = { player.seekToNextMediaItem() }) {
81- Icon (Icons .Default .SkipNext , " Next" , tint = Color .White )
96+ IconButton (
97+ modifier = Modifier .scale(1f ),
98+ onClick = {
99+ if (System .currentTimeMillis() - lastSeek < 500 ) {
100+ return @IconButton
101+ }
102+ lastSeek = System .currentTimeMillis()
103+ player.seekToNextMediaItem()
104+ },
105+ ) {
106+ Icon (
107+ modifier = Modifier .size(100 .dp),
108+ imageVector = Icons .Default .SkipNext ,
109+ contentDescription = " Next" ,
110+ tint = Color .White
111+ )
82112 }
83113 }
84114 Text (
@@ -103,71 +133,30 @@ fun BottomControl(
103133 remember(tracks) { tracks.groups.filter { it.type == C .TRACK_TYPE_AUDIO } }
104134 if (audioGroups.size > 1 ) {
105135 PlayerSettingChip (" 音轨" ) {
106- val infos = TrackUtils .getFormattedTracks(audioGroups, " 音轨" )
107- val options = infos.map { it.label }
108- val current =
109- infos.find { it.isSelected }?.label ? : options.firstOrNull() ? : " "
110-
111- MixDialogBuilder (" 选择音轨" , colorScheme = playerColorScheme).apply {
112- setContent {
113- SingleSelectItemList (
114- options,
115- currentOption = current
116- ) { selected ->
117- val target = infos.find { it.label == selected }!!
118- player.trackSelectionParameters =
119- player.trackSelectionParameters
120- .buildUpon()
121- .setOverrideForType(
122- TrackSelectionOverride (
123- target.group,
124- target.index
125- )
126- )
127- .build()
128- closeDialog()
129- }
130- }
131- show()
132- }
136+ showTrackSelector(
137+ title = " 选择音轨" ,
138+ player = player,
139+ trackType = C .TRACK_TYPE_AUDIO ,
140+ colorScheme = playerColorScheme,
141+ hasDisableOption = false
142+ )
133143 }
134144 }
135145
136146 // 字幕选择
137147 val textGroups = remember(tracks) {
138148 tracks.groups.filter { it.type == C .TRACK_TYPE_TEXT }
139149 }
150+
140151 if (textGroups.isNotEmpty()) {
141152 PlayerSettingChip (" 字幕" ) {
142- val infos = TrackUtils .getFormattedTracks(textGroups, " 字幕" )
143- val options = listOf (" 关闭" ) + infos.map { it.label }
144- val current = infos.find { it.isSelected }?.label ? : " 关闭"
145-
146- MixDialogBuilder (" 选择字幕" , colorScheme = playerColorScheme).apply {
147- setContent {
148- SingleSelectItemList (
149- options,
150- currentOption = current
151- ) { selected ->
152- val builder = player.trackSelectionParameters.buildUpon()
153- if (selected == " 关闭" ) {
154- builder.setTrackTypeDisabled(C .TRACK_TYPE_TEXT , true )
155- } else {
156- val target = infos.find { it.label == selected }!!
157- builder.setTrackTypeDisabled(C .TRACK_TYPE_TEXT , false )
158- .setOverrideForType(
159- TrackSelectionOverride (
160- target.group,
161- target.index
162- )
163- )
164- }
165- player.trackSelectionParameters = builder.build()
166- closeDialog()
167- }
168- }
169- show()
170- }
153+ showTrackSelector(
154+ title = " 选择字幕" ,
155+ player = player,
156+ trackType = C .TRACK_TYPE_TEXT ,
157+ colorScheme = playerColorScheme,
158+ hasDisableOption = true
159+ )
171160 }
172161 }
173162
0 commit comments