diff --git a/src/components/mindset/components/MediaPlayer/index.tsx b/src/components/mindset/components/MediaPlayer/index.tsx
index 5e203d19e..e9c694746 100644
--- a/src/components/mindset/components/MediaPlayer/index.tsx
+++ b/src/components/mindset/components/MediaPlayer/index.tsx
@@ -66,6 +66,7 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => {
setIsSeeking,
setPlayerRef,
playerRef,
+ playbackSpeed,
} = usePlayerStore((s) => s)
useEffect(() => () => resetPlayer(), [resetPlayer])
@@ -184,6 +185,7 @@ const MediaPlayerComponent = ({ mediaUrl }: Props) => {
onPlay={handlePlay}
onProgress={handleProgress}
onReady={handleReady}
+ playbackRate={playbackSpeed}
playing={isPlaying}
url={mediaUrl || ''}
volume={volume}
diff --git a/src/components/mindset/components/PlayerContols/Controls/index.tsx b/src/components/mindset/components/PlayerContols/Controls/index.tsx
index 2f454bc85..13911c345 100644
--- a/src/components/mindset/components/PlayerContols/Controls/index.tsx
+++ b/src/components/mindset/components/PlayerContols/Controls/index.tsx
@@ -1,16 +1,23 @@
import { IconButton } from '@mui/material'
-import { memo } from 'react'
+import { memo, useState } from 'react'
import styled from 'styled-components'
import PauseIcon from '~/components/Icons/PauseIcon'
import PlayIcon from '~/components/Icons/PlayIcon'
import { Flex } from '~/components/common/Flex'
import { usePlayerStore } from '~/stores/usePlayerStore'
import { colors } from '~/utils/colors'
+import VolumeIcon from '~/components/Icons/VolumeIcon'
+import MuteVolumeIcon from '~/components/Icons/MuteVolumeIcon'
export const Controls = memo(() => {
const isPlaying = usePlayerStore((s) => s.isPlaying)
const setIsPlaying = usePlayerStore((s) => s.setIsPlaying)
+ const setVolume = usePlayerStore((s) => s.setVolume)
+ const setPlaybackSpeed = usePlayerStore((s) => s.setPlaybackSpeed)
+ const playbackSpeed = usePlayerStore((s) => s.playbackSpeed)
const playerRef = usePlayerStore((s) => s.playerRef)
+ const [isMuted, setIsMuted] = useState(false)
+ const speedOptions = [0.5, 1, 1.5, 2]
const handleRewind = () => {
if (playerRef) {
@@ -32,8 +39,30 @@ export const Controls = memo(() => {
setIsPlaying(!isPlaying)
}
+ const toggleMute = () => {
+ setIsMuted(!isMuted)
+ setVolume(isMuted ? 1 : 0)
+ }
+
+ const cycleSpeed = () => {
+ const currentIndex = speedOptions.indexOf(playbackSpeed)
+ const nextIndex = (currentIndex + 1) % speedOptions.length
+ const newSpeed = speedOptions[nextIndex]
+
+ setPlaybackSpeed(newSpeed)
+
+ if (playerRef) {
+ const internalPlayer = playerRef.getInternalPlayer() as HTMLMediaElement
+
+ if (internalPlayer && typeof internalPlayer.playbackRate !== 'undefined') {
+ internalPlayer.playbackRate = newSpeed
+ }
+ }
+ }
+
return (
+ {isMuted ? : }
@@ -43,6 +72,7 @@ export const Controls = memo(() => {
+ {playbackSpeed}x
)
})
@@ -54,7 +84,7 @@ const Wrapper = styled(Flex).attrs({
align: 'center',
justify: 'flex-start',
})`
- width: 142px;
+ width: 200px;
height: 54px;
background: ${colors.BG1};
border-radius: 40px;
@@ -96,3 +126,38 @@ const ForwardIconWrapper = styled.div`
height: auto;
}
`
+
+const MuteWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ cursor: pointer;
+ border-radius: 50%;
+ transition: background-color 0.3s ease;
+ color: ${colors.GRAY6};
+
+ svg {
+ margin-top: 3px;
+ width: 24px;
+ height: 24px;
+ }
+
+ &:hover {
+ background-color: ${colors.DROPDOWN_BG};
+ }
+`
+
+const SpeedButton = styled.button`
+ margin-top: 4px;
+ background: ${colors.BG1};
+ color: ${colors.GRAY6};
+ border: none;
+ width: 8px;
+ border-radius: 20px;
+ padding: 8px 20px 8px 8px;
+ font-size: 14px;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+`
diff --git a/src/stores/usePlayerStore/index.ts b/src/stores/usePlayerStore/index.ts
index aced28cba..f73f943fd 100644
--- a/src/stores/usePlayerStore/index.ts
+++ b/src/stores/usePlayerStore/index.ts
@@ -11,6 +11,7 @@ type PlayerStore = {
playingTime: number
duration: number
volume: number
+ playbackSpeed: number
playingNode: NodeExtended | null
playerRef: ReactPlayer | null
setPlayingTime: (time: number) => void
@@ -24,6 +25,7 @@ type PlayerStore = {
setPlayingNodeLink: (link: string) => void
setIsSeeking: (isSeeking: boolean) => void
setPlayerRef: (playerRef: ReactPlayer) => void
+ setPlaybackSpeed: (speed: number) => void
}
const defaultData: Omit<
@@ -39,6 +41,7 @@ const defaultData: Omit<
| 'setPlayingNodeLink'
| 'setIsSeeking'
| 'setPlayerRef'
+ | 'setPlaybackSpeed'
> = {
isPlaying: false,
miniPlayerIsVisible: false,
@@ -48,6 +51,7 @@ const defaultData: Omit<
playingNode: null,
duration: 0,
volume: 0.5,
+ playbackSpeed: 1,
playerRef: null,
}
@@ -95,5 +99,6 @@ export const usePlayerStore = create()(
}
},
resetPlayer: () => set({ duration: defaultData.duration, hasError: defaultData.hasError }),
+ setPlaybackSpeed: (speed) => set({ playbackSpeed: speed }),
})),
)