Actually fix audio sharing volume control
This commit is contained in:
parent
e6d2fb5640
commit
1e11870171
@ -6,12 +6,12 @@ import StreamMuteIcon from "../../icons/StreamMuteIcon";
|
|||||||
import Banner from "../Banner";
|
import Banner from "../Banner";
|
||||||
|
|
||||||
function Stream({ stream, nickname }) {
|
function Stream({ stream, nickname }) {
|
||||||
const [streamVolume, setStreamVolume] = useState(0);
|
const [streamVolume, setStreamVolume] = useState(1);
|
||||||
const [showStreamInteractBanner, setShowStreamInteractBanner] = useState(
|
const [showStreamInteractBanner, setShowStreamInteractBanner] = useState(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
const [streamMuted, setStreamMuted] = useState(false);
|
||||||
const audioRef = useRef();
|
const audioRef = useRef();
|
||||||
const streamMuted = streamVolume === 0;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (audioRef.current) {
|
if (audioRef.current) {
|
||||||
@ -21,11 +21,10 @@ function Stream({ stream, nickname }) {
|
|||||||
.play()
|
.play()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Played fine
|
// Played fine
|
||||||
setStreamVolume(1);
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// Unable to autoplay
|
// Unable to autoplay
|
||||||
setStreamVolume(0);
|
setStreamMuted(true);
|
||||||
setShowStreamInteractBanner(true);
|
setShowStreamInteractBanner(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -35,11 +34,11 @@ function Stream({ stream, nickname }) {
|
|||||||
if (audioRef.current) {
|
if (audioRef.current) {
|
||||||
if (streamMuted) {
|
if (streamMuted) {
|
||||||
audioRef.current.play().then(() => {
|
audioRef.current.play().then(() => {
|
||||||
setStreamVolume(1);
|
setStreamMuted(false);
|
||||||
setShowStreamInteractBanner(false);
|
setShowStreamInteractBanner(false);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setStreamVolume(0);
|
setStreamMuted(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,40 +46,50 @@ function Stream({ stream, nickname }) {
|
|||||||
function handleVolumeChange(event) {
|
function handleVolumeChange(event) {
|
||||||
const volume = parseFloat(event.target.value);
|
const volume = parseFloat(event.target.value);
|
||||||
setStreamVolume(volume);
|
setStreamVolume(volume);
|
||||||
if (showStreamInteractBanner) {
|
|
||||||
audioRef.current.play().then(() => {
|
|
||||||
setShowStreamInteractBanner(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use an audio context gain node to control volume to go past 100%
|
|
||||||
const audioGainRef = useRef();
|
|
||||||
useEffect(() => {
|
|
||||||
if (stream && !streamMuted) {
|
|
||||||
let audioContext = new AudioContext();
|
|
||||||
let source = audioContext.createMediaStreamSource(stream);
|
|
||||||
let gainNode = audioContext.createGain();
|
|
||||||
gainNode.gain.value = 0;
|
|
||||||
source.connect(gainNode);
|
|
||||||
gainNode.connect(audioContext.destination);
|
|
||||||
audioGainRef.current = gainNode;
|
|
||||||
}
|
|
||||||
}, [stream, streamMuted]);
|
|
||||||
|
|
||||||
// Platforms like iOS don't allow you to control audio volume
|
// Platforms like iOS don't allow you to control audio volume
|
||||||
// Detect this by trying to change the audio volume
|
// Detect this by trying to change the audio volume
|
||||||
const [isVolumeControlAvailable, setIsVolumeControlAvailable] = useState(
|
const [isVolumeControlAvailable, setIsVolumeControlAvailable] = useState(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (audioRef.current) {
|
let audio = audioRef.current;
|
||||||
const prevVolume = audioRef.current.volume;
|
function checkVolumeControlAvailable() {
|
||||||
audioRef.current.volume = 0.5;
|
const prevVolume = audio.volume;
|
||||||
setIsVolumeControlAvailable(audioRef.current.volume === 0.5);
|
// Set volume to 0.5, then check if the value actually stuck 100ms later
|
||||||
audioRef.current.volume = prevVolume;
|
audio.volume = 0.5;
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsVolumeControlAvailable(audio.volume === 0.5);
|
||||||
|
audio.volume = prevVolume;
|
||||||
|
}, [100]);
|
||||||
}
|
}
|
||||||
}, [stream]);
|
|
||||||
|
audio.addEventListener("playing", checkVolumeControlAvailable);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
audio.removeEventListener("playing", checkVolumeControlAvailable);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Use an audio context gain node to control volume to go past 100%
|
||||||
|
const audioGainRef = useRef();
|
||||||
|
useEffect(() => {
|
||||||
|
let audioContext;
|
||||||
|
if (stream && !streamMuted && isVolumeControlAvailable) {
|
||||||
|
audioContext = new AudioContext();
|
||||||
|
let source = audioContext.createMediaStreamSource(stream);
|
||||||
|
let gainNode = audioContext.createGain();
|
||||||
|
gainNode.gain.value = 0;
|
||||||
|
source.connect(gainNode);
|
||||||
|
gainNode.connect(audioContext.destination);
|
||||||
|
audioGainRef.current = gainNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
audioContext && audioContext.close();
|
||||||
|
};
|
||||||
|
}, [stream, streamMuted, isVolumeControlAvailable]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (audioGainRef.current && audioRef.current) {
|
if (audioGainRef.current && audioRef.current) {
|
||||||
@ -109,12 +118,12 @@ function Stream({ stream, nickname }) {
|
|||||||
<StreamMuteIcon muted={streamMuted} />
|
<StreamMuteIcon muted={streamMuted} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Slider
|
<Slider
|
||||||
value={streamVolume}
|
value={streamMuted ? 0 : streamVolume}
|
||||||
min={0}
|
min={0}
|
||||||
max={2}
|
max={2}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
onChange={handleVolumeChange}
|
onChange={handleVolumeChange}
|
||||||
disabled={!isVolumeControlAvailable}
|
disabled={!isVolumeControlAvailable || streamMuted}
|
||||||
/>
|
/>
|
||||||
{stream && <audio ref={audioRef} playsInline muted={streamMuted} />}
|
{stream && <audio ref={audioRef} playsInline muted={streamMuted} />}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user