@@ -19,6 +19,7 @@ import androidx.compose.runtime.Composable
1919import androidx.compose.runtime.LaunchedEffect
2020import androidx.compose.runtime.collectAsState
2121import androidx.compose.runtime.getValue
22+ import androidx.compose.runtime.mutableFloatStateOf
2223import androidx.compose.runtime.mutableStateOf
2324import androidx.compose.runtime.remember
2425import androidx.compose.runtime.setValue
@@ -38,12 +39,12 @@ import androidx.compose.ui.unit.dp
3839import androidx.compose.ui.window.Window
3940import androidx.compose.ui.window.WindowPosition
4041import androidx.compose.ui.window.rememberWindowState
41- import com.jankinwu.fntv.client.data.model.SubtitleSettings
4242import com.jankinwu.fntv.client.data.network.fnOfficialClient
4343import com.jankinwu.fntv.client.data.store.PlayingSettingsStore
4444import com.jankinwu.fntv.client.icons.PlayCircle
4545import com.jankinwu.fntv.client.manager.PlayerResourceManager
4646import com.jankinwu.fntv.client.ui.component.player.SubtitleOverlay
47+ import com.jankinwu.fntv.client.ui.component.player.VolumeControl
4748import com.jankinwu.fntv.client.ui.providable.LocalMediaPlayer
4849import com.jankinwu.fntv.client.utils.ExternalSubtitleUtil
4950import com.jankinwu.fntv.client.utils.HlsSubtitleUtil
@@ -64,6 +65,7 @@ import org.jetbrains.compose.resources.painterResource
6465import org.koin.compose.viewmodel.koinViewModel
6566import org.openani.mediamp.PlaybackState
6667import org.openani.mediamp.compose.MediampPlayerSurface
68+ import org.openani.mediamp.features.AudioLevelController
6769import java.awt.MouseInfo
6870import java.awt.Point
6971
@@ -80,6 +82,10 @@ fun PipPlayerWindow(
8082 val subtitleSettings by playerViewModel.subtitleSettings.collectAsState()
8183 val savedData = remember { PlayingSettingsStore .getPipWindowData() }
8284
85+ val audioLevelController = remember(mediaPlayer) { mediaPlayer.features[AudioLevelController ] }
86+ val volume by audioLevelController?.volume?.collectAsState() ? : remember { mutableFloatStateOf(1f ) }
87+ var isVolumeControlHovered by remember { mutableStateOf(false ) }
88+
8389 val hlsSubtitleUtil = remember(playingInfoCache) {
8490 val playLink = playingInfoCache?.playLink
8591 val subtitle = playingInfoCache?.currentSubtitleStream
@@ -339,6 +345,26 @@ fun PipPlayerWindow(
339345 }
340346 }
341347
348+ // Bottom Left: Volume Control
349+ if (isHovered || isVolumeControlHovered) {
350+ Box (
351+ modifier = Modifier
352+ .align(Alignment .BottomStart )
353+ .offset(y = 5 .dp, x = (- 5 ).dp)
354+ // .padding(8.dp)
355+ ) {
356+ VolumeControl (
357+ volume = volume,
358+ onVolumeChange = {
359+ audioLevelController?.setVolume(it)
360+ PlayingSettingsStore .saveVolume(it)
361+ },
362+ onHoverStateChanged = { isVolumeControlHovered = it },
363+ modifier = Modifier .size(50 .dp)
364+ )
365+ }
366+ }
367+
342368 // Bottom Right: Exit PiP Button
343369 val pipSpec = PlayerResourceManager .quitPipSpec
344370 if (pipSpec != null ) {
0 commit comments