mirror of
https://github.com/screego/server.git
synced 2025-09-27 04:26:34 +08:00
feat: system/tab audio on supported systems
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
import React, {useCallback} from 'react';
|
||||
import {Badge, IconButton, Paper, Tooltip, Typography} from '@mui/material';
|
||||
import {Badge, Box, IconButton, Paper, Tooltip, Typography, Slider, Stack} from '@mui/material';
|
||||
import CancelPresentationIcon from '@mui/icons-material/CancelPresentation';
|
||||
import PresentToAllIcon from '@mui/icons-material/PresentToAll';
|
||||
import FullScreenIcon from '@mui/icons-material/Fullscreen';
|
||||
import PeopleIcon from '@mui/icons-material/People';
|
||||
import VolumeMuteIcon from '@mui/icons-material/VolumeOff';
|
||||
import VolumeIcon from '@mui/icons-material/VolumeUp';
|
||||
import SettingsIcon from '@mui/icons-material/Settings';
|
||||
import {useHotkeys} from 'react-hotkeys-hook';
|
||||
import {Video} from './Video';
|
||||
@@ -97,7 +99,17 @@ export const Room = ({
|
||||
React.useEffect(() => {
|
||||
if (videoElement && stream) {
|
||||
videoElement.srcObject = stream;
|
||||
videoElement.play().catch((e) => console.log('Could not play main video', e));
|
||||
videoElement.play().catch((err) => {
|
||||
console.log('Could not play main video', err);
|
||||
if (err.name === 'NotAllowedError') {
|
||||
videoElement.muted = true;
|
||||
videoElement
|
||||
.play()
|
||||
.catch((retryErr) =>
|
||||
console.log('Could not play main video with mute', retryErr)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [videoElement, stream]);
|
||||
|
||||
@@ -161,6 +173,15 @@ export const Room = ({
|
||||
},
|
||||
[state.clientStreams, selectedStream]
|
||||
);
|
||||
useHotkeys(
|
||||
'm',
|
||||
() => {
|
||||
if (videoElement) {
|
||||
videoElement.muted = !videoElement.muted;
|
||||
}
|
||||
},
|
||||
[videoElement]
|
||||
);
|
||||
|
||||
const videoClasses = () => {
|
||||
switch (settings.displayMode) {
|
||||
@@ -194,7 +215,6 @@ export const Room = ({
|
||||
|
||||
{stream ? (
|
||||
<video
|
||||
muted
|
||||
ref={setVideoElement}
|
||||
className={videoClasses()}
|
||||
onDoubleClick={handleFullscreen}
|
||||
@@ -217,6 +237,10 @@ export const Room = ({
|
||||
|
||||
{controlVisible && (
|
||||
<Paper className={classes.control} elevation={10} {...setHoverState}>
|
||||
{(stream?.getAudioTracks().length ?? 0) > 0 && videoElement && (
|
||||
<AudioControl video={videoElement} />
|
||||
)}
|
||||
<Box whiteSpace="nowrap">
|
||||
{state.hostStream ? (
|
||||
<Tooltip title="Cancel Presentation" arrow>
|
||||
<IconButton onClick={stopShare} size="large">
|
||||
@@ -264,6 +288,7 @@ export const Room = ({
|
||||
<SettingsIcon fontSize="large" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Paper>
|
||||
)}
|
||||
|
||||
@@ -353,6 +378,40 @@ const useShowOnMouseMovement = (doShow: (s: boolean) => void) => {
|
||||
);
|
||||
};
|
||||
|
||||
const AudioControl = ({video}: {video: FullScreenHTMLVideoElement}) => {
|
||||
// this is used to force a rerender
|
||||
const [, setMuted] = React.useState<boolean>();
|
||||
|
||||
React.useEffect(() => {
|
||||
const handler = () => setMuted(video.muted);
|
||||
video.addEventListener('volumechange', handler);
|
||||
setMuted(video.muted);
|
||||
return () => video.removeEventListener('volumechange', handler);
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack spacing={0.5} pr={2} direction="row" sx={{alignItems: 'center', my: 1, height: 35}}>
|
||||
<IconButton size="large" onClick={() => (video.muted = !video.muted)}>
|
||||
{video.muted ? (
|
||||
<VolumeMuteIcon fontSize="large" />
|
||||
) : (
|
||||
<VolumeIcon fontSize="large" />
|
||||
)}
|
||||
</IconButton>
|
||||
<Slider
|
||||
min={0}
|
||||
max={1}
|
||||
step={0.01}
|
||||
defaultValue={video.volume}
|
||||
onChange={(_, newVolume) => {
|
||||
video.muted = false;
|
||||
video.volume = newVolume;
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
title: {
|
||||
padding: 15,
|
||||
|
@@ -143,10 +143,15 @@ const clientSession = async ({
|
||||
done();
|
||||
}
|
||||
};
|
||||
peer.ontrack = (event) => {
|
||||
|
||||
let notified = false;
|
||||
const stream = new MediaStream();
|
||||
peer.ontrack = (event) => {
|
||||
stream.addTrack(event.track);
|
||||
if (!notified) {
|
||||
notified = true;
|
||||
onTrack(stream);
|
||||
}
|
||||
};
|
||||
|
||||
return peer;
|
||||
@@ -332,6 +337,14 @@ export const useRoom = (config: UIConfig): UseRoom => {
|
||||
try {
|
||||
stream.current = await navigator.mediaDevices.getDisplayMedia({
|
||||
video: {frameRate: loadSettings().framerate},
|
||||
audio: {
|
||||
echoCancellation: false,
|
||||
autoGainControl: false,
|
||||
noiseSuppression: false,
|
||||
// https://medium.com/@trystonperry/why-is-getdisplaymedias-audio-quality-so-bad-b49ba9cfaa83
|
||||
// @ts-expect-error
|
||||
googAutoGainControl: false,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
console.log('Could not getDisplayMedia', e);
|
||||
|
Reference in New Issue
Block a user