diff --git a/ui/src/audioplayer/Player.js b/ui/src/audioplayer/Player.js
index b22449832..50a53a2ee 100644
--- a/ui/src/audioplayer/Player.js
+++ b/ui/src/audioplayer/Player.js
@@ -5,7 +5,7 @@ import { useAuthState, useDataProvider, useTranslate } from 'react-admin'
 import ReactJkMusicPlayer from 'react-jinke-music-player'
 import 'react-jinke-music-player/assets/index.css'
 import subsonic from '../subsonic'
-import { scrobble, syncQueue, currentPlaying } from './queue'
+import { scrobble, syncQueue, currentPlaying, setVolume } from './queue'
 import themes from '../themes'
 import { makeStyles } from '@material-ui/core/styles'
 
@@ -93,8 +93,9 @@ const Player = () => {
       ...defaultOptions,
       clearPriorAudioLists: queue.clear,
       audioLists: queue.queue.map((item) => item),
+      defaultVolume: queue.volume,
     }
-  }, [queue.clear, queue.queue, defaultOptions])
+  }, [queue.clear, queue.queue, queue.volume, defaultOptions])
 
   const OnAudioListsChange = useCallback(
     (currentPlayIndex, audioLists) => {
@@ -121,6 +122,11 @@ const Player = () => {
     [dispatch, queue.queue]
   )
 
+  const onAudioVolumeChange = useCallback(
+    (volume) => dispatch(setVolume(volume)),
+    [dispatch]
+  )
+
   const OnAudioPlay = useCallback(
     (info) => {
       dispatch(currentPlaying(info))
@@ -157,6 +163,7 @@ const Player = () => {
         onAudioPlay={OnAudioPlay}
         onAudioPause={onAudioPause}
         onAudioEnded={onAudioEnded}
+        onAudioVolumeChange={onAudioVolumeChange}
       />
     )
   }
diff --git a/ui/src/audioplayer/queue.js b/ui/src/audioplayer/queue.js
index 927bb93ac..f2b7da03a 100644
--- a/ui/src/audioplayer/queue.js
+++ b/ui/src/audioplayer/queue.js
@@ -8,6 +8,7 @@ const PLAYER_CLEAR_QUEUE = 'PLAYER_CLEAR_QUEUE'
 const PLAYER_SCROBBLE = 'PLAYER_SCROBBLE'
 const PLAYER_PLAY_TRACKS = 'PLAYER_PLAY_TRACKS'
 const PLAYER_CURRENT = 'PLAYER_CURRENT'
+const PLAYER_SET_VOLUME = 'PLAYER_SET_VOLUME'
 
 const mapToAudioLists = (item) => {
   // If item comes from a playlist, id is mediaFileId
@@ -99,7 +100,12 @@ const currentPlaying = (audioInfo) => ({
   data: audioInfo,
 })
 
-const initialState = { queue: [], clear: true, current: {} }
+const setVolume = (volume) => ({
+  type: PLAYER_SET_VOLUME,
+  data: { volume },
+})
+
+const initialState = { queue: [], clear: true, current: {}, volume: 1 }
 
 const playQueueReducer = (previousState = initialState, payload) => {
   let queue, current
@@ -107,6 +113,11 @@ const playQueueReducer = (previousState = initialState, payload) => {
   switch (type) {
     case PLAYER_CLEAR_QUEUE:
       return initialState
+    case PLAYER_SET_VOLUME:
+      return {
+        ...previousState,
+        volume: data.volume,
+      }
     case PLAYER_CURRENT:
       queue = previousState.queue
       current = data.ended
@@ -118,6 +129,7 @@ const playQueueReducer = (previousState = initialState, payload) => {
       return {
         ...previousState,
         current,
+        volume: data.volume,
       }
     case PLAYER_ADD_TRACKS:
       queue = previousState.queue
@@ -181,6 +193,7 @@ export {
   clearQueue,
   scrobble,
   currentPlaying,
+  setVolume,
   shuffleTracks,
   playQueueReducer,
 }
diff --git a/ui/src/store/createAdminStore.js b/ui/src/store/createAdminStore.js
index f2a7b2542..de5c145cb 100644
--- a/ui/src/store/createAdminStore.js
+++ b/ui/src/store/createAdminStore.js
@@ -48,7 +48,7 @@ export default ({
       const state = store.getState()
       saveState({
         theme: state.theme,
-        queue: pick(state.queue, ['queue']),
+        queue: pick(state.queue, ['queue', 'volume']),
         albumView: state.albumView,
       })
     }),