Aman Sharma
commited on
Commit
·
d0fe640
1
Parent(s):
7448002
Fix : volumeSlider
Browse files
streaming-react-app/src/RoomConfig.tsx
CHANGED
@@ -232,7 +232,7 @@ export default function RoomConfig({
|
|
232 |
disabled={
|
233 |
roomState?.room_id != null ||
|
234 |
joinInProgress ||
|
235 |
-
streamingStatus !== "stopped"
|
236 |
}
|
237 |
onClick={() => onJoinRoom(true)}
|
238 |
>
|
|
|
232 |
disabled={
|
233 |
roomState?.room_id != null ||
|
234 |
joinInProgress ||
|
235 |
+
streamingStatus !== "stopped" || !isValidRoles
|
236 |
}
|
237 |
onClick={() => onJoinRoom(true)}
|
238 |
>
|
streaming-react-app/src/StreamingInterface.tsx
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
-
import {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react';
|
2 |
import Button from '@mui/material/Button';
|
3 |
import Typography from '@mui/material/Typography';
|
4 |
import InputLabel from '@mui/material/InputLabel';
|
5 |
import FormControl from '@mui/material/FormControl';
|
6 |
-
import Select, {SelectChangeEvent} from '@mui/material/Select';
|
7 |
import MenuItem from '@mui/material/MenuItem';
|
8 |
import Stack from '@mui/material/Stack';
|
9 |
import {
|
@@ -30,8 +30,8 @@ import FormControlLabel from '@mui/material/FormControlLabel';
|
|
30 |
import Radio from '@mui/material/Radio';
|
31 |
import './StreamingInterface.css';
|
32 |
import RoomConfig from './RoomConfig';
|
33 |
-
import {useSocket} from './useSocket';
|
34 |
-
import {RoomState} from './types/RoomState';
|
35 |
import useStable from './useStable';
|
36 |
import float32To16BitPCM from './float32To16BitPCM';
|
37 |
import createBufferedSpeechPlayer from './createBufferedSpeechPlayer';
|
@@ -51,13 +51,13 @@ import {
|
|
51 |
getTotalSentencesLength,
|
52 |
} from './sliceTranslationSentencesUtils';
|
53 |
import Blink from './Blink';
|
54 |
-
import {CURSOR_BLINK_INTERVAL_MS} from './cursorBlinkInterval';
|
55 |
-
import {getURLParams} from './URLParams';
|
56 |
import debug from './debug';
|
57 |
import DebugSection from './DebugSection';
|
58 |
import Switch from '@mui/material/Switch';
|
59 |
import Grid from '@mui/material/Grid';
|
60 |
-
import {getLanguageFromThreeLetterCode} from './languageLookup';
|
61 |
import HeadphonesIcon from '@mui/icons-material/Headphones';
|
62 |
|
63 |
const AUDIO_STREAM_DEFAULTS = {
|
@@ -75,7 +75,7 @@ async function requestUserMediaAudioStream(
|
|
75 |
config: BrowserAudioStreamConfig = AUDIO_STREAM_DEFAULTS['userMedia'],
|
76 |
) {
|
77 |
const stream = await navigator.mediaDevices.getUserMedia({
|
78 |
-
audio: {...config, channelCount: 1},
|
79 |
});
|
80 |
console.debug(
|
81 |
'[requestUserMediaAudioStream] stream created with settings:',
|
@@ -88,7 +88,7 @@ async function requestDisplayMediaAudioStream(
|
|
88 |
config: BrowserAudioStreamConfig = AUDIO_STREAM_DEFAULTS['displayMedia'],
|
89 |
) {
|
90 |
const stream = await navigator.mediaDevices.getDisplayMedia({
|
91 |
-
audio: {...config, channelCount: 1},
|
92 |
});
|
93 |
console.debug(
|
94 |
'[requestDisplayMediaAudioStream] stream created with settings:',
|
@@ -97,7 +97,7 @@ async function requestDisplayMediaAudioStream(
|
|
97 |
return stream;
|
98 |
}
|
99 |
|
100 |
-
const buttonLabelMap: {[key in StreamingStatus]: string} = {
|
101 |
stopped: 'Start broadcasting',
|
102 |
running: 'Stop broadcasting',
|
103 |
starting: 'Starting...',
|
@@ -126,7 +126,7 @@ export default function StreamingInterface() {
|
|
126 |
);
|
127 |
|
128 |
const socketObject = useSocket();
|
129 |
-
const {socket, clientID} = socketObject;
|
130 |
|
131 |
const [serverState, setServerState] = useState<ServerState | null>(null);
|
132 |
const [agent, setAgent] = useState<AgentCapabilities | null>(null);
|
@@ -228,9 +228,9 @@ export default function StreamingInterface() {
|
|
228 |
|
229 |
const translationSentences: TranslationSentences = animateTextDisplay
|
230 |
? sliceTranslationSentencesUpToIndex(
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
: translationSentencesBase;
|
235 |
|
236 |
// We want the blinking cursor to show before any text has arrived, so let's add an empty string so that the cursor shows up
|
@@ -281,7 +281,7 @@ export default function StreamingInterface() {
|
|
281 |
[socket],
|
282 |
);
|
283 |
|
284 |
-
const configureStreamAsync = ({sampleRate}: {sampleRate: number}) => {
|
285 |
return new Promise<void>((resolve, reject) => {
|
286 |
if (socket == null) {
|
287 |
reject(new Error('[configureStreamAsync] socket is null '));
|
@@ -672,7 +672,7 @@ export default function StreamingInterface() {
|
|
672 |
<Stack
|
673 |
spacing={2}
|
674 |
direction="row"
|
675 |
-
sx={{mb: 1, width: '100%'}}
|
676 |
alignItems="center">
|
677 |
<VolumeDown color="primary" />
|
678 |
<Slider
|
@@ -683,10 +683,10 @@ export default function StreamingInterface() {
|
|
683 |
max={3}
|
684 |
step={0.1}
|
685 |
marks={[
|
686 |
-
{value: 0, label: '0%'},
|
687 |
-
{value: 1, label: '100%'},
|
688 |
-
{value: 2, label: '400%'},
|
689 |
-
{value: 3, label: '700%'},
|
690 |
]}
|
691 |
valueLabelFormat={(value) => `${(value * 100).toFixed(0)}%`}
|
692 |
valueLabelDisplay="auto"
|
@@ -737,39 +737,45 @@ export default function StreamingInterface() {
|
|
737 |
<div
|
738 |
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
739 |
// @ts-ignore Not sure why it's complaining about complexity here
|
740 |
-
style={{width:"100%"}}
|
741 |
-
|
742 |
<div className="main-container-sra">
|
743 |
<Stack direction={{ xs: 'column', md: 'row' }} spacing={6} className="top-section-sra horizontal-padding-sra">
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
|
|
757 |
</div>
|
758 |
-
|
759 |
-
|
760 |
{/* <Box> */}
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
|
|
771 |
|
772 |
-
|
|
|
|
|
|
|
|
|
|
|
773 |
<Box
|
774 |
sx={{
|
775 |
paddingX: 6,
|
@@ -781,22 +787,19 @@ export default function StreamingInterface() {
|
|
781 |
}}>
|
782 |
{volumeSliderNode}
|
783 |
</Box>
|
784 |
-
|
785 |
-
|
786 |
-
</Stack>
|
787 |
-
|
788 |
-
<Stack spacing="22px" direction="column" sx={{flex:1}}>
|
789 |
{isSpeaker && (
|
790 |
<>
|
791 |
-
|
792 |
<FormLabel id="output-modes-radio-group-label">
|
793 |
Output
|
794 |
</FormLabel>
|
795 |
|
796 |
-
<Box sx={{paddingTop: 2, paddingBottom: 1}}>
|
797 |
-
<FormControl fullWidth sx={{minWidth: '14em'}}>
|
798 |
<InputLabel id="target-selector-input-label">
|
799 |
-
|
800 |
</InputLabel>
|
801 |
<Select
|
802 |
labelId="target-selector-input-label"
|
@@ -812,8 +815,8 @@ export default function StreamingInterface() {
|
|
812 |
<MenuItem value={langCode} key={langCode}>
|
813 |
{getLanguageFromThreeLetterCode(langCode) != null
|
814 |
? `${getLanguageFromThreeLetterCode(
|
815 |
-
|
816 |
-
|
817 |
: langCode}
|
818 |
</MenuItem>
|
819 |
))}
|
@@ -837,7 +840,7 @@ export default function StreamingInterface() {
|
|
837 |
name="output-modes-radio-buttons-group">
|
838 |
{
|
839 |
// TODO: Use supported modalities from agentCapabilities
|
840 |
-
SUPPORTED_OUTPUT_MODES.map(({value, label}) => (
|
841 |
<FormControlLabel
|
842 |
key={value}
|
843 |
value={value}
|
@@ -855,28 +858,28 @@ export default function StreamingInterface() {
|
|
855 |
direction="column"
|
856 |
spacing={1}
|
857 |
alignItems="flex-start"
|
858 |
-
sx={{flexGrow: 1}}>
|
859 |
{currentAgent?.dynamicParams?.includes(
|
860 |
'expressive',
|
861 |
) && (
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
|
881 |
{isListener && (
|
882 |
<Box
|
@@ -904,7 +907,7 @@ export default function StreamingInterface() {
|
|
904 |
agentsCapabilities.length === 0
|
905 |
}
|
906 |
fullWidth
|
907 |
-
sx={{minWidth: '14em'}}>
|
908 |
<InputLabel id="model-selector-input-label">
|
909 |
Model
|
910 |
</InputLabel>
|
@@ -943,7 +946,7 @@ export default function StreamingInterface() {
|
|
943 |
<Box >
|
944 |
<FormControl disabled={streamFixedConfigOptionsDisabled}>
|
945 |
<FormLabel id="input-source-radio-group-label">
|
946 |
-
|
947 |
</FormLabel>
|
948 |
<RadioGroup
|
949 |
aria-labelledby="input-source-radio-group-label"
|
@@ -954,7 +957,7 @@ export default function StreamingInterface() {
|
|
954 |
)
|
955 |
}
|
956 |
name="input-source-radio-buttons-group">
|
957 |
-
{SUPPORTED_INPUT_SOURCES.map(({label, value}) => (
|
958 |
<FormControlLabel
|
959 |
key={value}
|
960 |
value={value}
|
@@ -967,7 +970,7 @@ export default function StreamingInterface() {
|
|
967 |
</Box>
|
968 |
|
969 |
<Box >
|
970 |
-
|
971 |
<FormLabel>Options</FormLabel>
|
972 |
<FormControlLabel
|
973 |
control={
|
@@ -1043,7 +1046,7 @@ export default function StreamingInterface() {
|
|
1043 |
<Stack direction="row" spacing={6} justifyContent="center">
|
1044 |
{streamingStatus === 'stopped' ? (
|
1045 |
<Button
|
1046 |
-
|
1047 |
variant="contained"
|
1048 |
onClick={startStreaming}
|
1049 |
disabled={
|
@@ -1110,7 +1113,7 @@ export default function StreamingInterface() {
|
|
1110 |
)}
|
1111 |
{serverState != null &&
|
1112 |
serverState.totalActiveTranscoders >=
|
1113 |
-
|
1114 |
<div>
|
1115 |
<Alert severity="warning">
|
1116 |
{`The server currently has ${serverState?.totalActiveTranscoders} active streaming sessions. Performance may be degraded.`}
|
|
|
1 |
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
2 |
import Button from '@mui/material/Button';
|
3 |
import Typography from '@mui/material/Typography';
|
4 |
import InputLabel from '@mui/material/InputLabel';
|
5 |
import FormControl from '@mui/material/FormControl';
|
6 |
+
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
7 |
import MenuItem from '@mui/material/MenuItem';
|
8 |
import Stack from '@mui/material/Stack';
|
9 |
import {
|
|
|
30 |
import Radio from '@mui/material/Radio';
|
31 |
import './StreamingInterface.css';
|
32 |
import RoomConfig from './RoomConfig';
|
33 |
+
import { useSocket } from './useSocket';
|
34 |
+
import { RoomState } from './types/RoomState';
|
35 |
import useStable from './useStable';
|
36 |
import float32To16BitPCM from './float32To16BitPCM';
|
37 |
import createBufferedSpeechPlayer from './createBufferedSpeechPlayer';
|
|
|
51 |
getTotalSentencesLength,
|
52 |
} from './sliceTranslationSentencesUtils';
|
53 |
import Blink from './Blink';
|
54 |
+
import { CURSOR_BLINK_INTERVAL_MS } from './cursorBlinkInterval';
|
55 |
+
import { getURLParams } from './URLParams';
|
56 |
import debug from './debug';
|
57 |
import DebugSection from './DebugSection';
|
58 |
import Switch from '@mui/material/Switch';
|
59 |
import Grid from '@mui/material/Grid';
|
60 |
+
import { getLanguageFromThreeLetterCode } from './languageLookup';
|
61 |
import HeadphonesIcon from '@mui/icons-material/Headphones';
|
62 |
|
63 |
const AUDIO_STREAM_DEFAULTS = {
|
|
|
75 |
config: BrowserAudioStreamConfig = AUDIO_STREAM_DEFAULTS['userMedia'],
|
76 |
) {
|
77 |
const stream = await navigator.mediaDevices.getUserMedia({
|
78 |
+
audio: { ...config, channelCount: 1 },
|
79 |
});
|
80 |
console.debug(
|
81 |
'[requestUserMediaAudioStream] stream created with settings:',
|
|
|
88 |
config: BrowserAudioStreamConfig = AUDIO_STREAM_DEFAULTS['displayMedia'],
|
89 |
) {
|
90 |
const stream = await navigator.mediaDevices.getDisplayMedia({
|
91 |
+
audio: { ...config, channelCount: 1 },
|
92 |
});
|
93 |
console.debug(
|
94 |
'[requestDisplayMediaAudioStream] stream created with settings:',
|
|
|
97 |
return stream;
|
98 |
}
|
99 |
|
100 |
+
const buttonLabelMap: { [key in StreamingStatus]: string } = {
|
101 |
stopped: 'Start broadcasting',
|
102 |
running: 'Stop broadcasting',
|
103 |
starting: 'Starting...',
|
|
|
126 |
);
|
127 |
|
128 |
const socketObject = useSocket();
|
129 |
+
const { socket, clientID } = socketObject;
|
130 |
|
131 |
const [serverState, setServerState] = useState<ServerState | null>(null);
|
132 |
const [agent, setAgent] = useState<AgentCapabilities | null>(null);
|
|
|
228 |
|
229 |
const translationSentences: TranslationSentences = animateTextDisplay
|
230 |
? sliceTranslationSentencesUpToIndex(
|
231 |
+
translationSentencesBase,
|
232 |
+
translationSentencesAnimatedIndex,
|
233 |
+
)
|
234 |
: translationSentencesBase;
|
235 |
|
236 |
// We want the blinking cursor to show before any text has arrived, so let's add an empty string so that the cursor shows up
|
|
|
281 |
[socket],
|
282 |
);
|
283 |
|
284 |
+
const configureStreamAsync = ({ sampleRate }: { sampleRate: number }) => {
|
285 |
return new Promise<void>((resolve, reject) => {
|
286 |
if (socket == null) {
|
287 |
reject(new Error('[configureStreamAsync] socket is null '));
|
|
|
672 |
<Stack
|
673 |
spacing={2}
|
674 |
direction="row"
|
675 |
+
sx={{ mb: 1, width: '100%' }}
|
676 |
alignItems="center">
|
677 |
<VolumeDown color="primary" />
|
678 |
<Slider
|
|
|
683 |
max={3}
|
684 |
step={0.1}
|
685 |
marks={[
|
686 |
+
{ value: 0, label: '0%' },
|
687 |
+
{ value: 1, label: '100%' },
|
688 |
+
{ value: 2, label: '400%' },
|
689 |
+
{ value: 3, label: '700%' },
|
690 |
]}
|
691 |
valueLabelFormat={(value) => `${(value * 100).toFixed(0)}%`}
|
692 |
valueLabelDisplay="auto"
|
|
|
737 |
<div
|
738 |
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
739 |
// @ts-ignore Not sure why it's complaining about complexity here
|
740 |
+
style={{ width: "100%" }}
|
741 |
+
>
|
742 |
<div className="main-container-sra">
|
743 |
<Stack direction={{ xs: 'column', md: 'row' }} spacing={6} className="top-section-sra horizontal-padding-sra">
|
744 |
+
<Stack alignItems="center" sx={{ flex: 1, borderRight: { md: 1 } }}>
|
745 |
+
<div className="header-container-sra">
|
746 |
+
<img
|
747 |
+
src={"./logo.png"}
|
748 |
+
className="header-icon-sra"
|
749 |
+
alt="Hotdub Translation Logo"
|
750 |
+
|
751 |
+
/>
|
752 |
|
753 |
+
<div>
|
754 |
+
<Typography variant="h1" fontSize={20} >
|
755 |
+
Hotdub Real Time Translation
|
756 |
+
</Typography>
|
757 |
+
</div>
|
758 |
</div>
|
759 |
+
|
|
|
760 |
{/* <Box> */}
|
761 |
+
<RoomConfig
|
762 |
+
roomState={roomState}
|
763 |
+
serverState={serverState}
|
764 |
+
streamingStatus={streamingStatus}
|
765 |
+
onJoinRoomOrUpdateRoles={() => {
|
766 |
+
// If the user has switched from speaker to listener we need to tell the
|
767 |
+
// player to play eagerly, since currently the listener doesn't have any stop/start controls
|
768 |
+
bufferedSpeechPlayer.start();
|
769 |
+
}}
|
770 |
+
/>
|
771 |
+
</Stack>
|
772 |
|
773 |
+
<Stack spacing="22px" direction="column" sx={{ flex: 1 }}>
|
774 |
+
{isListener && !isSpeaker && (
|
775 |
+
<>
|
776 |
+
<FormLabel id="output-modes-radio-group-label">
|
777 |
+
Volume Level
|
778 |
+
</FormLabel>
|
779 |
<Box
|
780 |
sx={{
|
781 |
paddingX: 6,
|
|
|
787 |
}}>
|
788 |
{volumeSliderNode}
|
789 |
</Box>
|
790 |
+
</>
|
791 |
+
)}
|
|
|
|
|
|
|
792 |
{isSpeaker && (
|
793 |
<>
|
794 |
+
<Stack spacing={0.5}>
|
795 |
<FormLabel id="output-modes-radio-group-label">
|
796 |
Output
|
797 |
</FormLabel>
|
798 |
|
799 |
+
<Box sx={{ paddingTop: 2, paddingBottom: 1 }}>
|
800 |
+
<FormControl fullWidth sx={{ minWidth: '14em' }}>
|
801 |
<InputLabel id="target-selector-input-label">
|
802 |
+
Language
|
803 |
</InputLabel>
|
804 |
<Select
|
805 |
labelId="target-selector-input-label"
|
|
|
815 |
<MenuItem value={langCode} key={langCode}>
|
816 |
{getLanguageFromThreeLetterCode(langCode) != null
|
817 |
? `${getLanguageFromThreeLetterCode(
|
818 |
+
langCode,
|
819 |
+
)} (${langCode})`
|
820 |
: langCode}
|
821 |
</MenuItem>
|
822 |
))}
|
|
|
840 |
name="output-modes-radio-buttons-group">
|
841 |
{
|
842 |
// TODO: Use supported modalities from agentCapabilities
|
843 |
+
SUPPORTED_OUTPUT_MODES.map(({ value, label }) => (
|
844 |
<FormControlLabel
|
845 |
key={value}
|
846 |
value={value}
|
|
|
858 |
direction="column"
|
859 |
spacing={1}
|
860 |
alignItems="flex-start"
|
861 |
+
sx={{ flexGrow: 1 }}>
|
862 |
{currentAgent?.dynamicParams?.includes(
|
863 |
'expressive',
|
864 |
) && (
|
865 |
+
<FormControlLabel
|
866 |
+
control={
|
867 |
+
<Switch
|
868 |
+
checked={enableExpressive ?? false}
|
869 |
+
onChange={(
|
870 |
+
event: React.ChangeEvent<HTMLInputElement>,
|
871 |
+
) => {
|
872 |
+
const newValue = event.target.checked;
|
873 |
+
setEnableExpressive(newValue);
|
874 |
+
onSetDynamicConfig({
|
875 |
+
expressive: newValue,
|
876 |
+
});
|
877 |
+
}}
|
878 |
+
/>
|
879 |
+
}
|
880 |
+
label="Expressive"
|
881 |
+
/>
|
882 |
+
)}
|
883 |
|
884 |
{isListener && (
|
885 |
<Box
|
|
|
907 |
agentsCapabilities.length === 0
|
908 |
}
|
909 |
fullWidth
|
910 |
+
sx={{ minWidth: '14em' }}>
|
911 |
<InputLabel id="model-selector-input-label">
|
912 |
Model
|
913 |
</InputLabel>
|
|
|
946 |
<Box >
|
947 |
<FormControl disabled={streamFixedConfigOptionsDisabled}>
|
948 |
<FormLabel id="input-source-radio-group-label">
|
949 |
+
Audio Input
|
950 |
</FormLabel>
|
951 |
<RadioGroup
|
952 |
aria-labelledby="input-source-radio-group-label"
|
|
|
957 |
)
|
958 |
}
|
959 |
name="input-source-radio-buttons-group">
|
960 |
+
{SUPPORTED_INPUT_SOURCES.map(({ label, value }) => (
|
961 |
<FormControlLabel
|
962 |
key={value}
|
963 |
value={value}
|
|
|
970 |
</Box>
|
971 |
|
972 |
<Box >
|
973 |
+
<FormControl disabled={streamFixedConfigOptionsDisabled}>
|
974 |
<FormLabel>Options</FormLabel>
|
975 |
<FormControlLabel
|
976 |
control={
|
|
|
1046 |
<Stack direction="row" spacing={6} justifyContent="center">
|
1047 |
{streamingStatus === 'stopped' ? (
|
1048 |
<Button
|
1049 |
+
sx={{ borderRadius: "20px" }}
|
1050 |
variant="contained"
|
1051 |
onClick={startStreaming}
|
1052 |
disabled={
|
|
|
1113 |
)}
|
1114 |
{serverState != null &&
|
1115 |
serverState.totalActiveTranscoders >=
|
1116 |
+
TOTAL_ACTIVE_TRANSCODER_WARNING_THRESHOLD && (
|
1117 |
<div>
|
1118 |
<Alert severity="warning">
|
1119 |
{`The server currently has ${serverState?.totalActiveTranscoders} active streaming sessions. Performance may be degraded.`}
|