We create an input range with a label, where the range is between 0 and 1 with a step of 0 - 1. The input's value should be determined by a ternary statement that checks if the volume is muted and sets it to 0 or to the current volume if not muted.
onVolumeScrubberChange function is also added that sets the volume to the event target value when the input value changes and updates the volume in the state and an audio reference. The
onVolumeChange function does not need to be used and the logic needs to be adjusted to ensure that the volume can be updated and that it mutes when the volume reaches 0.
Think about: Why do we have to add
audioRef.current.volume === 0 in addition to
Instructor: [0:00] The first thing we're going to do is create the volume state. We are going to destructure useState. State will be called volume, the setter will be set volume, and we'll use the useState hook and set the initial volume to one. [0:15] Next, let's go down to our JSX, create an input type range. We want to add an associated label. We'll add an ID and we'll call that ID volume-scrubber. Then we will create a label with an HTML for matching that volume-scrubber ID.
[0:35] We will set the inner text to be volume. Next, we will set the min to be , the max to be 1, and the step to be .1. Next, let's set the value of this input range. It's going to be conditional based off of if it is muted. Let's create a ternary.
[0:51] If it is muted, you want to set it to zero. Otherwise, it will be that volume state. Next, we have to add an onChange to this input range. Let's go up here to our functions. We'll do const onVolumeScrubberChange equals will pass at the event.
[1:10] First, we are going to create a variable called new volume and we're going to set that to event target value. To be safe, we're going to wrap that in a number constructor. Then we'll set the volume state to be the new volume. Then we also have to make sure we're updating the audioRef volume. audioRef.current.volume equals new volume.
[1:34] Next, let's add that to the onChange event on that input range. onChange equals on volume scrubber change. We notice a few things here. One, if I lower the volume on this input range scrubber that we created and I hover over the volume on the audio player, you see it has adjusted.
[1:55] You can also see that when I press the mute button, the volume gets set to zero, and unmute, it gets set back to the state. However, there are a few things missing here.
[2:04] First, when we use the scrubber to go all the way to zero, it doesn't update the mute state. You may also notice that when the volume is zero on the scrubber, the mute button enables. The next thing is when we're changing the volume on the audio element itself, you'll notice that the input range volume scrubber does not change.
[2:24] Let's go back to the onVolumeChange function. When we set is muted to 1, we don't just want to look for if we have the audioRef.current.muted. We also want to check to see if the volume equals zero. When that happens, we can set isMuted to 1. When either of these happen, then we will set isMuted to 1.
[2:46] The other thing we want to do is instead of using the state, I'm going to change this to not audioRef.current.muted. If it's not muted, we're going to set isMuted to . Next, we're going to map that [?] audioRef.volume to the volume state. So set volume audioRef.current.volume.
[3:09] Let's go back to our browser and see how that works. Great. We see that works really well. Now if I use this volume scrubber to go all the way down to the bottom, we get the unmute button. You can also see if I use the audio element to change the volume, it maps to the volume scrubber that we created.
[3:32] To summarize, we created a volume state and set the initial state to 1. Then we created an input type range and we called that volume scrubber and gave it an accessible label called volume, set the min to , the max to 1 and the step to .1. We conditionally set the value depending on if it is muted. If it is muted, we set the value to . Otherwise, we set it to volume.
[4:00] Next, we created an onVolumeScrubberChange. We got the new volume from that input type range value. Then we set the volume state to that new volume and also set the audioRef.current.volume to that new volume. Next, to make sure that things were properly mapping. Next, we updated the onVolumeChange function.
[4:19] We updated the first if statement to be if audioRef.current.muted or audioRef.current.volume equals , then we set the isMuted to 1. Then we changed the else if and we said if not audioRef.current.muted, then we set isMuted to and we update the volume.